Add mods: technic, moreores, paintings, Nyancat (Pbj_pup). Small fix: sandwiches
This commit is contained in:
parent
15e8e696a2
commit
fb09deddc1
1404 changed files with 156555 additions and 211 deletions
21
mods/technic_plus_beta/technic/machines/HV/battery_box.lua
Normal file
21
mods/technic_plus_beta/technic/machines/HV/battery_box.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- HV battery box
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_battery_box0',
|
||||
recipe = {
|
||||
{'technic:mv_battery_box0', 'technic:mv_battery_box0', 'technic:mv_battery_box0'},
|
||||
{'technic:mv_battery_box0', 'technic:hv_transformer', 'technic:mv_battery_box0'},
|
||||
{'', 'technic:hv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_battery_box("technic:hv_battery_box", {
|
||||
tier = "HV",
|
||||
max_charge = 1000000,
|
||||
charge_rate = 100000,
|
||||
discharge_rate = 400000,
|
||||
charge_step = 10000,
|
||||
discharge_step = 40000,
|
||||
upgrade = 1,
|
||||
tube = 1,
|
||||
})
|
54
mods/technic_plus_beta/technic/machines/HV/cables.lua
Normal file
54
mods/technic_plus_beta/technic/machines/HV/cables.lua
Normal file
|
@ -0,0 +1,54 @@
|
|||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_cable 3',
|
||||
recipe = {
|
||||
{'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting'},
|
||||
{'technic:mv_cable', 'technic:mv_cable', 'technic:mv_cable'},
|
||||
{'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting', 'homedecor:plastic_sheeting'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:hv_cable_plate_1 5",
|
||||
recipe = {
|
||||
{"" , "" , "technic:hv_cable"},
|
||||
{"technic:hv_cable", "technic:hv_cable", "technic:hv_cable"},
|
||||
{"" , "" , "technic:hv_cable"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:hv_cable",
|
||||
recipe = {{"technic:hv_cable_plate_1"}}
|
||||
})
|
||||
|
||||
-- Register cables
|
||||
|
||||
technic.register_cable("technic:hv_cable", {
|
||||
tier = "HV",
|
||||
size = 3/16,
|
||||
description = S("@1 Cable", S("HV"))
|
||||
})
|
||||
technic.register_cable_plate("technic:hv_cable_plate", {
|
||||
tier = "HV",
|
||||
size = 3/16,
|
||||
description = S("@1 Cable Plate", S("HV")),
|
||||
tiles = {"technic_hv_cable.png"},
|
||||
})
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
technic.register_cable("technic:hv_digi_cable", {
|
||||
tier = "HV",
|
||||
size = 3/16,
|
||||
description = S("@1 Digiline Cable", S("HV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } }
|
||||
})
|
||||
technic.register_cable_plate("technic:hv_digi_cable_plate", {
|
||||
tier = "HV",
|
||||
size = 3/16,
|
||||
description = S("@1 Digiline Cable Plate", S("HV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } },
|
||||
tiles = {"technic_hv_digi_cable.png"}
|
||||
})
|
||||
end
|
21
mods/technic_plus_beta/technic/machines/HV/compressor.lua
Normal file
21
mods/technic_plus_beta/technic/machines/HV/compressor.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- HV compressor
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_compressor',
|
||||
recipe = {
|
||||
{'technic:carbon_plate', 'technic:mv_compressor', 'technic:composite_plate'},
|
||||
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:hv_compressor", {
|
||||
typename = "compressing",
|
||||
description = S("@1 Compressor", S("HV")),
|
||||
tier = "HV",
|
||||
demand = {1500, 1000, 750},
|
||||
speed = 5,
|
||||
upgrade = 1,
|
||||
tube = 1
|
||||
})
|
|
@ -0,0 +1,26 @@
|
|||
-- MV Electric Furnace
|
||||
-- This is a faster version of the stone furnace which runs on EUs
|
||||
-- In addition to this it can be upgraded with microcontrollers and batteries
|
||||
-- This new version uses the batteries to lower the power consumption of the machine
|
||||
-- Also in addition this furnace can be attached to the pipe system from the pipeworks mod.
|
||||
local S = technic.getter
|
||||
|
||||
-- FIXME: kpoppel I'd like to introduce an induction heating element here also
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_electric_furnace',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_electric_furnace', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:hv_electric_furnace", {
|
||||
typename = "cooking",
|
||||
description = S("@1 Furnace", S("HV")),
|
||||
tier="HV",
|
||||
upgrade=1,
|
||||
tube=1,
|
||||
demand={4000, 2500, 1500},
|
||||
speed=12
|
||||
})
|
400
mods/technic_plus_beta/technic/machines/HV/forcefield.lua
Normal file
400
mods/technic_plus_beta/technic/machines/HV/forcefield.lua
Normal file
|
@ -0,0 +1,400 @@
|
|||
--- Forcefield generator.
|
||||
-- @author ShadowNinja
|
||||
--
|
||||
-- Forcefields are powerful barriers but they consume huge amounts of power.
|
||||
-- The forcefield Generator is an HV machine.
|
||||
|
||||
-- How expensive is the generator?
|
||||
-- Leaves room for upgrades lowering the power drain?
|
||||
local digilines_path = minetest.get_modpath("digilines")
|
||||
|
||||
local forcefield_power_drain = 10
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:forcefield_emitter_off",
|
||||
recipe = {
|
||||
{mat.mese, "basic_materials:motor", mat.mese },
|
||||
{"technic:deployer_off", "technic:machine_casing", "technic:deployer_off"},
|
||||
{mat.mese, "technic:hv_cable", mat.mese },
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
local replaceable_cids = {}
|
||||
|
||||
minetest.after(0, function()
|
||||
for name, ndef in pairs(minetest.registered_nodes) do
|
||||
if ndef.buildable_to == true and name ~= "ignore" then
|
||||
replaceable_cids[minetest.get_content_id(name)] = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Idea: Let forcefields have different colors by upgrade slot.
|
||||
-- Idea: Let forcefields add up by detecting if one hits another.
|
||||
-- ___ __
|
||||
-- / \/ \
|
||||
-- | |
|
||||
-- \___/\___/
|
||||
|
||||
local function update_forcefield(pos, meta, active)
|
||||
|
||||
if active then
|
||||
-- rate limit by chance
|
||||
if math.floor(math.random()*4) ~= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local shape = meta:get_int("shape")
|
||||
local range = meta:get_int("range")
|
||||
local vm = VoxelManip()
|
||||
local MinEdge, MaxEdge = vm:read_from_map(vector.subtract(pos, range),
|
||||
vector.add(pos, range))
|
||||
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
|
||||
local data = vm:get_data()
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_field = minetest.get_content_id("technic:forcefield")
|
||||
|
||||
for z = -range, range do
|
||||
for y = -range, range do
|
||||
local vi = area:index(pos.x + (-range), pos.y + y, pos.z + z)
|
||||
for x = -range, range do
|
||||
local relevant
|
||||
if shape == 0 then
|
||||
local squared = x * x + y * y + z * z
|
||||
relevant =
|
||||
squared <= range * range + range and
|
||||
squared >= (range - 1) * (range - 1) + (range - 1)
|
||||
else
|
||||
relevant =
|
||||
x == -range or x == range or
|
||||
y == -range or y == range or
|
||||
z == -range or z == range
|
||||
end
|
||||
if relevant then
|
||||
local cid = data[vi]
|
||||
if active and replaceable_cids[cid] then
|
||||
data[vi] = c_field
|
||||
elseif not active and cid == c_field then
|
||||
data[vi] = c_air
|
||||
end
|
||||
end
|
||||
vi = vi + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vm:set_data(data)
|
||||
vm:update_liquids()
|
||||
vm:write_to_map()
|
||||
end
|
||||
|
||||
local function set_forcefield_formspec(meta)
|
||||
local formspec
|
||||
if digilines_path then
|
||||
formspec = "size[5,3.25]"..
|
||||
"field[0.3,3;5,1;channel;"..S("Digiline Channel")..";${channel}]"
|
||||
else
|
||||
formspec = "size[5,2.25]"
|
||||
end
|
||||
formspec = formspec..
|
||||
"field[0.3,0.5;2,1;range;"..S("Range")..";${range}]"
|
||||
-- The names for these toggle buttons are explicit about which
|
||||
-- state they'll switch to, so that multiple presses (arising
|
||||
-- from the ambiguity between lag and a missed press) only make
|
||||
-- the single change that the user expects.
|
||||
if meta:get_int("shape") == 0 then
|
||||
formspec = formspec.."button[3,0.2;2,1;shape1;"..S("Sphere").."]"
|
||||
else
|
||||
formspec = formspec.."button[3,0.2;2,1;shape0;"..S("Cube").."]"
|
||||
end
|
||||
if meta:get_int("mesecon_mode") == 0 then
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
|
||||
end
|
||||
if meta:get_int("enabled") == 0 then
|
||||
formspec = formspec..
|
||||
"button[0,1.75;5,1;enable;"..S("@1 Disabled", S("@1 Forcefield Emitter", S("HV"))).."]"
|
||||
else
|
||||
formspec = formspec..
|
||||
"button[0,1.75;5,1;disable;"..S("@1 Enabled", S("@1 Forcefield Emitter", S("HV"))).."]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
||||
local forcefield_receive_fields = function(pos, formname, fields, sender)
|
||||
local player_name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, player_name) then
|
||||
minetest.chat_send_player(player_name, S("You are not allowed to edit this!"))
|
||||
minetest.record_protection_violation(pos, player_name)
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local range = nil
|
||||
if fields.range then
|
||||
range = tonumber(fields.range) or 0
|
||||
-- Smallest field is 5. Anything less is asking for trouble.
|
||||
-- Largest is 20. It is a matter of pratical node handling.
|
||||
-- At the maximim range updating the forcefield takes about 0.2s
|
||||
range = math.max(range, 5)
|
||||
range = math.min(range, 20)
|
||||
if range == meta:get_int("range") then range = nil end
|
||||
end
|
||||
if fields.shape0 or fields.shape1 or range then
|
||||
update_forcefield(pos, meta, false)
|
||||
end
|
||||
if range then meta:set_int("range", range) end
|
||||
if fields.channel then meta:set_string("channel", fields.channel) end
|
||||
if fields.shape0 then meta:set_int("shape", 0) end
|
||||
if fields.shape1 then meta:set_int("shape", 1) end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
|
||||
if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
|
||||
set_forcefield_formspec(meta)
|
||||
end
|
||||
|
||||
local mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 1)
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 0)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local digiline_def = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function() end
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function(pos, node, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
local msgt = type(msg)
|
||||
if msgt == "string" then
|
||||
local smsg = msg:lower()
|
||||
msg = {}
|
||||
if smsg == "get" then
|
||||
msg.command = "get"
|
||||
elseif smsg == "off" then
|
||||
msg.command = "off"
|
||||
elseif smsg == "on" then
|
||||
msg.command = "on"
|
||||
elseif smsg == "toggle" then
|
||||
msg.command = "toggle"
|
||||
elseif smsg:sub(1, 5) == "range" then
|
||||
msg.command = "range"
|
||||
msg.value = tonumber(smsg:sub(7))
|
||||
elseif smsg:sub(1, 5) == "shape" then
|
||||
msg.command = "shape"
|
||||
msg.value = smsg:sub(7):lower()
|
||||
msg.value = tonumber(msg.value) or msg.value
|
||||
end
|
||||
elseif msgt ~= "table" then
|
||||
return
|
||||
end
|
||||
if msg.command == "get" then
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
enabled = meta:get_int("enabled"),
|
||||
range = meta:get_int("range"),
|
||||
shape = meta:get_int("shape")
|
||||
})
|
||||
return
|
||||
elseif msg.command == "off" then
|
||||
meta:set_int("enabled", 0)
|
||||
elseif msg.command == "on" then
|
||||
meta:set_int("enabled", 1)
|
||||
elseif msg.command == "toggle" then
|
||||
local onn = meta:get_int("enabled")
|
||||
onn = 1-onn -- Mirror onn with pivot 0.5, so switch between 1 and 0.
|
||||
meta:set_int("enabled", onn)
|
||||
elseif msg.command == "range" then
|
||||
if type(msg.value) ~= "number" then
|
||||
return
|
||||
end
|
||||
msg.value = math.max(msg.value, 5)
|
||||
msg.value = math.min(msg.value, 20)
|
||||
update_forcefield(pos, meta, false)
|
||||
meta:set_int("range", msg.value)
|
||||
elseif msg.command == "shape" then
|
||||
local valuet = type(msg.value)
|
||||
if valuet == "string" then
|
||||
if msg.value == "sphere" then
|
||||
msg.value = 0
|
||||
elseif msg.value == "cube" then
|
||||
msg.value = 1
|
||||
end
|
||||
elseif valuet ~= "number" then
|
||||
return
|
||||
end
|
||||
if not msg.value then
|
||||
return
|
||||
end
|
||||
update_forcefield(pos, meta, false)
|
||||
meta:set_int("shape", msg.value)
|
||||
else
|
||||
return
|
||||
end
|
||||
set_forcefield_formspec(meta)
|
||||
end
|
||||
},
|
||||
}
|
||||
|
||||
local function run(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local eu_input = meta:get_int("HV_EU_input")
|
||||
local enabled = meta:get_int("enabled") ~= 0 and
|
||||
(meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
|
||||
local machine_name = S("@1 Forcefield Emitter", S("HV"))
|
||||
|
||||
local range = meta:get_int("range")
|
||||
local power_requirement
|
||||
if meta:get_int("shape") == 0 then
|
||||
power_requirement = math.floor(4 * math.pi * range * range)
|
||||
else
|
||||
power_requirement = 24 * range * range
|
||||
end
|
||||
power_requirement = power_requirement * forcefield_power_drain
|
||||
|
||||
if not enabled then
|
||||
if node.name == "technic:forcefield_emitter_on" then
|
||||
update_forcefield(pos, meta, false)
|
||||
technic.swap_node(pos, "technic:forcefield_emitter_off")
|
||||
meta:set_string("infotext", S("@1 Disabled", machine_name))
|
||||
end
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
return
|
||||
end
|
||||
meta:set_int("HV_EU_demand", power_requirement)
|
||||
if eu_input < power_requirement then
|
||||
meta:set_string("infotext", S("@1 Unpowered", machine_name))
|
||||
if node.name == "technic:forcefield_emitter_on" then
|
||||
update_forcefield(pos, meta, false)
|
||||
technic.swap_node(pos, "technic:forcefield_emitter_off")
|
||||
end
|
||||
elseif eu_input >= power_requirement then
|
||||
if node.name == "technic:forcefield_emitter_off" then
|
||||
technic.swap_node(pos, "technic:forcefield_emitter_on")
|
||||
meta:set_string("infotext", S("@1 Active", machine_name) .. "\n" ..
|
||||
S("Demand: @1", technic.EU_string(power_requirement)))
|
||||
end
|
||||
update_forcefield(pos, meta, true)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:forcefield_emitter_off", {
|
||||
description = S("@1 Forcefield Emitter", S("HV")),
|
||||
tiles = {
|
||||
"technic_forcefield_emitter_off.png",
|
||||
"technic_machine_bottom.png"..cable_entry,
|
||||
"technic_forcefield_emitter_off.png",
|
||||
"technic_forcefield_emitter_off.png",
|
||||
"technic_forcefield_emitter_off.png",
|
||||
"technic_forcefield_emitter_off.png"
|
||||
},
|
||||
groups = {cracky = 1, technic_machine = 1, technic_hv = 1, pickaxey = 3},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
on_receive_fields = forcefield_receive_fields,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("HV_EU_input", 0)
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
meta:set_int("range", 10)
|
||||
meta:set_int("enabled", 0)
|
||||
meta:set_int("mesecon_mode", 0)
|
||||
meta:set_int("mesecon_effect", 0)
|
||||
if digilines_path then
|
||||
meta:set_string("channel", "forcefield"..minetest.pos_to_string(pos))
|
||||
end
|
||||
meta:set_string("infotext", S("@1 Forcefield Emitter", S("HV")))
|
||||
set_forcefield_formspec(meta)
|
||||
end,
|
||||
mesecons = mesecons,
|
||||
digiline = digiline_def,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:forcefield_emitter_on", {
|
||||
description = S("@1 Forcefield Emitter", S("HV")),
|
||||
tiles = {
|
||||
"technic_forcefield_emitter_on.png",
|
||||
"technic_machine_bottom.png"..cable_entry,
|
||||
"technic_forcefield_emitter_on.png",
|
||||
"technic_forcefield_emitter_on.png",
|
||||
"technic_forcefield_emitter_on.png",
|
||||
"technic_forcefield_emitter_on.png"
|
||||
},
|
||||
groups = {cracky = 1, technic_machine = 1, technic_hv = 1,
|
||||
not_in_creative_inventory=1, pickaxey = 3},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
drop = "technic:forcefield_emitter_off",
|
||||
on_receive_fields = forcefield_receive_fields,
|
||||
on_destruct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_forcefield(pos, meta, false)
|
||||
end,
|
||||
mesecons = mesecons,
|
||||
digiline = digiline_def,
|
||||
technic_run = run,
|
||||
technic_on_disable = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_forcefield(pos, meta, false)
|
||||
technic.swap_node(pos, "technic:forcefield_emitter_off")
|
||||
end,
|
||||
on_blast = function(pos, intensity)
|
||||
minetest.dig_node(pos)
|
||||
return {"technic:forcefield_emitter_off"}
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:forcefield", {
|
||||
description = S("@1 Forcefield", S("HV")),
|
||||
sunlight_propagates = true,
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
light_source = minetest.LIGHT_MAX,
|
||||
diggable = false,
|
||||
drop = '',
|
||||
tiles = {{
|
||||
name = "technic_forcefield_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1.0,
|
||||
},
|
||||
}},
|
||||
on_blast = function(pos, intensity)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") then
|
||||
mesecon.register_mvps_stopper("technic:forcefield")
|
||||
end
|
||||
|
||||
technic.register_machine("HV", "technic:forcefield_emitter_on", technic.receiver)
|
||||
technic.register_machine("HV", "technic:forcefield_emitter_off", technic.receiver)
|
13
mods/technic_plus_beta/technic/machines/HV/generator.lua
Normal file
13
mods/technic_plus_beta/technic/machines/HV/generator.lua
Normal file
|
@ -0,0 +1,13 @@
|
|||
minetest.register_alias("hv_generator", "technic:hv_generator")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_generator',
|
||||
recipe = {
|
||||
{'technic:carbon_plate', 'technic:mv_generator', 'technic:composite_plate'},
|
||||
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_generator({tier="HV", tube=1, supply=1200})
|
||||
|
21
mods/technic_plus_beta/technic/machines/HV/grinder.lua
Normal file
21
mods/technic_plus_beta/technic/machines/HV/grinder.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- HV grinder
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_grinder',
|
||||
recipe = {
|
||||
{'technic:carbon_plate', 'technic:mv_grinder', 'technic:composite_plate'},
|
||||
{'pipeworks:tube_1', 'technic:hv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:hv_grinder", {
|
||||
typename = "grinding",
|
||||
description = S("@1 Grinder", S("HV")),
|
||||
tier="HV",
|
||||
demand={1200, 900, 600},
|
||||
speed=5,
|
||||
upgrade=1,
|
||||
tube=1
|
||||
})
|
20
mods/technic_plus_beta/technic/machines/HV/init.lua
Normal file
20
mods/technic_plus_beta/technic/machines/HV/init.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
technic.register_tier("HV", "High Voltage")
|
||||
|
||||
local path = technic.modpath.."/machines/HV"
|
||||
|
||||
-- Wiring stuff
|
||||
dofile(path.."/cables.lua")
|
||||
dofile(path.."/battery_box.lua")
|
||||
|
||||
-- Generators
|
||||
dofile(path.."/solar_array.lua")
|
||||
dofile(path.."/nuclear_reactor.lua")
|
||||
dofile(path.."/generator.lua")
|
||||
|
||||
-- Machines
|
||||
dofile(path.."/quarry.lua")
|
||||
dofile(path.."/forcefield.lua")
|
||||
dofile(path.."/electric_furnace.lua")
|
||||
dofile(path.."/grinder.lua")
|
||||
dofile(path.."/compressor.lua")
|
557
mods/technic_plus_beta/technic/machines/HV/nuclear_reactor.lua
Normal file
557
mods/technic_plus_beta/technic/machines/HV/nuclear_reactor.lua
Normal file
|
@ -0,0 +1,557 @@
|
|||
--[[
|
||||
The enriched uranium rod driven EU generator.
|
||||
A very large and advanced machine providing vast amounts of power.
|
||||
Very efficient but also expensive to run as it needs uranium.
|
||||
Provides 100000 HV EUs for one week (only counted when loaded).
|
||||
|
||||
The nuclear reactor core requires a casing of water and a protective
|
||||
shield to work. This is checked now and then and if the casing is not
|
||||
intact the reactor will melt down!
|
||||
--]]
|
||||
|
||||
local burn_ticks = 7 * 24 * 60 * 60 -- Seconds
|
||||
local power_supply = 100000 -- EUs
|
||||
local fuel_type = "technic:uranium_fuel" -- The reactor burns this
|
||||
local digiline_meltdown = technic.config:get_bool("enable_nuclear_reactor_digiline_selfdestruct")
|
||||
local has_digilines = minetest.get_modpath("digilines")
|
||||
local has_mcl = minetest.get_modpath("mcl_core")
|
||||
local mat = technic.materials
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local reactor_desc = S("@1 Nuclear Reactor Core", S("HV"))
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
-- FIXME: Recipe should make more sense like a rod recepticle, steam chamber, HV generator?
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_nuclear_reactor_core',
|
||||
recipe = {
|
||||
{'technic:carbon_plate', mat.obsidian_glass, 'technic:carbon_plate'},
|
||||
{'technic:composite_plate', 'technic:machine_casing', 'technic:composite_plate'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,9]" or "size[8,9]"
|
||||
local function make_reactor_formspec(meta)
|
||||
local f = size..
|
||||
"label[0,0;"..S("Nuclear Reactor Rod Compartment").."]"..
|
||||
"list[context;src;2,1;3,2;]"..
|
||||
"listring[context;src]"..
|
||||
"button[5.5,1.5;2,1;start;"..S("Start").."]"..
|
||||
"checkbox[5.5,2.5;autostart;"..S("Automatic Start")..";"..meta:get_string("autostart").."]"
|
||||
if has_mcl then
|
||||
f = f..
|
||||
mcl_formspec.get_itemslot_bg(2,1,3,2)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
|
||||
"listring[current_player;main]"
|
||||
else
|
||||
f = f..
|
||||
"list[current_player;main;0,5;8,4;]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
if not has_digilines then
|
||||
return f
|
||||
end
|
||||
local digiline_enabled = meta:get_string("enable_digiline")
|
||||
f = f.."checkbox[0.5,2.8;enable_digiline;Enable Digiline;"..digiline_enabled.."]"
|
||||
if digiline_enabled ~= "true" then
|
||||
return f
|
||||
end
|
||||
return f..
|
||||
"button_exit[4.6,3.69;2,1;save;"..S("Save").."]"..
|
||||
"field[1,4;4,1;channel;"..S("Digiline Channel")..";${channel}]"
|
||||
end
|
||||
|
||||
local SS_OFF = 0
|
||||
local SS_DANGER = 1
|
||||
local SS_CLEAR = 2
|
||||
|
||||
local reactor_siren = {}
|
||||
local function siren_set_state(pos, state)
|
||||
local hpos = minetest.hash_node_position(pos)
|
||||
local siren = reactor_siren[hpos]
|
||||
if not siren then
|
||||
if state == SS_OFF then return end
|
||||
siren = {state=SS_OFF}
|
||||
reactor_siren[hpos] = siren
|
||||
end
|
||||
if state == SS_DANGER and siren.state ~= SS_DANGER then
|
||||
if siren.handle then minetest.sound_stop(siren.handle) end
|
||||
siren.handle = minetest.sound_play("technic_hv_nuclear_reactor_siren_danger_loop",
|
||||
{pos=pos, gain=1.5, loop=true, max_hear_distance=48})
|
||||
siren.state = SS_DANGER
|
||||
elseif state == SS_CLEAR then
|
||||
if siren.handle then minetest.sound_stop(siren.handle) end
|
||||
local clear_handle = minetest.sound_play("technic_hv_nuclear_reactor_siren_clear",
|
||||
{pos=pos, gain=1.5, loop=false, max_hear_distance=48})
|
||||
siren.handle = clear_handle
|
||||
siren.state = SS_CLEAR
|
||||
minetest.after(10, function()
|
||||
if siren.handle ~= clear_handle then return end
|
||||
minetest.sound_stop(clear_handle)
|
||||
if reactor_siren[hpos] == siren then
|
||||
reactor_siren[hpos] = nil
|
||||
end
|
||||
end)
|
||||
elseif state == SS_OFF and siren.state ~= SS_OFF then
|
||||
if siren.handle then minetest.sound_stop(siren.handle) end
|
||||
reactor_siren[hpos] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function siren_danger(pos, meta)
|
||||
meta:set_int("siren", 1)
|
||||
siren_set_state(pos, SS_DANGER)
|
||||
end
|
||||
|
||||
local function siren_clear(pos, meta)
|
||||
if meta:get_int("siren") ~= 0 then
|
||||
siren_set_state(pos, SS_CLEAR)
|
||||
meta:set_int("siren", 0)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
The standard reactor structure consists of a 9x9x9 cube. A cross
|
||||
section through the middle:
|
||||
|
||||
CCCC CCCC
|
||||
CBBB BBBC
|
||||
CBLL LLBC
|
||||
CBLWWWLBC
|
||||
CBLW#WLBC
|
||||
CBLW|WLBC
|
||||
CBLL|LLBC
|
||||
CBBB|BBBC
|
||||
CCCC|CCCC
|
||||
C = Concrete, B = Blast-resistant concrete, L = Lead,
|
||||
W = water node, # = reactor core, | = HV cable
|
||||
|
||||
The man-hole is optional (but necessary for refueling).
|
||||
|
||||
For the reactor to operate and not melt down, it insists on the inner
|
||||
7x7x7 portion (from the core out to the blast-resistant concrete)
|
||||
being intact. Intactness only depends on the number of nodes of the
|
||||
right type in each layer. The water layer must have water in all but
|
||||
at most one node; the steel and blast-resistant concrete layers must
|
||||
have the right material in all but at most two nodes. The permitted
|
||||
gaps are meant for the cable and man-hole, but can actually be anywhere
|
||||
and contain anything. For the reactor to be useful, a cable must
|
||||
connect to the core, but it can go in any direction.
|
||||
|
||||
The outer concrete layer of the standard structure is not required
|
||||
for the reactor to operate. It is noted here because it used to
|
||||
be mandatory, and for historical reasons (that it predates the
|
||||
implementation of radiation) it needs to continue being adequate
|
||||
shielding of legacy reactors. If it ever ceases to be adequate
|
||||
shielding for new reactors, legacy ones should be grandfathered.
|
||||
|
||||
For legacy reasons, if the reactor has a stainless steel layer instead
|
||||
of a lead layer it will be converted to a lead layer.
|
||||
--]]
|
||||
local function reactor_structure_badness(pos)
|
||||
local vm = VoxelManip()
|
||||
local pos1 = vector.subtract(pos, 3)
|
||||
local pos2 = vector.add(pos, 3)
|
||||
local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2)
|
||||
local data = vm:get_data()
|
||||
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
|
||||
|
||||
local c_blast_concrete = minetest.get_content_id("technic:blast_resistant_concrete")
|
||||
local c_lead = minetest.get_content_id("technic:lead_block")
|
||||
local c_steel = minetest.get_content_id("technic:stainless_steel_block")
|
||||
local c_water_source = minetest.get_content_id(mat.water_source)
|
||||
local c_water_flowing = minetest.get_content_id(mat.water_flowing)
|
||||
|
||||
local blast_layer, steel_layer, lead_layer, water_layer = 0, 0, 0, 0
|
||||
|
||||
for z = pos1.z, pos2.z do
|
||||
for y = pos1.y, pos2.y do
|
||||
for x = pos1.x, pos2.x do
|
||||
local cid = data[area:index(x, y, z)]
|
||||
if x == pos1.x or x == pos2.x or
|
||||
y == pos1.y or y == pos2.y or
|
||||
z == pos1.z or z == pos2.z then
|
||||
if cid == c_blast_concrete then
|
||||
blast_layer = blast_layer + 1
|
||||
end
|
||||
elseif x == pos1.x+1 or x == pos2.x-1 or
|
||||
y == pos1.y+1 or y == pos2.y-1 or
|
||||
z == pos1.z+1 or z == pos2.z-1 then
|
||||
if cid == c_lead then
|
||||
lead_layer = lead_layer + 1
|
||||
elseif cid == c_steel then
|
||||
steel_layer = steel_layer + 1
|
||||
end
|
||||
elseif x == pos1.x+2 or x == pos2.x-2 or
|
||||
y == pos1.y+2 or y == pos2.y-2 or
|
||||
z == pos1.z+2 or z == pos2.z-2 then
|
||||
if cid == c_water_source or cid == c_water_flowing then
|
||||
water_layer = water_layer + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if steel_layer >= 96 then
|
||||
for z = pos1.z+1, pos2.z-1 do
|
||||
for y = pos1.y+1, pos2.y-1 do
|
||||
for x = pos1.x+1, pos2.x-1 do
|
||||
local vi = area:index(x, y, z)
|
||||
if x == pos1.x+1 or x == pos2.x-1 or
|
||||
y == pos1.y+1 or y == pos2.y-1 or
|
||||
z == pos1.z+1 or z == pos2.z-1 then
|
||||
if data[vi] == c_steel then
|
||||
data[vi] = c_lead
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
lead_layer = steel_layer
|
||||
end
|
||||
|
||||
if water_layer > 25 then water_layer = 25 end
|
||||
if lead_layer > 96 then lead_layer = 96 end
|
||||
if blast_layer > 216 then blast_layer = 216 end
|
||||
return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer)
|
||||
end
|
||||
|
||||
local mcl_expl_info = {
|
||||
drop_chance = 1.0,
|
||||
max_blast_resistance = 10,
|
||||
sound = true,
|
||||
particles = true,
|
||||
fire = true,
|
||||
griefing = true,
|
||||
grief_protected = true,
|
||||
}
|
||||
|
||||
local function melt_down_reactor(pos)
|
||||
minetest.log("action", "A reactor melted down at "..minetest.pos_to_string(pos))
|
||||
if minetest.get_modpath("mcl_explosions") then
|
||||
mcl_explosions.explode(pos, 30, mcl_expl_info)
|
||||
end
|
||||
minetest.set_node(pos, {name = "technic:corium_source"})
|
||||
end
|
||||
|
||||
|
||||
local function start_reactor(pos, meta)
|
||||
if minetest.get_node(pos).name ~= "technic:hv_nuclear_reactor_core" then
|
||||
return false
|
||||
end
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
local src_list = inv:get_list("src")
|
||||
local correct_fuel_count = 0
|
||||
for _, src_stack in pairs(src_list) do
|
||||
if src_stack and src_stack:get_name() == fuel_type then
|
||||
correct_fuel_count = correct_fuel_count + 1
|
||||
end
|
||||
end
|
||||
-- Check that the reactor is complete and has the correct fuel
|
||||
if correct_fuel_count ~= 6 or reactor_structure_badness(pos) ~= 0 then
|
||||
return false
|
||||
end
|
||||
meta:set_int("burn_time", 1)
|
||||
technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active")
|
||||
meta:set_int("HV_EU_supply", power_supply)
|
||||
for idx, src_stack in pairs(src_list) do
|
||||
src_stack:take_item()
|
||||
inv:set_stack("src", idx, src_stack)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Machines: reactor melt-down check",
|
||||
nodenames = {"technic:hv_nuclear_reactor_core_active"},
|
||||
interval = 4,
|
||||
chance = 1,
|
||||
action = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local badness = reactor_structure_badness(pos)
|
||||
local accum_badness = meta:get_int("structure_accumulated_badness")
|
||||
if badness == 0 then
|
||||
if accum_badness ~= 0 then
|
||||
meta:set_int("structure_accumulated_badness", math.max(accum_badness - 4, 0))
|
||||
siren_clear(pos, meta)
|
||||
end
|
||||
else
|
||||
siren_danger(pos, meta)
|
||||
accum_badness = accum_badness + badness
|
||||
if accum_badness >= 25 then
|
||||
melt_down_reactor(pos)
|
||||
else
|
||||
meta:set_int("structure_accumulated_badness", accum_badness)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local function run(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local burn_time = meta:get_int("burn_time") or 0
|
||||
if burn_time >= burn_ticks or burn_time == 0 then
|
||||
if has_digilines and meta:get_int("HV_EU_supply") == power_supply then
|
||||
digilines.receptor_send(pos, technic.digilines.rules_allfaces,
|
||||
-- TODO: Remove "remote_channel" and use de facto standard "channel"
|
||||
meta:get("channel") or meta:get_string("remote_channel"),
|
||||
{
|
||||
command = "fuel_used",
|
||||
pos = pos
|
||||
}
|
||||
)
|
||||
end
|
||||
if meta:get_string("autostart") == "true" then
|
||||
if start_reactor(pos, meta) then
|
||||
return
|
||||
end
|
||||
end
|
||||
meta:set_int("HV_EU_supply", 0)
|
||||
meta:set_int("burn_time", 0)
|
||||
meta:set_string("infotext", S("@1 Idle", reactor_desc))
|
||||
technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
|
||||
meta:set_int("structure_accumulated_badness", 0)
|
||||
siren_clear(pos, meta)
|
||||
elseif burn_time > 0 then
|
||||
burn_time = burn_time + 1
|
||||
meta:set_int("burn_time", burn_time)
|
||||
local percent = math.floor(burn_time / burn_ticks * 100)
|
||||
meta:set_string("infotext", S("@1 (@2% Fuel Used)", reactor_desc, percent))
|
||||
meta:set_int("HV_EU_supply", power_supply)
|
||||
end
|
||||
end
|
||||
|
||||
local nuclear_reactor_receive_fields = function(pos, formname, fields, sender)
|
||||
local player_name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, player_name) then
|
||||
minetest.chat_send_player(player_name, S("You are not allowed to edit this!"))
|
||||
minetest.record_protection_violation(pos, player_name)
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local update_formspec = false
|
||||
if fields.channel or fields.remote_channel then
|
||||
-- TODO: Remove "remote_channel" and use de facto standard "channel"
|
||||
meta:set_string("remote_channel", fields.channel or fields.remote_channel)
|
||||
meta:set_string("channel", fields.channel or fields.remote_channel)
|
||||
end
|
||||
if fields.start then
|
||||
local b = start_reactor(pos, meta)
|
||||
if b then
|
||||
minetest.chat_send_player(player_name, S("Start successful"))
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("Error"))
|
||||
end
|
||||
end
|
||||
if fields.autostart then
|
||||
meta:set_string("autostart", fields.autostart)
|
||||
update_formspec = true
|
||||
end
|
||||
if fields.enable_digiline then
|
||||
meta:set_string("enable_digiline", fields.enable_digiline)
|
||||
update_formspec = true
|
||||
end
|
||||
if update_formspec then
|
||||
meta:set_string("formspec", make_reactor_formspec(meta))
|
||||
end
|
||||
end
|
||||
|
||||
local digiline_def = function(pos, _, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("enable_digiline") ~= "true" or
|
||||
-- TODO: Remove "remote_channel" and use de facto standard "channel"
|
||||
channel ~= (meta:get("channel") or meta:get_string("remote_channel")) then
|
||||
return
|
||||
end
|
||||
-- Convert string messages to tables:
|
||||
local msgt = type(msg)
|
||||
if msgt == "string" then
|
||||
local smsg = msg:lower()
|
||||
msg = {}
|
||||
if smsg == "get" then
|
||||
msg.command = "get"
|
||||
elseif smsg:sub(1, 13) == "self_destruct" then
|
||||
msg.command = "self_destruct"
|
||||
msg.timer = tonumber(smsg:sub(15)) or 0
|
||||
elseif smsg == "start" then
|
||||
msg.command = "start"
|
||||
end
|
||||
elseif msgt ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
if msg.command == "get" then
|
||||
local inv = meta:get_inventory()
|
||||
local invtable = {}
|
||||
for i = 1, 6 do
|
||||
local stack = inv:get_stack("src", i)
|
||||
if stack:is_empty() then
|
||||
invtable[i] = 0
|
||||
elseif stack:get_name() == fuel_type then
|
||||
invtable[i] = stack:get_count()
|
||||
else
|
||||
invtable[i] = -stack:get_count()
|
||||
end
|
||||
end
|
||||
digilines.receptor_send(pos, technic.digilines.rules_allfaces, channel, {
|
||||
burn_time = meta:get_int("burn_time"),
|
||||
enabled = meta:get_int("HV_EU_supply") == power_supply,
|
||||
siren = meta:get_int("siren") == 1,
|
||||
structure_accumulated_badness = meta:get_int("structure_accumulated_badness"),
|
||||
rods = invtable
|
||||
})
|
||||
elseif digiline_meltdown and msg.command == "self_destruct" and
|
||||
minetest.get_node(pos).name == "technic:hv_nuclear_reactor_core_active" then
|
||||
if msg.timer ~= 0 and type(msg.timer) == "number" then
|
||||
siren_danger(pos, meta)
|
||||
minetest.after(msg.timer, melt_down_reactor, pos)
|
||||
else
|
||||
melt_down_reactor(pos)
|
||||
end
|
||||
elseif msg.command == "start" then
|
||||
local b = start_reactor(pos, meta)
|
||||
if b then
|
||||
digilines.receptor_send(pos, technic.digilines.rules_allfaces, channel, {
|
||||
command = "start_success",
|
||||
pos = pos
|
||||
})
|
||||
else
|
||||
digilines.receptor_send(pos, technic.digilines.rules_allfaces, channel, {
|
||||
command = "start_error",
|
||||
pos = pos
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:hv_nuclear_reactor_core", {
|
||||
description = reactor_desc,
|
||||
tiles = {
|
||||
"technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png"..cable_entry
|
||||
},
|
||||
drawtype = "mesh",
|
||||
mesh = "technic_reactor.obj",
|
||||
groups = {cracky = 1, technic_machine = 1, technic_hv = 1, pickaxey = 3},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
stack_max = 1,
|
||||
on_receive_fields = nuclear_reactor_receive_fields,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", reactor_desc)
|
||||
meta:set_string("formspec", make_reactor_formspec(meta))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", 6)
|
||||
end,
|
||||
|
||||
-- digiline interface
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules_allfaces,
|
||||
action = function() end,
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules_allfaces,
|
||||
action = digiline_def,
|
||||
},
|
||||
},
|
||||
|
||||
can_dig = technic.machine_can_dig,
|
||||
on_destruct = function(pos) siren_set_state(pos, SS_OFF) end,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:hv_nuclear_reactor_core_active", {
|
||||
tiles = {
|
||||
"technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png"..cable_entry
|
||||
},
|
||||
drawtype = "mesh",
|
||||
mesh = "technic_reactor.obj",
|
||||
groups = {cracky = 1, technic_machine = 1, technic_hv = 1, radioactive = 4,
|
||||
not_in_creative_inventory = 1, pickaxey = 3},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
drop = "technic:hv_nuclear_reactor_core",
|
||||
light_source = 14,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
on_receive_fields = nuclear_reactor_receive_fields,
|
||||
|
||||
-- digiline interface
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules_allfaces,
|
||||
action = function() end,
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules_allfaces,
|
||||
action = digiline_def,
|
||||
},
|
||||
},
|
||||
|
||||
can_dig = technic.machine_can_dig,
|
||||
after_dig_node = melt_down_reactor,
|
||||
on_destruct = function(pos) siren_set_state(pos, SS_OFF) end,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
technic_run = run,
|
||||
technic_on_disable = function(pos, node)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(1)
|
||||
end,
|
||||
on_timer = function(pos, node)
|
||||
-- Connected back?
|
||||
if technic.get_timeout("HV", pos) > 0 then return false end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local burn_time = meta:get_int("burn_time") or 0
|
||||
|
||||
if burn_time >= burn_ticks or burn_time == 0 then
|
||||
meta:set_int("HV_EU_supply", 0)
|
||||
meta:set_int("burn_time", 0)
|
||||
technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
|
||||
meta:set_int("structure_accumulated_badness", 0)
|
||||
siren_clear(pos, meta)
|
||||
return false
|
||||
end
|
||||
|
||||
meta:set_int("burn_time", burn_time + 1)
|
||||
return true
|
||||
end,
|
||||
})
|
||||
|
||||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core", technic.producer)
|
||||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core_active", technic.producer)
|
640
mods/technic_plus_beta/technic/machines/HV/quarry.lua
Normal file
640
mods/technic_plus_beta/technic/machines/HV/quarry.lua
Normal file
|
@ -0,0 +1,640 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
local has_digilines = minetest.get_modpath("digilines")
|
||||
local has_mesecons = minetest.get_modpath("mesecons")
|
||||
local has_vizlib = minetest.get_modpath("vizlib")
|
||||
local has_jumpdrive = minetest.get_modpath("jumpdrive")
|
||||
local has_mcl = minetest.get_modpath("mcl_formspec")
|
||||
|
||||
local quarry_max_depth = technic.config:get_int("quarry_max_depth")
|
||||
local quarry_dig_particles = technic.config:get_bool("quarry_dig_particles")
|
||||
local quarry_time_limit = technic.config:get_int("quarry_time_limit")
|
||||
local quarry_demand = 10000
|
||||
local network_time_limit = 30000
|
||||
|
||||
local infotext
|
||||
do
|
||||
local name = S("@1 Quarry", S("HV"))
|
||||
local demand = S("Demand: @1", technic.EU_string(quarry_demand))
|
||||
infotext = {
|
||||
active = S("@1 Active", name).."\n"..demand,
|
||||
disabled = S("@1 Disabled", name),
|
||||
finished = S("@1 Finished", name),
|
||||
purge = S("@1 Purging Cache", name),
|
||||
unpowered = S("@1 Unpowered", name),
|
||||
}
|
||||
end
|
||||
|
||||
-- Hard-coded outward-spiral dig pattern for up to 17x17 dig area
|
||||
local dig_pattern = {
|
||||
0,1,2,2,3,3,0,0,0,1,1,1,2,2,2,2,3,3,3,3,0,0,0,0,0,1,1,1,1,1,2,2,
|
||||
2,2,2,2,3,3,3,3,3,3,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,
|
||||
2,2,2,2,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
|
||||
1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
}
|
||||
|
||||
-- Convert the dig pattern values to x/z offset vectors
|
||||
do
|
||||
local head = vector.new()
|
||||
dig_pattern[0] = head
|
||||
for i = 1, #dig_pattern do
|
||||
head = vector.add(head, minetest.facedir_to_dir(dig_pattern[i]))
|
||||
dig_pattern[i] = {x = head.x, z = head.z}
|
||||
end
|
||||
end
|
||||
|
||||
-- Cache of pipeworks fake players
|
||||
local fake_players = {}
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
fake_players[player:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
local function get_fake_player(name)
|
||||
if not fake_players[name] then
|
||||
fake_players[name] = pipeworks.create_fake_player({name = name})
|
||||
end
|
||||
return fake_players[name]
|
||||
end
|
||||
|
||||
local function player_allowed(pos, name)
|
||||
local owner = minetest.get_meta(pos):get_string("owner")
|
||||
if owner == "" or owner == name then
|
||||
return true
|
||||
end
|
||||
return not minetest.is_protected(pos, name)
|
||||
end
|
||||
|
||||
local function can_dig_node(pos, dig_pos, node_name, owner, digger)
|
||||
if node_name == "air" or node_name == "vacuum:vacuum" then
|
||||
return false
|
||||
end
|
||||
if vector.equals(pos, dig_pos) then
|
||||
return false -- Don't dig self
|
||||
end
|
||||
local def = minetest.registered_nodes[node_name]
|
||||
if not def or not def.diggable or (def.can_dig and not def.can_dig(dig_pos, digger)) then
|
||||
return false
|
||||
end
|
||||
if def._mcl_hardness == -1 then
|
||||
return false
|
||||
end
|
||||
return not minetest.is_protected(dig_pos, owner)
|
||||
end
|
||||
|
||||
local function do_purge(pos, meta)
|
||||
local inv = meta:get_inventory()
|
||||
for i, stack in ipairs(inv:get_list("cache")) do
|
||||
if not stack:is_empty() then
|
||||
technic.tube_inject_item(pos, pos, vector.new(0, 1, 0), stack:to_table())
|
||||
inv:set_stack("cache", i, "")
|
||||
break
|
||||
end
|
||||
end
|
||||
if inv:is_empty("cache") then
|
||||
meta:set_int("purge_on", 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_dig_particles(pos, dig_pos, node)
|
||||
local end_pos = vector.new(pos.x, pos.y - 0.5, pos.z)
|
||||
local dist = vector.distance(dig_pos, end_pos)
|
||||
local t = math.sqrt((2 * dist) / 20)
|
||||
local acc = vector.multiply(vector.subtract(end_pos, dig_pos), (1 / dist) * 20)
|
||||
minetest.add_particlespawner({
|
||||
amount = 50,
|
||||
time = 0.5,
|
||||
minpos = vector.subtract(dig_pos, 0.4),
|
||||
maxpos = vector.add(dig_pos, 0.4),
|
||||
minacc = acc,
|
||||
maxacc = acc,
|
||||
minsize = 0.5,
|
||||
maxsize = 1.5,
|
||||
minexptime = t,
|
||||
maxexptime = t,
|
||||
node = node,
|
||||
})
|
||||
end
|
||||
|
||||
local function do_digging(pos, meta, net_time)
|
||||
local us_start = minetest.get_us_time()
|
||||
local step = tonumber(meta:get("step") or "")
|
||||
if not step then
|
||||
-- Missing metadata or not yet updated by conversion LBM, abort digging
|
||||
return
|
||||
end
|
||||
local radius = meta:get_int("size")
|
||||
local diameter = radius * 2 + 1
|
||||
local num_steps = diameter * diameter
|
||||
local dug = meta:get_int("dug")
|
||||
local max_depth = meta:get_int("max_depth")
|
||||
local offset = {
|
||||
x = meta:get_int("offset_x"),
|
||||
y = math.floor(step / num_steps) + 1 - meta:get_int("offset_y"),
|
||||
z = meta:get_int("offset_z")
|
||||
}
|
||||
if dug == -1 then
|
||||
-- Find ground before digging
|
||||
if offset.y > max_depth then
|
||||
meta:set_int("finished", 1)
|
||||
return
|
||||
end
|
||||
local pos1 = {
|
||||
x = pos.x + offset.x - radius,
|
||||
y = pos.y - offset.y,
|
||||
z = pos.z + offset.z - radius
|
||||
}
|
||||
local pos2 = {
|
||||
x = pos.x + offset.x + radius,
|
||||
y = pos.y - offset.y,
|
||||
z = pos.z + offset.z + radius
|
||||
}
|
||||
minetest.load_area(pos1, pos2)
|
||||
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"air", "vacuum:vacuum"})
|
||||
if #nodes < num_steps then
|
||||
-- There are nodes to dig, start digging at this layer
|
||||
meta:set_int("dug", 0)
|
||||
else
|
||||
-- Move down to next layer
|
||||
meta:set_int("step", step + num_steps)
|
||||
end
|
||||
return
|
||||
end
|
||||
local owner = meta:get_string("owner")
|
||||
local digger = get_fake_player(owner)
|
||||
while true do
|
||||
-- Search for something to dig
|
||||
if offset.y > max_depth then
|
||||
-- Finished digging
|
||||
meta:set_int("finished", 1)
|
||||
meta:set_int("purge_on", 1)
|
||||
break
|
||||
end
|
||||
local dig_offset = dig_pattern[step % num_steps]
|
||||
local dig_pos = {
|
||||
x = pos.x + offset.x + dig_offset.x,
|
||||
y = pos.y - offset.y,
|
||||
z = pos.z + offset.z + dig_offset.z,
|
||||
}
|
||||
step = step + 1
|
||||
if step % num_steps == 0 then
|
||||
-- Finished this layer, move down
|
||||
offset.y = offset.y + 1
|
||||
end
|
||||
local node = technic.get_or_load_node(dig_pos)
|
||||
if can_dig_node(pos, dig_pos, node.name, owner, digger) then
|
||||
-- Found something to dig, dig it and stop
|
||||
minetest.remove_node(dig_pos)
|
||||
if quarry_dig_particles then
|
||||
spawn_dig_particles(pos, dig_pos, node)
|
||||
end
|
||||
local inv = meta:get_inventory()
|
||||
local drops = minetest.get_node_drops(node.name, "")
|
||||
local full = false
|
||||
for _, item in ipairs(drops) do
|
||||
local left = inv:add_item("cache", item)
|
||||
while not left:is_empty() do
|
||||
-- Cache is full, forcibly purge until the item fits
|
||||
full = true
|
||||
do_purge(pos, meta)
|
||||
left = inv:add_item("cache", left)
|
||||
end
|
||||
end
|
||||
dug = dug + 1
|
||||
if full or dug % 99 == 0 then
|
||||
-- Time to purge the cache
|
||||
meta:set_int("purge_on", 1)
|
||||
end
|
||||
break
|
||||
end
|
||||
local us_used = minetest.get_us_time() - us_start
|
||||
if us_used > quarry_time_limit or net_time + us_used > network_time_limit then
|
||||
break
|
||||
end
|
||||
end
|
||||
meta:set_int("dug", dug)
|
||||
meta:set_int("step", step)
|
||||
end
|
||||
|
||||
local function quarry_run(pos, _, _, network)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_int("purge_on") == 1 then
|
||||
-- Purging
|
||||
meta:set_string("infotext", infotext.purge)
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
do_purge(pos, meta)
|
||||
elseif meta:get_int("finished") == 1 then
|
||||
-- Finished
|
||||
meta:set_string("infotext", infotext.finished)
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
elseif meta:get_int("enabled") == 1 then
|
||||
-- Active
|
||||
if meta:get_int("HV_EU_input") >= quarry_demand then
|
||||
meta:set_string("infotext", infotext.active)
|
||||
do_digging(pos, meta, network.lag)
|
||||
else
|
||||
meta:set_string("infotext", infotext.unpowered)
|
||||
end
|
||||
meta:set_int("HV_EU_demand", quarry_demand)
|
||||
else
|
||||
-- Disabled
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
meta:set_string("infotext", infotext.disabled)
|
||||
if not meta:get_inventory():is_empty("cache") then
|
||||
meta:set_int("purge_on", 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function reset_quarry(meta)
|
||||
meta:set_int("step", 0)
|
||||
meta:set_int("dug", -1)
|
||||
meta:set_int("purge_on", 1)
|
||||
meta:set_int("finished", 0)
|
||||
end
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,10]" or "size[8,9]"
|
||||
local base_formspec = size..
|
||||
"label[0,0;"..S("@1 Quarry", S("HV")).."]"..
|
||||
"list[context;cache;0,0.7;4,3;]"..
|
||||
"listring[context;cache]"..
|
||||
"button[6,0.6;2,1;restart;"..S("Restart").."]"..
|
||||
"field[4.3,2.1;2,1;size;"..S("Radius")..";${size}]"..
|
||||
"field[6.3,2.1;2,1;max_depth;"..S("Max Depth")..";${max_depth}]"..
|
||||
"field[4.3,3.1;1.333,1;offset_x;"..S("Offset X")..";${offset_x}]"..
|
||||
"field[5.633,3.1;1.333,1;offset_y;"..S("Offset Y")..";${offset_y}]"..
|
||||
"field[6.966,3.1;1.333,1;offset_z;"..S("Offset Z")..";${offset_z}]"
|
||||
|
||||
if has_digilines then
|
||||
base_formspec = base_formspec..
|
||||
"field[4.3,4.2;4,1;channel;"..S("Digiline Channel")..";${channel}]"
|
||||
end
|
||||
|
||||
if has_mcl then
|
||||
base_formspec = base_formspec..
|
||||
mcl_formspec.get_itemslot_bg(0,0.7,4,3)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,5.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,5.5,9,3)..
|
||||
"list[current_player;main;0,8.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,8.74,9,1)..
|
||||
"listring[current_player;main]"
|
||||
else
|
||||
base_formspec = base_formspec..
|
||||
"list[current_player;main;0,5;8,4;]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local function update_formspec(meta)
|
||||
local fs = base_formspec
|
||||
local status = S("Digging not started")
|
||||
if meta:get_int("purge_on") == 1 then
|
||||
status = S("Purging cache")
|
||||
elseif meta:get_int("finished") == 1 then
|
||||
status = S("Digging finished")
|
||||
elseif meta:get_int("enabled") == 1 then
|
||||
local diameter = meta:get_int("size") * 2 + 1
|
||||
local num_steps = diameter * diameter
|
||||
local y_level = math.floor(meta:get_int("step") / num_steps) + 1 - meta:get_int("offset_y")
|
||||
if y_level < 0 then
|
||||
status = S("Digging @1 m above machine", math.abs(y_level))
|
||||
else
|
||||
status = S("Digging @1 m below machine", y_level)
|
||||
end
|
||||
end
|
||||
if meta:get_int("enabled") == 1 then
|
||||
fs = fs.."button[4,0.6;2,1;disable;"..S("Enabled").."]"
|
||||
else
|
||||
fs = fs.."button[4,0.6;2,1;enable;"..S("Disabled").."]"
|
||||
end
|
||||
if has_mesecons then
|
||||
local selected = meta:get("mesecons") or "true"
|
||||
if has_jumpdrive then
|
||||
fs = fs.."checkbox[0,3.6;mesecons;"..S("Enable Mesecons Control")..";"..selected.."]"
|
||||
else
|
||||
fs = fs.."checkbox[0,3.8;mesecons;"..S("Enable Mesecons Control")..";"..selected.."]"
|
||||
end
|
||||
end
|
||||
if has_jumpdrive then
|
||||
local selected = meta:get("reset_on_move") or "true"
|
||||
if has_mesecons then
|
||||
fs = fs.."checkbox[0,4.1;reset_on_move;"..S("Restart When Moved")..";"..selected.."]"
|
||||
else
|
||||
fs = fs.."checkbox[0,3.8;reset_on_move;"..S("Restart When Moved")..";"..selected.."]"
|
||||
end
|
||||
end
|
||||
meta:set_string("formspec", fs.."label[4,0;"..status.."]")
|
||||
end
|
||||
|
||||
local function clamp(value, min, max, default)
|
||||
value = tonumber(value) or default or max
|
||||
return math.min(math.max(value, min), max)
|
||||
end
|
||||
|
||||
local function quarry_receive_fields(pos, _, fields, sender)
|
||||
local player_name = sender:get_player_name()
|
||||
if not player_allowed(pos, player_name) then
|
||||
minetest.chat_send_player(player_name, S("You are not allowed to edit this!"))
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.size then
|
||||
meta:set_int("size", clamp(fields.size, 0, 8, 4))
|
||||
end
|
||||
if fields.max_depth then
|
||||
local depth = clamp(fields.max_depth, 1, quarry_max_depth)
|
||||
meta:set_int("max_depth", depth)
|
||||
local ymin = -math.min(10, depth - 1)
|
||||
meta:set_int("offset_y", clamp(meta:get_int("offset_y"), ymin, 10, 0))
|
||||
end
|
||||
if fields.offset_x then
|
||||
meta:set_int("offset_x", clamp(fields.offset_x, -10, 10, 0))
|
||||
end
|
||||
if fields.offset_y then
|
||||
local ymin = -math.min(10, meta:get_int("max_depth") - 1)
|
||||
meta:set_int("offset_y", clamp(fields.offset_y, ymin, 10, 0))
|
||||
end
|
||||
if fields.offset_z then
|
||||
meta:set_int("offset_z", clamp(fields.offset_z, -10, 10, 0))
|
||||
end
|
||||
if fields.mesecons then
|
||||
meta:set_string("mesecons", fields.mesecons)
|
||||
end
|
||||
if fields.reset_on_move then
|
||||
meta:set_string("reset_on_move", fields.reset_on_move)
|
||||
end
|
||||
if fields.channel then
|
||||
meta:set_string("channel", fields.channel)
|
||||
end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.restart then reset_quarry(meta) end
|
||||
update_formspec(meta)
|
||||
end
|
||||
|
||||
local function show_working_area(pos, _, player)
|
||||
if not player or player:get_wielded_item():get_name() ~= "" then
|
||||
-- Only spawn particles when using an empty hand
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local radius = meta:get_int("size") + 0.5
|
||||
local offset = vector.new(meta:get_int("offset_x"), meta:get_int("offset_y"), meta:get_int("offset_z"))
|
||||
local depth = meta:get_int("max_depth") + 0.5
|
||||
-- Draw area from top corner to bottom corner
|
||||
local pos1 = vector.add(pos, vector.new(offset.x - radius, offset.y - 0.5, offset.z - radius))
|
||||
local pos2 = vector.add(pos, vector.new(offset.x + radius, -depth, offset.z + radius))
|
||||
vizlib.draw_area(pos1, pos2, {player = player})
|
||||
end
|
||||
|
||||
local function digiline_action(pos, _, channel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
-- Convert string message to table
|
||||
if type(msg) == "string" then
|
||||
msg = msg:lower()
|
||||
if msg == "get" or msg == "on" or msg == "off" or msg == "restart" then
|
||||
msg = {command = msg}
|
||||
elseif msg:sub(1, 7) == "radius " then
|
||||
msg = {command = "radius", value = msg:sub(8,-1)}
|
||||
elseif msg:sub(1,10) == "max_depth " then
|
||||
msg = {command = "max_depth", value = msg:sub(11,-1)}
|
||||
elseif msg:sub(1,9) == "offset_x " then
|
||||
msg = {command = "offset_x", value = msg:sub(10,-1)}
|
||||
elseif msg:sub(1,9) == "offset_y " then
|
||||
msg = {command = "offset_y", value = msg:sub(10,-1)}
|
||||
elseif msg:sub(1,9) == "offset_z " then
|
||||
msg = {command = "offset_z", value = msg:sub(10,-1)}
|
||||
elseif msg:sub(1,7) == "offset " then
|
||||
local s = string.split(msg:sub(8,-1), ",")
|
||||
msg = {command = "offset", value = {x = s[1], y = s[2], z = s[3]}}
|
||||
end
|
||||
end
|
||||
if type(msg) ~= "table" then return end
|
||||
-- Convert old message format to new format
|
||||
if msg.command ~= "set" and msg.command ~= "get" then
|
||||
local cmd = msg.command
|
||||
if cmd == "restart" then
|
||||
msg = {command = "set", restart = true}
|
||||
elseif cmd == "on" or cmd == "off" then
|
||||
msg = {command = "set", enabled = msg.command == "on"}
|
||||
elseif cmd == "radius" or cmd == "max_depth" or cmd == "offset"
|
||||
or cmd == "offset_x" or cmd == "offset_y" or cmd == "offset_z" then
|
||||
msg = {command = "set", [cmd] = msg.value}
|
||||
end
|
||||
end
|
||||
-- Process message
|
||||
if msg.command == "get" then
|
||||
local diameter = meta:get_int("size") * 2 + 1
|
||||
local num_steps = diameter * diameter
|
||||
local offset = {
|
||||
x = meta:get_int("offset_x"),
|
||||
y = meta:get_int("offset_y"),
|
||||
z = meta:get_int("offset_z")
|
||||
}
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
enabled = meta:get_int("enabled") == 1,
|
||||
finished = meta:get_int("finished") == 1,
|
||||
radius = meta:get_int("size"),
|
||||
max_depth = meta:get_int("max_depth"),
|
||||
offset_x = offset.x,
|
||||
offset_y = offset.y,
|
||||
offset_z = offset.z,
|
||||
offset = offset,
|
||||
dug_nodes = meta:get_int("dug"),
|
||||
dig_level = -(math.floor(meta:get_int("step") / num_steps) + 1 - offset.y),
|
||||
})
|
||||
elseif msg.command == "set" then
|
||||
if msg.enabled ~= nil then
|
||||
meta:set_int("enabled", msg.enabled == true and 1 or 0)
|
||||
end
|
||||
if msg.restart == true then
|
||||
reset_quarry(meta)
|
||||
end
|
||||
if msg.radius then
|
||||
meta:set_int("size", clamp(msg.radius, 0, 8, 4))
|
||||
end
|
||||
if msg.max_depth then
|
||||
local depth = clamp(msg.max_depth, 1, quarry_max_depth)
|
||||
meta:set_int("max_depth", depth)
|
||||
local ymin = -math.min(10, depth - 1)
|
||||
meta:set_int("offset_y", clamp(meta:get_int("offset_y"), ymin, 10, 0))
|
||||
end
|
||||
if msg.offset_x then
|
||||
meta:set_int("offset_x", clamp(msg.offset_x, -10, 10, 0))
|
||||
end
|
||||
if msg.offset_y then
|
||||
local ymin = -math.min(10, meta:get_int("max_depth") - 1)
|
||||
meta:set_int("offset_y", clamp(msg.offset_y, ymin, 10, 0))
|
||||
end
|
||||
if msg.offset_z then
|
||||
meta:set_int("offset_z", clamp(msg.offset_z, -10, 10, 0))
|
||||
end
|
||||
if msg.offset and type(msg.offset) == "table" then
|
||||
local ymin = -math.min(10, meta:get_int("max_depth") - 1)
|
||||
meta:set_int("offset_x", clamp(msg.offset.x, -10, 10, 0))
|
||||
meta:set_int("offset_y", clamp(msg.offset.y, ymin, 10, 0))
|
||||
meta:set_int("offset_z", clamp(msg.offset.z, -10, 10, 0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:quarry", {
|
||||
description = S("@1 Quarry", S("HV")),
|
||||
tiles = {
|
||||
"technic_carbon_steel_block.png^pipeworks_tube_connection_metallic.png",
|
||||
"technic_carbon_steel_block.png^technic_quarry_bottom.png",
|
||||
"technic_carbon_steel_block.png^technic_cable_connection_overlay.png",
|
||||
"technic_carbon_steel_block.png^technic_cable_connection_overlay.png",
|
||||
"technic_carbon_steel_block.png^technic_cable_connection_overlay.png",
|
||||
"technic_carbon_steel_block.png^technic_cable_connection_overlay.png"
|
||||
},
|
||||
groups = {cracky = 2, tubedevice = 1, technic_machine = 1, technic_hv = 1, pickaxey = 2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"front", "back", "left", "right"},
|
||||
tube = {
|
||||
connect_sides = {top = 1},
|
||||
-- Lower priority than tubes, so items will prefer any tube to another quarry
|
||||
priority = 10,
|
||||
can_go = function(pos, node, velocity, stack)
|
||||
-- Always eject up, even if items came in another way
|
||||
return { vector.new(0, 1, 0) }
|
||||
end
|
||||
},
|
||||
on_punch = has_vizlib and show_working_area or nil,
|
||||
on_rightclick = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_formspec(meta)
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("size", 4)
|
||||
meta:set_int("offset_x", 0)
|
||||
meta:set_int("offset_y", 0)
|
||||
meta:set_int("offset_z", 0)
|
||||
meta:set_int("max_depth", quarry_max_depth)
|
||||
meta:set_string("mesecons", "false")
|
||||
meta:set_string("reset_on_move", "false")
|
||||
meta:get_inventory():set_size("cache", 12)
|
||||
reset_quarry(meta)
|
||||
update_formspec(meta)
|
||||
end,
|
||||
on_movenode = has_jumpdrive and function(_, pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get("reset_on_move") ~= "false" then
|
||||
reset_quarry(meta)
|
||||
end
|
||||
end or nil,
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
minetest.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
return minetest.get_meta(pos):get_inventory():is_empty("cache")
|
||||
end,
|
||||
after_dig_node = pipeworks.scan_for_tube_objects,
|
||||
on_receive_fields = quarry_receive_fields,
|
||||
technic_run = quarry_run,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
return player_allowed(pos, player:get_player_name()) and count or 0
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
return player_allowed(pos, player:get_player_name()) and stack:get_count() or 0
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
return player_allowed(pos, player:get_player_name()) and stack:get_count() or 0
|
||||
end,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get("mesecons") ~= "false" then
|
||||
meta:set_int("enabled", 1)
|
||||
end
|
||||
end,
|
||||
action_off = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get("mesecons") ~= "false" then
|
||||
meta:set_int("enabled", 0)
|
||||
end
|
||||
end
|
||||
}
|
||||
},
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = digiline_action,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:quarry",
|
||||
recipe = {
|
||||
{"technic:carbon_plate", "pipeworks:filter", "technic:composite_plate"},
|
||||
{"basic_materials:motor", "technic:machine_casing", "technic:diamond_drill_head"},
|
||||
{"technic:carbon_steel_block", "technic:hv_cable", "technic:carbon_steel_block"}
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_machine("HV", "technic:quarry", technic.receiver)
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Old quarry conversion",
|
||||
name = "technic:old_quarry_conversion",
|
||||
nodenames = {"technic:quarry"},
|
||||
run_at_every_load = false,
|
||||
action = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get("step") then
|
||||
-- Quarry v3, don't do anything
|
||||
-- This can happen when a quarry is moved with a jumpdrive
|
||||
return
|
||||
elseif meta:get("quarry_pos") then
|
||||
-- Quarry v2, calculate step if quarry is digging below
|
||||
local level = meta:get_int("dig_level") - pos.y
|
||||
if level < 0 then
|
||||
local diameter = meta:get_int("size") * 2 + 1
|
||||
local num_steps = diameter * diameter
|
||||
-- Convert the negative value to positive, and go back up one level
|
||||
level = math.abs(level + 1)
|
||||
meta:set_int("step", level * num_steps)
|
||||
end
|
||||
-- Delete unused meta values
|
||||
meta:set_string("quarry_dir", "")
|
||||
meta:set_string("quarry_pos", "")
|
||||
meta:set_string("dig_pos", "")
|
||||
meta:set_string("dig_level", "")
|
||||
meta:set_string("dig_index", "")
|
||||
meta:set_string("dig_steps", "")
|
||||
else
|
||||
-- Quarry v1, reset quarry
|
||||
reset_quarry(meta)
|
||||
end
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
local offset = vector.multiply(dir, meta:get_int("size") + 1)
|
||||
meta:set_int("offset_x", offset.x)
|
||||
meta:set_int("offset_y", 4)
|
||||
meta:set_int("offset_z", offset.z)
|
||||
if not meta:get("max_depth") then
|
||||
meta:set_int("max_depth", quarry_max_depth)
|
||||
end
|
||||
update_formspec(meta)
|
||||
end
|
||||
})
|
18
mods/technic_plus_beta/technic/machines/HV/solar_array.lua
Normal file
18
mods/technic_plus_beta/technic/machines/HV/solar_array.lua
Normal file
|
@ -0,0 +1,18 @@
|
|||
-- The high voltage solar array is an assembly of medium voltage arrays.
|
||||
-- Solar arrays are not able to store large amounts of energy.
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_solar_array 1',
|
||||
recipe = {
|
||||
{'technic:mv_solar_array', 'technic:mv_solar_array', 'technic:mv_solar_array'},
|
||||
{'technic:carbon_plate', 'technic:hv_transformer', 'technic:composite_plate'},
|
||||
{'', 'technic:hv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_solar_array("technic:hv_solar_array", {
|
||||
tier="HV",
|
||||
power=100
|
||||
})
|
||||
|
||||
minetest.register_alias("technic:solar_array_hv", "technic:hv_solar_array")
|
23
mods/technic_plus_beta/technic/machines/LV/alloy_furnace.lua
Normal file
23
mods/technic_plus_beta/technic/machines/LV/alloy_furnace.lua
Normal file
|
@ -0,0 +1,23 @@
|
|||
-- LV Alloy furnace
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
-- FIXME: kpoppel: I'd like to introduce an induction heating element here...
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_alloy_furnace',
|
||||
recipe = {
|
||||
{mat.brick, mat.brick, mat.brick},
|
||||
{mat.brick, 'technic:machine_casing', mat.brick},
|
||||
{mat.brick, 'technic:lv_cable', mat.brick},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:lv_alloy_furnace", {
|
||||
typename = "alloy",
|
||||
description = S("@1 Alloy Furnace", S("LV")),
|
||||
insert_object = technic.insert_object_unique_stack,
|
||||
can_insert = technic.can_insert_unique_stack,
|
||||
tier = "LV",
|
||||
speed = 1,
|
||||
demand = {300}
|
||||
})
|
19
mods/technic_plus_beta/technic/machines/LV/battery_box.lua
Normal file
19
mods/technic_plus_beta/technic/machines/LV/battery_box.lua
Normal file
|
@ -0,0 +1,19 @@
|
|||
-- LV Battery box
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_battery_box0',
|
||||
recipe = {
|
||||
{'group:wood', 'group:wood', 'group:wood'},
|
||||
{'technic:battery', 'technic:machine_casing', 'technic:battery'},
|
||||
{'technic:battery', 'technic:lv_cable', 'technic:battery'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_battery_box("technic:lv_battery_box", {
|
||||
tier = "LV",
|
||||
max_charge = 40000,
|
||||
charge_rate = 1000,
|
||||
discharge_rate = 4000,
|
||||
charge_step = 500,
|
||||
discharge_step = 800,
|
||||
})
|
57
mods/technic_plus_beta/technic/machines/LV/cables.lua
Normal file
57
mods/technic_plus_beta/technic/machines/LV/cables.lua
Normal file
|
@ -0,0 +1,57 @@
|
|||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("lv_cable", "technic:lv_cable")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_cable 6',
|
||||
recipe = {
|
||||
{mat.paper, mat.paper, mat.paper},
|
||||
{mat.copper_ingot, mat.copper_ingot, mat.copper_ingot},
|
||||
{mat.paper, mat.paper, mat.paper},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:lv_cable_plate_1 5",
|
||||
recipe = {
|
||||
{"" , "" , "technic:lv_cable"},
|
||||
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"},
|
||||
{"" , "" , "technic:lv_cable"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:lv_cable",
|
||||
recipe = {{"technic:lv_cable_plate_1"}}
|
||||
})
|
||||
|
||||
-- Register cables
|
||||
|
||||
technic.register_cable("technic:lv_cable", {
|
||||
tier = "LV",
|
||||
size = 2/16,
|
||||
description = S("@1 Cable", S("LV"))
|
||||
})
|
||||
technic.register_cable_plate("technic:lv_cable_plate", {
|
||||
tier = "LV",
|
||||
size = 2/16,
|
||||
description = S("@1 Cable Plate", S("LV")),
|
||||
tiles = {"technic_lv_cable.png"},
|
||||
})
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
technic.register_cable("technic:lv_digi_cable", {
|
||||
tier = "LV",
|
||||
size = 2/16,
|
||||
description = S("@1 Digiline Cable", S("LV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } }
|
||||
})
|
||||
technic.register_cable_plate("technic:lv_digi_cable_plate", {
|
||||
tier = "LV",
|
||||
size = 2/16,
|
||||
description = S("@1 Digiline Cable Plate", S("LV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } },
|
||||
tiles = {"technic_lv_digi_cable.png"}
|
||||
})
|
||||
end
|
26
mods/technic_plus_beta/technic/machines/LV/compressor.lua
Normal file
26
mods/technic_plus_beta/technic/machines/LV/compressor.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("compressor", "technic:lv_compressor")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_compressor',
|
||||
recipe = {
|
||||
{mat.stone, 'basic_materials:motor', mat.stone},
|
||||
{'mesecons:piston', 'technic:machine_casing', 'mesecons:piston'},
|
||||
{'basic_materials:silver_wire', 'technic:lv_cable', 'basic_materials:silver_wire'},
|
||||
},
|
||||
replacements = {
|
||||
{"basic_materials:silver_wire", "basic_materials:empty_spool"},
|
||||
{"basic_materials:silver_wire", "basic_materials:empty_spool"}
|
||||
},
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:lv_compressor", {
|
||||
typename = "compressing",
|
||||
description = S("@1 Compressor", S("LV")),
|
||||
tier = "LV",
|
||||
demand = {300},
|
||||
speed = 1
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
-- LV Electric Furnace
|
||||
-- This is a faster version of the stone furnace which runs on EUs
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
-- FIXME: kpoppel I'd like to introduce an induction heating element here also
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_electric_furnace',
|
||||
recipe = {
|
||||
{mat.cobble, mat.cobble, mat.cobble},
|
||||
{mat.cobble, 'technic:machine_casing', mat.cobble},
|
||||
{mat.cobble, 'technic:lv_cable', mat.cobble},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:lv_electric_furnace", {
|
||||
typename = "cooking",
|
||||
description = S("@1 Furnace", S("LV")),
|
||||
tier="LV",
|
||||
demand={300},
|
||||
speed = 2
|
||||
})
|
35
mods/technic_plus_beta/technic/machines/LV/extractor.lua
Normal file
35
mods/technic_plus_beta/technic/machines/LV/extractor.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
local S = technic.getter
|
||||
|
||||
minetest.register_alias("extractor", "technic:lv_extractor")
|
||||
|
||||
if technic.config:get_bool("enable_tree_tap") then
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_extractor',
|
||||
recipe = {
|
||||
{'technic:treetap', 'basic_materials:motor', 'technic:treetap'},
|
||||
{'technic:treetap', 'technic:machine_casing', 'technic:treetap'},
|
||||
{'', 'technic:lv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_extractor',
|
||||
recipe = {
|
||||
{'basic_materials:motor', 'pipeworks:tube_1', 'basic_materials:motor'},
|
||||
{'technic:carbon_steel_ingot', 'technic:machine_casing', 'technic:carbon_steel_ingot'},
|
||||
{'', 'technic:lv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
technic.register_base_machine("technic:lv_extractor", {
|
||||
typename = "extracting",
|
||||
description = S("@1 Extractor", S("LV")),
|
||||
tier = "LV",
|
||||
demand = {300},
|
||||
speed = 1
|
||||
})
|
20
mods/technic_plus_beta/technic/machines/LV/generator.lua
Normal file
20
mods/technic_plus_beta/technic/machines/LV/generator.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
-- The electric generator.
|
||||
-- A simple device to get started on the electric machines.
|
||||
-- Inefficient and expensive in fuel (200EU per tick)
|
||||
-- Also only allows for LV machinery to run.
|
||||
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("lv_generator", "technic:lv_generator")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_generator',
|
||||
recipe = {
|
||||
{mat.stone, mat.furnace, mat.stone},
|
||||
{mat.stone, 'technic:machine_casing', mat.stone},
|
||||
{mat.stone, 'technic:lv_cable', mat.stone},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_generator({tier="LV", supply=200})
|
||||
|
124
mods/technic_plus_beta/technic/machines/LV/geothermal.lua
Normal file
124
mods/technic_plus_beta/technic/machines/LV/geothermal.lua
Normal file
|
@ -0,0 +1,124 @@
|
|||
-- A geothermal EU generator
|
||||
-- Using hot lava and water this device can create energy from steam
|
||||
-- The machine is only producing LV EUs and can thus not drive more advanced equipment
|
||||
-- The output is a little more than the coal burning generator (max 300EUs)
|
||||
|
||||
minetest.register_alias("geothermal", "technic:geothermal")
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:geothermal',
|
||||
recipe = {
|
||||
{'technic:granite', mat.diamond, 'technic:granite'},
|
||||
{'basic_materials:copper_wire', 'technic:machine_casing', 'basic_materials:copper_wire'},
|
||||
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
|
||||
},
|
||||
replacements = {
|
||||
{"basic_materials:copper_wire", "basic_materials:empty_spool"},
|
||||
{"basic_materials:copper_wire", "basic_materials:empty_spool"}
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("technic:geothermal", {
|
||||
description = S("Geothermal @1 Generator", S("LV")),
|
||||
})
|
||||
|
||||
local check_node_around = function(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == mat.water_source or node.name == mat.water_flowing then return 1 end
|
||||
if node.name == mat.lava_source or node.name == mat.lava_flowing then return 2 end
|
||||
return 0
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local water_nodes = 0
|
||||
local lava_nodes = 0
|
||||
local production_level = 0
|
||||
local eu_supply = 0
|
||||
|
||||
-- Correct positioning is water on one side and lava on the other.
|
||||
-- The two cannot be adjacent because the lava the turns into obsidian or rock.
|
||||
-- To get to 100% production stack the water and lava one extra block down as well:
|
||||
-- WGL (W=Water, L=Lava, G=the generator, |=an LV cable)
|
||||
-- W|L
|
||||
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x+1, y=pos.y-1, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y-1, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y-1, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1},
|
||||
{x=pos.x, y=pos.y-1, z=pos.z-1},
|
||||
}
|
||||
for _, p in pairs(positions) do
|
||||
local check = check_node_around(p)
|
||||
if check == 1 then water_nodes = water_nodes + 1 end
|
||||
if check == 2 then lava_nodes = lava_nodes + 1 end
|
||||
end
|
||||
|
||||
if water_nodes == 1 and lava_nodes == 1 then production_level = 25; eu_supply = 50 end
|
||||
if water_nodes == 2 and lava_nodes == 1 then production_level = 50; eu_supply = 100 end
|
||||
if water_nodes == 1 and lava_nodes == 2 then production_level = 75; eu_supply = 200 end
|
||||
if water_nodes == 2 and lava_nodes == 2 then production_level = 100; eu_supply = 300 end
|
||||
|
||||
if production_level > 0 then
|
||||
meta:set_int("LV_EU_supply", eu_supply)
|
||||
end
|
||||
|
||||
meta:set_string("infotext", S("@1 (@2% Efficiency)",
|
||||
S("Geothermal @1 Generator", S("LV")), production_level))
|
||||
|
||||
if production_level > 0 and minetest.get_node(pos).name == "technic:geothermal" then
|
||||
technic.swap_node (pos, "technic:geothermal_active")
|
||||
return
|
||||
end
|
||||
if production_level == 0 then
|
||||
technic.swap_node(pos, "technic:geothermal")
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:geothermal", {
|
||||
description = S("Geothermal @1 Generator", S("LV")),
|
||||
tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
|
||||
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
paramtype2 = "facedir",
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Geothermal @1 Generator", S("LV")))
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
end,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:geothermal_active", {
|
||||
description = S("Geothermal @1 Generator", S("LV")),
|
||||
tiles = {"technic_geothermal_top_active.png", "technic_machine_bottom.png", "technic_geothermal_side.png",
|
||||
"technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, not_in_creative_inventory=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
drop = "technic:geothermal",
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:geothermal", technic.producer)
|
||||
technic.register_machine("LV", "technic:geothermal_active", technic.producer)
|
||||
|
20
mods/technic_plus_beta/technic/machines/LV/grinder.lua
Normal file
20
mods/technic_plus_beta/technic/machines/LV/grinder.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("grinder", "technic:lv_grinder")
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_grinder',
|
||||
recipe = {
|
||||
{mat.desert_stone, mat.diamond, mat.desert_stone},
|
||||
{mat.desert_stone, 'technic:machine_casing', mat.desert_stone},
|
||||
{'technic:granite', 'technic:lv_cable', 'technic:granite'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:lv_grinder", {
|
||||
typename = "grinding",
|
||||
description = S("@1 Grinder", S("LV")),
|
||||
tier="LV",
|
||||
demand={200},
|
||||
speed=1
|
||||
})
|
27
mods/technic_plus_beta/technic/machines/LV/init.lua
Normal file
27
mods/technic_plus_beta/technic/machines/LV/init.lua
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
technic.register_tier("LV", "Low Voltage")
|
||||
|
||||
local path = technic.modpath.."/machines/LV"
|
||||
|
||||
-- Wiring stuff
|
||||
dofile(path.."/cables.lua")
|
||||
dofile(path.."/battery_box.lua")
|
||||
|
||||
-- Generators
|
||||
dofile(path.."/solar_panel.lua")
|
||||
dofile(path.."/solar_array.lua")
|
||||
dofile(path.."/geothermal.lua")
|
||||
dofile(path.."/water_mill.lua")
|
||||
dofile(path.."/generator.lua")
|
||||
|
||||
-- Machines
|
||||
dofile(path.."/alloy_furnace.lua")
|
||||
dofile(path.."/electric_furnace.lua")
|
||||
dofile(path.."/grinder.lua")
|
||||
dofile(path.."/extractor.lua")
|
||||
dofile(path.."/compressor.lua")
|
||||
|
||||
dofile(path.."/music_player.lua")
|
||||
|
||||
dofile(path.."/led.lua")
|
||||
dofile(path.."/lamp.lua")
|
204
mods/technic_plus_beta/technic/machines/LV/lamp.lua
Normal file
204
mods/technic_plus_beta/technic/machines/LV/lamp.lua
Normal file
|
@ -0,0 +1,204 @@
|
|||
|
||||
-- LV Lamp - a powerful light source.
|
||||
-- Illuminates a 7x7x3(H) volume below itself with light bright as the sun.
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local demand = 50
|
||||
local desc = S("@1 Lamp", S("LV"))
|
||||
local active_desc = S("@1 Active", desc).."\n"..S("Demand: @1", technic.EU_string(demand))
|
||||
local unpowered_desc = S("@1 Unpowered", desc)
|
||||
local off_desc = S("@1 Off", desc)
|
||||
|
||||
-- Invisible light source node used for illumination
|
||||
minetest.register_node("technic:dummy_light_source", {
|
||||
description = S("Dummy light source node"),
|
||||
inventory_image = "technic_dummy_light_source.png",
|
||||
wield_image = "technic_dummy_light_source.png",
|
||||
paramtype = "light",
|
||||
drawtype = "airlike",
|
||||
light_source = 14,
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
diggable = false,
|
||||
pointable = false,
|
||||
--drop = "", -- Intentionally allowed to drop itself
|
||||
groups = {not_in_creative_inventory = 1}
|
||||
})
|
||||
|
||||
local cid_light = minetest.get_content_id("technic:dummy_light_source")
|
||||
local cid_air = minetest.CONTENT_AIR
|
||||
|
||||
local function illuminate(pos, active)
|
||||
local pos1 = {x = pos.x - 3, y = pos.y - 3, z = pos.z - 3}
|
||||
local pos2 = {x = pos.x + 3, y = pos.y - 1, z = pos.z + 3}
|
||||
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
local va = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local node_data = vm:get_data()
|
||||
|
||||
local find_node = active and cid_air or cid_light
|
||||
local set_node = active and cid_light or cid_air
|
||||
|
||||
local dirty = false
|
||||
for i in va:iterp(pos1, pos2) do
|
||||
if node_data[i] == find_node then
|
||||
node_data[i] = set_node
|
||||
dirty = true
|
||||
end
|
||||
end
|
||||
if dirty then
|
||||
vm:set_data(node_data)
|
||||
vm:write_to_map()
|
||||
end
|
||||
end
|
||||
|
||||
local function set_random_timer(pos, mint, maxt)
|
||||
local t = math.random(mint * 10, maxt * 10) * 0.1
|
||||
minetest.get_node_timer(pos):start(t)
|
||||
end
|
||||
|
||||
local function lamp_run(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
if meta:get_int("LV_EU_demand") == 0 then
|
||||
return -- Lamp is turned off
|
||||
end
|
||||
|
||||
local eu_input = meta:get_int("LV_EU_input")
|
||||
|
||||
if node.name == "technic:lv_lamp_active" then
|
||||
if eu_input < demand then
|
||||
technic.swap_node(pos, "technic:lv_lamp")
|
||||
meta:set_string("infotext", unpowered_desc)
|
||||
set_random_timer(pos, 0.2, 1)
|
||||
end
|
||||
elseif node.name == "technic:lv_lamp" then
|
||||
if eu_input >= demand then
|
||||
technic.swap_node(pos, "technic:lv_lamp_active")
|
||||
meta:set_string("infotext", active_desc)
|
||||
set_random_timer(pos, 0.2, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function lamp_toggle(pos, node, player)
|
||||
if not player or minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_int("LV_EU_demand") == 0 then
|
||||
meta:set_string("infotext", active_desc)
|
||||
meta:set_int("LV_EU_demand", demand)
|
||||
else
|
||||
technic.swap_node(pos, "technic:lv_lamp")
|
||||
meta:set_string("infotext", off_desc)
|
||||
meta:set_int("LV_EU_demand", 0)
|
||||
set_random_timer(pos, 0.2, 1)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:lv_lamp", {
|
||||
description = desc,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5,0.5,0.5,-0.5,-0.2,-0.5}
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5,0.5,0.5,-0.5,-0.2,-0.5}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5,0.5,0.5,-0.5,-0.2,-0.5}
|
||||
},
|
||||
tiles = {
|
||||
"technic_lv_lamp_top.png",
|
||||
"technic_lv_lamp_bottom.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png"
|
||||
},
|
||||
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, pickaxey = 2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"front", "back", "left", "right", "top"},
|
||||
can_dig = technic.machine_can_dig,
|
||||
technic_run = lamp_run,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", desc)
|
||||
meta:set_int("LV_EU_demand", demand)
|
||||
end,
|
||||
on_destruct = illuminate,
|
||||
on_rightclick = lamp_toggle,
|
||||
on_timer = function(pos)
|
||||
illuminate(pos, false)
|
||||
-- Don't start the timer again, otherwise lights will fight each other
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:lv_lamp_active", {
|
||||
description = active_desc,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5, 0.5, 0.5, -0.5, -0.2, -0.5}
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5, 0.5, 0.5, -0.5, -0.2, -0.5}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.5, 0.5, 0.5, -0.5, -0.2, -0.5}
|
||||
},
|
||||
tiles = {
|
||||
"technic_lv_lamp_top.png",
|
||||
"technic_lv_lamp_bottom.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png",
|
||||
"technic_lv_lamp_side.png"
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 14,
|
||||
drop = "technic:lv_lamp",
|
||||
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1, pickaxey = 2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"front", "back", "left", "right", "top"},
|
||||
can_dig = technic.machine_can_dig,
|
||||
technic_run = lamp_run,
|
||||
technic_on_disable = function(pos)
|
||||
technic.swap_node(pos, "technic:lv_lamp")
|
||||
set_random_timer(pos, 0.2, 1)
|
||||
end,
|
||||
on_destruct = illuminate,
|
||||
on_rightclick = lamp_toggle,
|
||||
on_timer = function(pos, elapsed)
|
||||
if elapsed < 60 then -- Don't check immediately after being unloaded
|
||||
illuminate(pos, true)
|
||||
end
|
||||
set_random_timer(pos, 30, 60) -- Check every 30-60 seconds
|
||||
end,
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:lv_lamp", technic.receiver)
|
||||
technic.register_machine("LV", "technic:lv_lamp_active", technic.receiver)
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:lv_lamp",
|
||||
recipe = {
|
||||
{mat.glass, mat.glass, mat.glass},
|
||||
{"technic:lv_led", "technic:lv_led", "technic:lv_led"},
|
||||
{"mesecons_materials:glue", "technic:lv_cable", "mesecons_materials:glue"},
|
||||
}
|
||||
})
|
102
mods/technic_plus_beta/technic/machines/LV/led.lua
Normal file
102
mods/technic_plus_beta/technic/machines/LV/led.lua
Normal file
|
@ -0,0 +1,102 @@
|
|||
|
||||
-- LED - a weak light source.
|
||||
-- Intended primarily as a core component for LED lamps.
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local demand = 5
|
||||
local desc = S("@1 LED", S("LV"))
|
||||
local active_desc = S("@1 Active", desc).."\n"..S("Demand: @1", technic.EU_string(demand))
|
||||
local unpowered_desc = S("@1 Unpowered", desc)
|
||||
|
||||
|
||||
local function led_run(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local eu_input = meta:get_int("LV_EU_input")
|
||||
|
||||
if eu_input < demand and node.name == "technic:lv_led_active" then
|
||||
technic.swap_node(pos, "technic:lv_led")
|
||||
meta:set_string("infotext", unpowered_desc)
|
||||
elseif eu_input >= demand and node.name == "technic:lv_led" then
|
||||
technic.swap_node(pos, "technic:lv_led_active")
|
||||
meta:set_string("infotext", active_desc)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:lv_led", {
|
||||
description = desc,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
tiles = {"technic_lv_led.png"},
|
||||
inventory_image = "technic_lv_led_inv.png",
|
||||
sunlight_propagates = true,
|
||||
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, pickaxey = 2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"front", "back", "left", "right", "top", "bottom"},
|
||||
can_dig = technic.machine_can_dig,
|
||||
technic_run = led_run,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", desc)
|
||||
meta:set_int("LV_EU_demand", demand)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:lv_led_active", {
|
||||
description = active_desc,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0.2, 0.2, 0.2, -0.2, -0.2, -0.2}
|
||||
},
|
||||
tiles = {"technic_lv_led.png"},
|
||||
inventory_image = "technic_lv_led_inv.png",
|
||||
paramtype = "light",
|
||||
light_source = 9,
|
||||
drop = "technic:lv_led",
|
||||
sunlight_propagates = true,
|
||||
groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1, pickaxey = 2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"front", "back", "left", "right", "top", "bottom"},
|
||||
can_dig = technic.machine_can_dig,
|
||||
technic_run = led_run,
|
||||
technic_on_disable = function(pos)
|
||||
technic.swap_node(pos, "technic:lv_led")
|
||||
end,
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:lv_led", technic.receiver)
|
||||
technic.register_machine("LV", "technic:lv_led_active", technic.receiver)
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:lv_led 2",
|
||||
recipe = {
|
||||
{"", "basic_materials:plastic_sheet", ""},
|
||||
{"basic_materials:plastic_sheet", "technic:doped_silicon_wafer", "basic_materials:plastic_sheet"},
|
||||
{"", "basic_materials:silver_wire", ""},
|
||||
},
|
||||
replacements = {{"basic_materials:silver_wire", "basic_materials:empty_spool"}},
|
||||
})
|
134
mods/technic_plus_beta/technic/machines/LV/music_player.lua
Normal file
134
mods/technic_plus_beta/technic/machines/LV/music_player.lua
Normal file
|
@ -0,0 +1,134 @@
|
|||
-- LV Music player.
|
||||
-- The player can play music. But it is high ampage!
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("music_player", "technic:music_player")
|
||||
minetest.register_craft({
|
||||
output = 'technic:music_player',
|
||||
recipe = {
|
||||
{'technic:chromium_ingot', mat.diamond, 'technic:chromium_ingot'},
|
||||
{mat.diamond, 'technic:machine_casing', mat.diamond},
|
||||
{mat.mossycobble, 'technic:lv_cable', mat.mossycobble},
|
||||
}
|
||||
})
|
||||
|
||||
local music_handles = {}
|
||||
|
||||
local function play_track(pos, track)
|
||||
return minetest.sound_play("technic_track"..tostring(track),
|
||||
{pos = pos, gain = 1.0, loop = true, max_hear_distance = 72,})
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local eu_input = meta:get_int("LV_EU_input")
|
||||
local machine_name = S("@1 Music Player", S("LV"))
|
||||
local demand = 150
|
||||
|
||||
local current_track = meta:get_int("current_track")
|
||||
local pos_hash = minetest.hash_node_position(pos)
|
||||
local music_handle = music_handles[pos_hash]
|
||||
|
||||
-- Setup meta data if it does not exist.
|
||||
if not eu_input then
|
||||
meta:set_int("LV_EU_demand", demand)
|
||||
meta:set_int("LV_EU_input", 0)
|
||||
return
|
||||
end
|
||||
|
||||
if meta:get_int("active") == 0 then
|
||||
meta:set_string("infotext", S("@1 Idle", machine_name))
|
||||
meta:set_int("LV_EU_demand", 0)
|
||||
return
|
||||
end
|
||||
|
||||
if eu_input < demand then
|
||||
meta:set_string("infotext", S("@1 Unpowered", machine_name))
|
||||
if music_handle then
|
||||
minetest.sound_stop(music_handle)
|
||||
music_handle = nil
|
||||
end
|
||||
elseif eu_input >= demand then
|
||||
meta:set_string("infotext", S("@1 Active", machine_name) .. "\n" ..
|
||||
S("Demand: @1", technic.EU_string(demand)))
|
||||
if not music_handle then
|
||||
music_handle = play_track(pos, current_track)
|
||||
end
|
||||
end
|
||||
music_handles[pos_hash] = music_handle
|
||||
meta:set_int("LV_EU_demand", demand)
|
||||
end
|
||||
|
||||
local function stop_player(pos, node)
|
||||
local pos_hash = minetest.hash_node_position(pos)
|
||||
local music_handle = music_handles[pos_hash]
|
||||
if music_handle then
|
||||
minetest.sound_stop(music_handle)
|
||||
music_handles[pos_hash] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function set_display(meta)
|
||||
meta:set_string("formspec",
|
||||
"size[4,4.5]"..
|
||||
"item_image[0,0;1,1;technic:music_player]"..
|
||||
"label[1,0;"..S("@1 Music Player", S("LV")).."]"..
|
||||
"button[0,1;1,1;track1;1]"..
|
||||
"button[1,1;1,1;track2;2]"..
|
||||
"button[2,1;1,1;track3;3]"..
|
||||
"button[0,2;1,1;track4;4]"..
|
||||
"button[1,2;1,1;track5;5]"..
|
||||
"button[2,2;1,1;track6;6]"..
|
||||
"button[0,3;1,1;track7;7]"..
|
||||
"button[1,3;1,1;track8;8]"..
|
||||
"button[2,3;1,1;track9;9]"..
|
||||
"button[3,1;1,1;stop;"..S("Stop").."]"..
|
||||
"label[0,4;"..(meta:get_int("active") == 0 and S("Stopped") or
|
||||
S("Current track: @1", meta:get_int("current_track"))).."]")
|
||||
end
|
||||
|
||||
minetest.register_node("technic:music_player", {
|
||||
description = S("@1 Music Player", S("LV")),
|
||||
tiles = {"technic_music_player_top.png", "technic_machine_bottom.png", "technic_music_player_side.png",
|
||||
"technic_music_player_side.png", "technic_music_player_side.png", "technic_music_player_side.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, axey = 2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("@1 Music Player", S("LV")))
|
||||
set_display(meta)
|
||||
end,
|
||||
on_receive_fields = function(pos, formanme, fields, sender)
|
||||
local new_track = nil
|
||||
if fields.stop then new_track = 0 end
|
||||
if fields.track1 then new_track = 1 end
|
||||
if fields.track2 then new_track = 2 end
|
||||
if fields.track3 then new_track = 3 end
|
||||
if fields.track4 then new_track = 4 end
|
||||
if fields.track5 then new_track = 5 end
|
||||
if fields.track6 then new_track = 6 end
|
||||
if fields.track7 then new_track = 7 end
|
||||
if fields.track8 then new_track = 8 end
|
||||
if fields.track9 then new_track = 9 end
|
||||
if new_track then
|
||||
stop_player(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("active", new_track == 0 and 0 or 1)
|
||||
meta:set_int("current_track", new_track)
|
||||
set_display(meta)
|
||||
end
|
||||
end,
|
||||
on_destruct = stop_player,
|
||||
technic_run = run,
|
||||
technic_on_disable = stop_player,
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:music_player", technic.receiver)
|
||||
|
22
mods/technic_plus_beta/technic/machines/LV/solar_array.lua
Normal file
22
mods/technic_plus_beta/technic/machines/LV/solar_array.lua
Normal file
|
@ -0,0 +1,22 @@
|
|||
-- The solar array is an assembly of panels into a powerful array
|
||||
-- The assembly can deliver more energy than the individual panel because
|
||||
-- of the transformer unit which converts the panel output variations into
|
||||
-- a stable supply.
|
||||
-- Solar arrays are not able to store large amounts of energy.
|
||||
-- The LV arrays are used to make medium voltage arrays.
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:lv_solar_array 1',
|
||||
recipe = {
|
||||
{'technic:solar_panel', 'technic:solar_panel', 'technic:solar_panel'},
|
||||
{'technic:carbon_steel_ingot', 'technic:lv_transformer', 'technic:carbon_steel_ingot'},
|
||||
{'', 'technic:lv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_solar_array("technic:lv_solar_array", {
|
||||
tier="LV",
|
||||
power=10
|
||||
})
|
||||
|
||||
minetest.register_alias("technic:solar_array_lv", "technic:lv_solar_array")
|
74
mods/technic_plus_beta/technic/machines/LV/solar_panel.lua
Normal file
74
mods/technic_plus_beta/technic/machines/LV/solar_panel.lua
Normal file
|
@ -0,0 +1,74 @@
|
|||
-- Solar panels are the building blocks of LV solar arrays
|
||||
-- They can however also be used separately but with reduced efficiency due to the missing transformer.
|
||||
-- Individual panels are less efficient than when the panels are combined into full arrays.
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:solar_panel',
|
||||
recipe = {
|
||||
{'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer'},
|
||||
{'basic_materials:silver_wire', 'technic:lv_cable', 'mesecons_materials:glue'},
|
||||
},
|
||||
replacements = { {"basic_materials:silver_wire", "basic_materials:empty_spool"}, },
|
||||
})
|
||||
|
||||
|
||||
local run = function(pos, node)
|
||||
-- The action here is to make the solar panel prodice power
|
||||
-- Power is dependent on the light level and the height above ground
|
||||
-- There are many ways to cheat by using other light sources like lamps.
|
||||
-- As there is no way to determine if light is sunlight that is just a shame.
|
||||
-- To take care of some of it solar panels do not work outside daylight hours or if
|
||||
-- built below 0m
|
||||
local pos1 = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local machine_name = S("Small Solar @1 Generator", S("LV"))
|
||||
|
||||
local light = minetest.get_node_light(pos1, nil)
|
||||
local time_of_day = minetest.get_timeofday()
|
||||
local meta = minetest.get_meta(pos)
|
||||
if light == nil then light = 0 end
|
||||
-- turn on panel only during day time and if sufficient light
|
||||
-- I know this is counter intuitive when cheating by using other light sources underground.
|
||||
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > -10 then
|
||||
local charge_to_give = math.floor((light + pos1.y) * 3)
|
||||
charge_to_give = math.max(charge_to_give, 0)
|
||||
charge_to_give = math.min(charge_to_give, 200)
|
||||
meta:set_string("infotext", S("@1 Active (@2)", machine_name,
|
||||
technic.EU_string(charge_to_give)))
|
||||
meta:set_int("LV_EU_supply", charge_to_give)
|
||||
else
|
||||
meta:set_string("infotext", S("@1 Idle", machine_name))
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:solar_panel", {
|
||||
tiles = {"technic_solar_panel_top.png", "technic_solar_panel_bottom.png", "technic_solar_panel_side.png",
|
||||
"technic_solar_panel_side.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
description = S("Small Solar @1 Generator", S("LV")),
|
||||
active = false,
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
meta:set_string("infotext", S("Small Solar @1 Generator", S("LV")))
|
||||
end,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:solar_panel", technic.producer)
|
||||
|
115
mods/technic_plus_beta/technic/machines/LV/water_mill.lua
Normal file
115
mods/technic_plus_beta/technic/machines/LV/water_mill.lua
Normal file
|
@ -0,0 +1,115 @@
|
|||
-- A water mill produces LV EUs by exploiting flowing water across it
|
||||
-- It is a LV EU supplier and fairly low yield (max 180EUs)
|
||||
-- It is a little over half as good as the thermal generator.
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
minetest.register_alias("water_mill", "technic:water_mill")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:water_mill',
|
||||
recipe = {
|
||||
{'technic:marble', mat.diamond, 'technic:marble'},
|
||||
{'group:wood', 'technic:machine_casing', 'group:wood'},
|
||||
{'technic:marble', 'technic:lv_cable', 'technic:marble'},
|
||||
}
|
||||
})
|
||||
|
||||
local function check_node_around_mill(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == mat.water_flowing or node.name == mat.river_water_flowing then
|
||||
return node.param2 -- returns approx. water flow, if any
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local water_flow = 0
|
||||
local production_level
|
||||
local eu_supply
|
||||
local max_output = 4 * 45 -- keeping it around 180, little more than previous 150 :)
|
||||
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1},
|
||||
}
|
||||
|
||||
for _, p in pairs(positions) do
|
||||
local check = check_node_around_mill(p)
|
||||
if check then
|
||||
water_flow = water_flow + check
|
||||
end
|
||||
end
|
||||
|
||||
eu_supply = math.min(4 * water_flow, max_output)
|
||||
production_level = math.floor(100 * eu_supply / max_output)
|
||||
|
||||
meta:set_int("LV_EU_supply", eu_supply)
|
||||
|
||||
meta:set_string("infotext", S("@1 (@2% Efficiency)",
|
||||
S("Hydro @1 Generator", S("LV")), production_level))
|
||||
|
||||
if production_level > 0 and
|
||||
minetest.get_node(pos).name == "technic:water_mill" then
|
||||
technic.swap_node (pos, "technic:water_mill_active")
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
return
|
||||
end
|
||||
if production_level == 0 then
|
||||
technic.swap_node(pos, "technic:water_mill")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:water_mill", {
|
||||
description = S("Hydro @1 Generator", S("LV")),
|
||||
tiles = {
|
||||
"technic_water_mill_top.png",
|
||||
"technic_machine_bottom.png"..cable_entry,
|
||||
"technic_water_mill_side.png",
|
||||
"technic_water_mill_side.png",
|
||||
"technic_water_mill_side.png",
|
||||
"technic_water_mill_side.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Hydro @1 Generator", S("LV")))
|
||||
meta:set_int("LV_EU_supply", 0)
|
||||
end,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:water_mill_active", {
|
||||
description = S("Hydro @1 Generator", S("LV")),
|
||||
tiles = {"technic_water_mill_top_active.png", "technic_machine_bottom.png",
|
||||
"technic_water_mill_side.png", "technic_water_mill_side.png",
|
||||
"technic_water_mill_side.png", "technic_water_mill_side.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_lv=1, not_in_creative_inventory=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
drop = "technic:water_mill",
|
||||
technic_run = run,
|
||||
technic_disabled_machine_name = "technic:water_mill",
|
||||
})
|
||||
|
||||
technic.register_machine("LV", "technic:water_mill", technic.producer)
|
||||
technic.register_machine("LV", "technic:water_mill_active", technic.producer)
|
||||
|
23
mods/technic_plus_beta/technic/machines/MV/alloy_furnace.lua
Normal file
23
mods/technic_plus_beta/technic/machines/MV/alloy_furnace.lua
Normal file
|
@ -0,0 +1,23 @@
|
|||
-- MV alloy furnace
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_alloy_furnace',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_alloy_furnace', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_alloy_furnace", {
|
||||
typename = "alloy",
|
||||
description = S("@1 Alloy Furnace", S("MV")),
|
||||
insert_object = technic.insert_object_unique_stack,
|
||||
can_insert = technic.can_insert_unique_stack,
|
||||
tier = "MV",
|
||||
speed = 1.5,
|
||||
upgrade = 1,
|
||||
tube = 1,
|
||||
demand = {3000, 2000, 1000}
|
||||
})
|
21
mods/technic_plus_beta/technic/machines/MV/battery_box.lua
Normal file
21
mods/technic_plus_beta/technic/machines/MV/battery_box.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- MV Battery box
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_battery_box0',
|
||||
recipe = {
|
||||
{'technic:lv_battery_box0', 'technic:lv_battery_box0', 'technic:lv_battery_box0'},
|
||||
{'technic:lv_battery_box0', 'technic:mv_transformer', 'technic:lv_battery_box0'},
|
||||
{'', 'technic:mv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_battery_box("technic:mv_battery_box", {
|
||||
tier = "MV",
|
||||
max_charge = 200000,
|
||||
charge_rate = 20000,
|
||||
discharge_rate = 80000,
|
||||
charge_step = 2000,
|
||||
discharge_step = 8000,
|
||||
upgrade = 1,
|
||||
tube = 1,
|
||||
})
|
56
mods/technic_plus_beta/technic/machines/MV/cables.lua
Normal file
56
mods/technic_plus_beta/technic/machines/MV/cables.lua
Normal file
|
@ -0,0 +1,56 @@
|
|||
local S = technic.getter
|
||||
|
||||
minetest.register_alias("mv_cable", "technic:mv_cable")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_cable 3',
|
||||
recipe ={
|
||||
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
|
||||
{'technic:lv_cable', 'technic:lv_cable', 'technic:lv_cable'},
|
||||
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:mv_cable_plate_1 5",
|
||||
recipe = {
|
||||
{"" , "" , "technic:mv_cable"},
|
||||
{"technic:mv_cable", "technic:mv_cable", "technic:mv_cable"},
|
||||
{"" , "" , "technic:mv_cable"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:mv_cable",
|
||||
recipe = {{"technic:mv_cable_plate_1"}}
|
||||
})
|
||||
|
||||
-- Register cables
|
||||
|
||||
technic.register_cable("technic:mv_cable", {
|
||||
tier = "MV",
|
||||
size = 2.5/16,
|
||||
description = S("@1 Cable", S("MV"))
|
||||
})
|
||||
technic.register_cable_plate("technic:mv_cable_plate", {
|
||||
tier = "MV",
|
||||
size = 2.5/16,
|
||||
description = S("@1 Cable Plate", S("MV")),
|
||||
tiles = {"technic_mv_cable.png"},
|
||||
})
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
technic.register_cable("technic:mv_digi_cable", {
|
||||
tier = "MV",
|
||||
size = 2.5/16,
|
||||
description = S("@1 Digiline Cable", S("MV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } }
|
||||
})
|
||||
technic.register_cable_plate("technic:mv_digi_cable_plate", {
|
||||
tier = "MV",
|
||||
size = 2.5/16,
|
||||
description = S("@1 Digiline Cable Plate", S("MV")),
|
||||
digiline = { wire = { rules = technic.digilines.rules_allfaces } },
|
||||
tiles = {"technic_mv_digi_cable.png"}
|
||||
})
|
||||
end
|
20
mods/technic_plus_beta/technic/machines/MV/centrifuge.lua
Normal file
20
mods/technic_plus_beta/technic/machines/MV/centrifuge.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:mv_centrifuge",
|
||||
recipe = {
|
||||
{"basic_materials:motor", "technic:copper_plate", "technic:diamond_drill_head"},
|
||||
{"technic:copper_plate", "technic:machine_casing", "technic:copper_plate" },
|
||||
{"pipeworks:one_way_tube", "technic:mv_cable", "pipeworks:mese_filter" },
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_centrifuge", {
|
||||
typename = "separating",
|
||||
description = S("@1 Centrifuge", S("MV")),
|
||||
tier = "MV",
|
||||
demand = { 8000, 7000, 6000 },
|
||||
speed = 2,
|
||||
upgrade = 1,
|
||||
tube = 1,
|
||||
})
|
21
mods/technic_plus_beta/technic/machines/MV/compressor.lua
Normal file
21
mods/technic_plus_beta/technic/machines/MV/compressor.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- MV compressor
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_compressor',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_compressor', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_compressor", {
|
||||
typename = "compressing",
|
||||
description = S("@1 Compressor", S("MV")),
|
||||
tier = "MV",
|
||||
demand = {800, 600, 400},
|
||||
speed = 2,
|
||||
upgrade = 1,
|
||||
tube = 1
|
||||
})
|
|
@ -0,0 +1,26 @@
|
|||
-- MV Electric Furnace
|
||||
-- This is a faster version of the stone furnace which runs on EUs
|
||||
-- In addition to this it can be upgraded with microcontrollers and batteries
|
||||
-- This new version uses the batteries to lower the power consumption of the machine
|
||||
-- Also in addition this furnace can be attached to the pipe system from the pipeworks mod.
|
||||
local S = technic.getter
|
||||
|
||||
-- FIXME: kpoppel I'd like to introduce an induction heating element here also
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_electric_furnace',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_electric_furnace', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_electric_furnace", {
|
||||
typename = "cooking",
|
||||
description = S("@1 Furnace", S("MV")),
|
||||
tier="MV",
|
||||
upgrade=1,
|
||||
tube=1,
|
||||
demand={2000, 1000, 500},
|
||||
speed=4
|
||||
})
|
21
mods/technic_plus_beta/technic/machines/MV/extractor.lua
Normal file
21
mods/technic_plus_beta/technic/machines/MV/extractor.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- MV extractor
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_extractor',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_extractor', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_extractor", {
|
||||
typename = "extracting",
|
||||
description = S("@1 Extractor", S("MV")),
|
||||
tier = "MV",
|
||||
demand = {800, 600, 400},
|
||||
speed = 2,
|
||||
upgrade = 1,
|
||||
tube = 1
|
||||
})
|
21
mods/technic_plus_beta/technic/machines/MV/freezer.lua
Normal file
21
mods/technic_plus_beta/technic/machines/MV/freezer.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- MV freezer
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_freezer',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'basic_materials:motor', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:pipe_1_empty', 'technic:mv_transformer', 'pipeworks:pipe_1_empty'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_freezer", {
|
||||
typename = "freezing",
|
||||
description = S("@1 Freezer", S("MV")),
|
||||
tier = "MV",
|
||||
demand = {800, 600, 400},
|
||||
speed = 0.5,
|
||||
upgrade = 1,
|
||||
tube = 1
|
||||
})
|
11
mods/technic_plus_beta/technic/machines/MV/generator.lua
Normal file
11
mods/technic_plus_beta/technic/machines/MV/generator.lua
Normal file
|
@ -0,0 +1,11 @@
|
|||
minetest.register_craft({
|
||||
output = 'technic:mv_generator',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_generator', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_generator({tier="MV", tube=1, supply=600})
|
||||
|
21
mods/technic_plus_beta/technic/machines/MV/grinder.lua
Normal file
21
mods/technic_plus_beta/technic/machines/MV/grinder.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- MV grinder
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_grinder',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:lv_grinder', 'technic:stainless_steel_ingot'},
|
||||
{'pipeworks:tube_1', 'technic:mv_transformer', 'pipeworks:tube_1'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_base_machine("technic:mv_grinder", {
|
||||
typename = "grinding",
|
||||
description = S("@1 Grinder", S("MV")),
|
||||
tier="MV",
|
||||
demand={600, 450, 300},
|
||||
speed=2,
|
||||
upgrade=1,
|
||||
tube=1
|
||||
})
|
111
mods/technic_plus_beta/technic/machines/MV/hydro_turbine.lua
Normal file
111
mods/technic_plus_beta/technic/machines/MV/hydro_turbine.lua
Normal file
|
@ -0,0 +1,111 @@
|
|||
-- A Hydro Turbine produces MV EUs by exploiting flowing water across it
|
||||
-- It is a MV EU supplier and fairly high yield (max 1800EUs)
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
minetest.register_alias("hydro_turbine", "technic:hydro_turbine")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hydro_turbine',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:water_mill', 'technic:stainless_steel_ingot'},
|
||||
{'technic:water_mill', 'technic:mv_transformer', 'technic:water_mill'},
|
||||
{'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
local function get_water_flow(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_item_group(node.name, "water") == 3 then
|
||||
return node.param2 -- returns approx. water flow, if any
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
---
|
||||
-- 10 times better than LV hydro because of 2 extra water mills and 4 stainless steel, a transformer and whatnot ;P.
|
||||
-- Man hydro turbines are tough and long lasting. So, give it some value :)
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local water_flow = 0
|
||||
local production_level
|
||||
local eu_supply
|
||||
local max_output = 40 * 45 -- Generates 1800EU/s
|
||||
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1},
|
||||
}
|
||||
|
||||
for _, p in pairs(positions) do
|
||||
water_flow = water_flow + get_water_flow(p)
|
||||
end
|
||||
|
||||
eu_supply = math.min(40 * water_flow, max_output)
|
||||
production_level = math.floor(100 * eu_supply / max_output)
|
||||
|
||||
meta:set_int("MV_EU_supply", eu_supply)
|
||||
|
||||
meta:set_string("infotext", S("@1 (@2% Efficiency)",
|
||||
S("Hydro @1 Generator", S("MV")), production_level))
|
||||
if production_level > 0 and
|
||||
minetest.get_node(pos).name == "technic:hydro_turbine" then
|
||||
technic.swap_node(pos, "technic:hydro_turbine_active")
|
||||
meta:set_int("MV_EU_supply", 0)
|
||||
return
|
||||
end
|
||||
if production_level == 0 then
|
||||
technic.swap_node(pos, "technic:hydro_turbine")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:hydro_turbine", {
|
||||
description = S("Hydro @1 Generator", S("MV")),
|
||||
tiles = {
|
||||
"technic_hydro_turbine_top.png",
|
||||
"technic_machine_bottom.png"..cable_entry,
|
||||
"technic_hydro_turbine_side.png",
|
||||
"technic_hydro_turbine_side.png",
|
||||
"technic_hydro_turbine_side.png",
|
||||
"technic_hydro_turbine_side.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_mv=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Hydro @1 Generator", S("MV")))
|
||||
meta:set_int("MV_EU_supply", 0)
|
||||
end,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:hydro_turbine_active", {
|
||||
description = S("Hydro @1 Generator", S("MV")),
|
||||
tiles = {"technic_hydro_turbine_top_active.png", "technic_machine_bottom.png",
|
||||
"technic_hydro_turbine_side.png", "technic_hydro_turbine_side.png",
|
||||
"technic_hydro_turbine_side.png", "technic_hydro_turbine_side.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, axey=2, handy=1,
|
||||
technic_machine=1, technic_mv=1, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
drop = "technic:hydro_turbine",
|
||||
technic_run = run,
|
||||
technic_disabled_machine_name = "technic:hydro_turbine",
|
||||
})
|
||||
|
||||
technic.register_machine("MV", "technic:hydro_turbine", technic.producer)
|
||||
technic.register_machine("MV", "technic:hydro_turbine_active", technic.producer)
|
28
mods/technic_plus_beta/technic/machines/MV/init.lua
Normal file
28
mods/technic_plus_beta/technic/machines/MV/init.lua
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
technic.register_tier("MV", "Medium Voltage")
|
||||
|
||||
local path = technic.modpath.."/machines/MV"
|
||||
|
||||
-- Wiring stuff
|
||||
dofile(path.."/cables.lua")
|
||||
dofile(path.."/battery_box.lua")
|
||||
|
||||
-- Generators
|
||||
if technic.config:get_bool("enable_wind_mill") then
|
||||
dofile(path.."/wind_mill.lua")
|
||||
end
|
||||
dofile(path.."/generator.lua")
|
||||
dofile(path.."/solar_array.lua")
|
||||
dofile(path.."/hydro_turbine.lua")
|
||||
|
||||
-- Machines
|
||||
dofile(path.."/alloy_furnace.lua")
|
||||
dofile(path.."/electric_furnace.lua")
|
||||
dofile(path.."/grinder.lua")
|
||||
dofile(path.."/extractor.lua")
|
||||
dofile(path.."/compressor.lua")
|
||||
dofile(path.."/centrifuge.lua")
|
||||
|
||||
dofile(path.."/tool_workshop.lua")
|
||||
|
||||
dofile(path.."/freezer.lua")
|
18
mods/technic_plus_beta/technic/machines/MV/solar_array.lua
Normal file
18
mods/technic_plus_beta/technic/machines/MV/solar_array.lua
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mv_solar_array 1',
|
||||
recipe = {
|
||||
{'technic:lv_solar_array', 'technic:lv_solar_array', 'technic:lv_solar_array'},
|
||||
{'technic:carbon_steel_ingot', 'technic:mv_transformer', 'technic:carbon_steel_ingot'},
|
||||
{'', 'technic:mv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_solar_array("technic:mv_solar_array", {
|
||||
tier="MV",
|
||||
power=30
|
||||
})
|
||||
|
||||
-- compatibility alias for upgrading from old versions of technic
|
||||
minetest.register_alias("technic:solar_panel_mv", "technic:mv_solar_array")
|
||||
minetest.register_alias("technic:solar_array_mv", "technic:mv_solar_array")
|
152
mods/technic_plus_beta/technic/machines/MV/tool_workshop.lua
Normal file
152
mods/technic_plus_beta/technic/machines/MV/tool_workshop.lua
Normal file
|
@ -0,0 +1,152 @@
|
|||
-- Tool workshop
|
||||
-- This machine repairs tools.
|
||||
|
||||
minetest.register_alias("tool_workshop", "technic:tool_workshop")
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local tube_entry = "^pipeworks_tube_connection_wooden.png"
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:tool_workshop',
|
||||
recipe = {
|
||||
{'group:wood', mat.diamond, 'group:wood'},
|
||||
{'mesecons_pistons:piston_sticky_off', 'technic:machine_casing', 'technic:carbon_cloth'},
|
||||
{mat.obsidian, 'technic:mv_cable', mat.obsidian},
|
||||
}
|
||||
})
|
||||
|
||||
local workshop_demand = {5000, 3500, 2000}
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,9;]" or "size[8,9;]"
|
||||
local workshop_formspec =
|
||||
size..
|
||||
"list[context;src;3,1;1,1;]"..
|
||||
"label[0,0;"..S("@1 Tool Workshop", S("MV")).."]"..
|
||||
"list[context;upgrade1;1,3;1,1;]"..
|
||||
"list[context;upgrade2;2,3;1,1;]"..
|
||||
"label[1,4;"..S("Upgrade Slots").."]"
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
workshop_formspec = workshop_formspec..
|
||||
mcl_formspec.get_itemslot_bg(3,1,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(1,3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(2,3,1,1)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)
|
||||
else
|
||||
workshop_formspec = workshop_formspec..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
end
|
||||
|
||||
-- listrings
|
||||
workshop_formspec = workshop_formspec..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;upgrade1]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;upgrade2]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local eu_input = meta:get_int("MV_EU_input")
|
||||
local machine_name = S("@1 Tool Workshop", S("MV"))
|
||||
|
||||
-- Setup meta data if it does not exist.
|
||||
if not eu_input then
|
||||
meta:set_int("MV_EU_demand", workshop_demand[1])
|
||||
meta:set_int("MV_EU_input", 0)
|
||||
return
|
||||
end
|
||||
|
||||
local EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
|
||||
|
||||
local repairable = false
|
||||
local srcstack = inv:get_stack("src", 1)
|
||||
if not srcstack:is_empty() then
|
||||
local itemdef = minetest.registered_items[srcstack:get_name()]
|
||||
if itemdef and
|
||||
(not itemdef.wear_represents or
|
||||
itemdef.wear_represents == "mechanical_wear") and
|
||||
srcstack:get_wear() ~= 0 then
|
||||
repairable = true
|
||||
end
|
||||
end
|
||||
technic.handle_machine_pipeworks(pos, tube_upgrade, function(pos2, x_velocity, z_velocity)
|
||||
if not repairable then
|
||||
technic.send_items(pos2, x_velocity, z_velocity, "src")
|
||||
end
|
||||
end)
|
||||
if not repairable then
|
||||
meta:set_string("infotext", S("@1 Idle", machine_name))
|
||||
meta:set_int("MV_EU_demand", 0)
|
||||
return
|
||||
end
|
||||
|
||||
if eu_input < workshop_demand[EU_upgrade+1] then
|
||||
meta:set_string("infotext", S("@1 Unpowered", machine_name))
|
||||
elseif eu_input >= workshop_demand[EU_upgrade+1] then
|
||||
meta:set_string("infotext", S("@1 Active", machine_name) .. "\n" ..
|
||||
S("Demand: @1", technic.EU_string(workshop_demand[EU_upgrade+1])))
|
||||
srcstack:add_wear(-1000)
|
||||
inv:set_stack("src", 1, srcstack)
|
||||
end
|
||||
meta:set_int("MV_EU_demand", workshop_demand[EU_upgrade+1])
|
||||
end
|
||||
|
||||
minetest.register_node("technic:tool_workshop", {
|
||||
description = S("@1 Tool Workshop", S("MV")),
|
||||
paramtype2 = "facedir",
|
||||
tiles = {
|
||||
"technic_workshop_top.png"..tube_entry,
|
||||
"technic_machine_bottom.png"..tube_entry,
|
||||
"technic_workshop_side.png"..tube_entry,
|
||||
"technic_workshop_side.png"..tube_entry,
|
||||
"technic_workshop_side.png"..tube_entry,
|
||||
"technic_workshop_side.png"
|
||||
},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_mv=1, tubedevice=1, tubedevice_receiver=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom", "back", "left", "right"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("@1 Tool Workshop", S("MV")))
|
||||
meta:set_string("formspec", workshop_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("upgrade1", 1)
|
||||
inv:set_size("upgrade2", 1)
|
||||
end,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
tube = {
|
||||
can_insert = function (pos, node, stack, direction)
|
||||
return minetest.get_meta(pos):get_inventory():room_for_item("src", stack)
|
||||
end,
|
||||
insert_object = function (pos, node, stack, direction)
|
||||
return minetest.get_meta(pos):get_inventory():add_item("src", stack)
|
||||
end,
|
||||
connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
|
||||
},
|
||||
technic_run = run,
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = technic.machine_after_dig_node
|
||||
})
|
||||
|
||||
technic.register_machine("MV", "technic:tool_workshop", technic.receiver)
|
||||
|
102
mods/technic_plus_beta/technic/machines/MV/wind_mill.lua
Normal file
102
mods/technic_plus_beta/technic/machines/MV/wind_mill.lua
Normal file
|
@ -0,0 +1,102 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:wind_mill_frame 5',
|
||||
recipe = {
|
||||
{'technic:carbon_steel_ingot', '', 'technic:carbon_steel_ingot'},
|
||||
{'', 'technic:carbon_steel_ingot', ''},
|
||||
{'technic:carbon_steel_ingot', '', 'technic:carbon_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:wind_mill',
|
||||
recipe = {
|
||||
{'', 'basic_materials:motor', ''},
|
||||
{'technic:carbon_steel_ingot', 'technic:carbon_steel_block', 'technic:carbon_steel_ingot'},
|
||||
{'', 'technic:mv_cable', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("technic:wind_mill_frame", {
|
||||
description = S("Wind Mill Frame"),
|
||||
drawtype = "glasslike_framed",
|
||||
tiles = {"technic_carbon_steel_block.png", "default_glass.png"},
|
||||
sunlight_propagates = true,
|
||||
groups = {cracky=3, pickaxey=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
paramtype = "light",
|
||||
})
|
||||
|
||||
local function check_wind_mill(pos)
|
||||
if pos.y < 30 then
|
||||
return false
|
||||
end
|
||||
pos = {x=pos.x, y=pos.y, z=pos.z}
|
||||
for i = 1, 20 do
|
||||
pos.y = pos.y - 1
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node then
|
||||
-- we reached CONTENT_IGNORE, we can assume, that nothing changed
|
||||
-- as the user will have to load the block to change it
|
||||
return
|
||||
end
|
||||
if node.name ~= "technic:wind_mill_frame" then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local machine_name = S("Wind @1 Generator", S("MV"))
|
||||
|
||||
local check = check_wind_mill(pos)
|
||||
if check == false then
|
||||
meta:set_int("MV_EU_supply", 0)
|
||||
meta:set_string("infotext", S("@1 Improperly Placed", machine_name))
|
||||
elseif check == true then
|
||||
local power = math.min(pos.y * 100, 5000)
|
||||
meta:set_int("MV_EU_supply", power)
|
||||
meta:set_string("infotext", S("@1 (@2)", machine_name,
|
||||
technic.EU_string(power)))
|
||||
end
|
||||
-- check == nil: assume nothing has changed
|
||||
end
|
||||
|
||||
minetest.register_node("technic:wind_mill", {
|
||||
description = S("Wind @1 Generator", S("MV")),
|
||||
tiles = {"technic_carbon_steel_block.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1, technic_machine=1, technic_mv=1, pickaxey=2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"top", "bottom", "back", "left", "right"},
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- Main box
|
||||
{-0.1, -0.1, -0.5, 0.1, 0.1, -0.6}, -- Shaft
|
||||
{-0.1, -1, -0.6, 0.1, 1, -0.7}, -- Vertical blades
|
||||
{-1, -0.1, -0.6, 1, 0.1, -0.7}, -- Horizontal blades
|
||||
}
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Wind @1 Generator", S("MV")))
|
||||
meta:set_int("MV_EU_supply", 0)
|
||||
end,
|
||||
technic_run = run,
|
||||
})
|
||||
|
||||
technic.register_machine("MV", "technic:wind_mill", technic.producer)
|
||||
|
87
mods/technic_plus_beta/technic/machines/compat/api.lua
Normal file
87
mods/technic_plus_beta/technic/machines/compat/api.lua
Normal file
|
@ -0,0 +1,87 @@
|
|||
local S = technic.getter
|
||||
|
||||
-- Registration compatibility shim to transform Technic 1.x arguments to 2.x
|
||||
-- This could be made stricter for new style API by utilizing `assert`
|
||||
|
||||
local function shallow_copy(t)
|
||||
local result = {}
|
||||
for k, v in pairs(t) do
|
||||
result[k] = v
|
||||
end
|
||||
return setmetatable(result, getmetatable(t))
|
||||
end
|
||||
|
||||
function technic.register_compat_v1_to_v2(name, data, default_name)
|
||||
local modname = minetest.get_current_modname()
|
||||
local colon, def
|
||||
if type(name) == "table" then
|
||||
-- Log old API usage, swap name to def and set name from def table
|
||||
local msg = "Deprecated Technic registration API call: %s (%s)"
|
||||
def = shallow_copy(name)
|
||||
name = def.machine_name or default_name
|
||||
def.machine_name = nil
|
||||
def.description = def.machine_desc
|
||||
def.machine_desc = nil
|
||||
minetest.log("warning", msg:format(tostring(name), tostring(modname)))
|
||||
else
|
||||
def = shallow_copy(data)
|
||||
end
|
||||
-- Input name can be "modname:nodename", ":modname:nodename" or "nodename".
|
||||
-- If name is presented as "nodename" then check for old def.modname field.
|
||||
if name:find(":") then
|
||||
colon, modname, name = name:match("(:?)(.+):(.+)")
|
||||
-- Make sure that all fields are set, can be empty but pattern matcher must succeed.
|
||||
assert(colon and modname and name)
|
||||
elseif def.modname then
|
||||
minetest.log("warning", ("Definition contains modname for %s"):format(name))
|
||||
colon = ":"
|
||||
modname = def.modname
|
||||
end
|
||||
return (colon or ""), modname, name, def
|
||||
end
|
||||
|
||||
-- Registration functions in Technic 1.x version
|
||||
|
||||
function technic.register_alloy_furnace(def)
|
||||
def.typename = "alloy"
|
||||
def.description = S("@1 Alloy Furnace", S(def.tier))
|
||||
def.insert_object = technic.insert_object_unique_stack
|
||||
def.can_insert = technic.can_insert_unique_stack
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_centrifuge(def)
|
||||
def.typename = "separating"
|
||||
def.description = S("@1 Centrifuge", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_compressor(def)
|
||||
def.typename = "compressing"
|
||||
def.description = S("@1 Compressor", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_extractor(def)
|
||||
def.typename = "extracting"
|
||||
def.description = S("@1 Extractor", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_freezer(def)
|
||||
def.typename = "freezing"
|
||||
def.description = S("@1 Freezer", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_grinder(def)
|
||||
def.typename = "grinding"
|
||||
def.description = S("@1 Grinder", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
||||
|
||||
function technic.register_electric_furnace(def)
|
||||
def.typename = "cooking"
|
||||
def.description = S("@1 Furnace", S(def.tier))
|
||||
technic.register_base_machine(def)
|
||||
end
|
109
mods/technic_plus_beta/technic/machines/compat/digtron.lua
Normal file
109
mods/technic_plus_beta/technic/machines/compat/digtron.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
--
|
||||
-- Compatibility hacks for digtron to work well with new Technic Plus network and power tools
|
||||
--
|
||||
-- More information:
|
||||
-- https://github.com/mt-mods/technic/issues/100
|
||||
-- https://github.com/mt-mods/technic/issues/233
|
||||
--
|
||||
-- Disable some luacheck warnings to allow having original formatting here
|
||||
-- luacheck: no max line length
|
||||
-- luacheck: globals digtron
|
||||
|
||||
-- Only relevant sections modified, you can directly compare this with upstream function defined in util.lua
|
||||
local node_inventory_table = {type="node"}
|
||||
local function tap_batteries(battery_positions, target, test)
|
||||
if (battery_positions == nil) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local current_burned = 0
|
||||
-- 1 coal block is 370 PU
|
||||
-- 1 coal lump is 40 PU
|
||||
-- An RE battery holds 10000 EU of charge
|
||||
-- local power_ratio = 100 -- How much charge equals 1 unit of PU from coal
|
||||
-- setting Moved to digtron.config.power_ratio
|
||||
|
||||
for k, location in pairs(battery_positions) do
|
||||
if current_burned > target then
|
||||
break
|
||||
end
|
||||
node_inventory_table.pos = location.pos
|
||||
local inv = minetest.get_inventory(node_inventory_table)
|
||||
local invlist = inv:get_list("batteries")
|
||||
|
||||
if (invlist == nil) then -- This check shouldn't be needed, it's yet another guard against https://github.com/minetest/minetest/issues/8067
|
||||
break
|
||||
end
|
||||
|
||||
for i, itemstack in pairs(invlist) do
|
||||
local charge = technic.get_charge(itemstack)
|
||||
local power_available = math.floor(charge / digtron.config.power_ratio)
|
||||
if power_available ~= 0 then
|
||||
local actual_burned = power_available -- we just take all we have from the battery, since they aren't stackable
|
||||
-- don't bother recording the items if we're just testing, nothing is actually being removed.
|
||||
if test ~= true then
|
||||
-- since we are taking everything, the wear and charge can both be set to 0
|
||||
technic.set_charge(itemstack, 0)
|
||||
end
|
||||
current_burned = current_burned + actual_burned
|
||||
end
|
||||
|
||||
if current_burned > target then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if test ~= true then
|
||||
-- only update the list if we're doing this for real.
|
||||
inv:set_list("batteries", invlist)
|
||||
end
|
||||
end
|
||||
return current_burned
|
||||
end
|
||||
|
||||
local function power_connector_compat()
|
||||
local digtron_technic_run = minetest.registered_nodes["digtron:power_connector"].technic_run
|
||||
minetest.override_item("digtron:power_connector",{
|
||||
technic_run = function(pos, node)
|
||||
local network_id = technic.pos2network(pos)
|
||||
local sw_pos = network_id and technic.network2sw_pos(network_id)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("HV_network", sw_pos and minetest.pos_to_string(sw_pos) or "")
|
||||
return digtron_technic_run(pos, node)
|
||||
end,
|
||||
technic_on_disable = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("HV_network", "")
|
||||
meta:set_string("HV_EU_input", "")
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
local function battery_holder_compat()
|
||||
-- Override battery holder
|
||||
local tube = minetest.registered_nodes["digtron:battery_holder"].tube
|
||||
tube.can_insert = function(pos, node, stack, direction)
|
||||
if technic.get_charge(stack) > 0 then
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
return inv:room_for_item("batteries", stack)
|
||||
end
|
||||
return false
|
||||
end
|
||||
minetest.override_item("digtron:battery_holder",{
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
return (listname == "batteries" and technic.get_charge(stack) > 0) and stack:get_count() or 0
|
||||
end,
|
||||
tube = tube,
|
||||
})
|
||||
-- Override digtron.tap_batteries
|
||||
digtron.tap_batteries = tap_batteries
|
||||
end
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
if minetest.registered_nodes["digtron:power_connector"] then
|
||||
power_connector_compat()
|
||||
end
|
||||
if minetest.registered_nodes["digtron:battery_holder"] then
|
||||
battery_holder_compat()
|
||||
end
|
||||
end)
|
139
mods/technic_plus_beta/technic/machines/compat/tools.lua
Normal file
139
mods/technic_plus_beta/technic/machines/compat/tools.lua
Normal file
|
@ -0,0 +1,139 @@
|
|||
--
|
||||
-- This allows using old style technic.register_power_tool tool registration function.
|
||||
--
|
||||
-- To make tool fully compatible replace `minetest.register_tool` with `technic.register_power_tool`
|
||||
-- and add `technic_max_charge` field for tool definition.
|
||||
-- Fields `wear_represents` and `on_refill` can be removed if using defaults.
|
||||
--
|
||||
-- Does not offer compatibility for charger mods: mods that charge or discharge registered power tools.
|
||||
-- Compatibility for those can be achieved by using `<tooldef>.technic_get_charge` / `<tooldef>.technic_set_charge`.
|
||||
--
|
||||
|
||||
local function compat_set_RE_wear(stack, charge)
|
||||
local def = stack:get_definition()
|
||||
if def.technic_wear_factor then
|
||||
local wear = math.floor(charge * def.technic_wear_factor + 0.5)
|
||||
stack:set_wear(wear > 0 and 65536 - wear or 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function compat_technic_get_charge(stack)
|
||||
local def = stack:get_definition()
|
||||
if def.technic_max_charge then
|
||||
local legacy_fields = minetest.deserialize(stack:get_meta():get_string("")) or {}
|
||||
return legacy_fields.charge or 0, def.technic_max_charge
|
||||
end
|
||||
return 0, 0
|
||||
end
|
||||
|
||||
local function compat_technic_set_charge(stack, charge)
|
||||
compat_set_RE_wear(stack, charge)
|
||||
local meta = stack:get_meta()
|
||||
local legacy_fields = minetest.deserialize(meta:get_string("")) or {}
|
||||
legacy_fields.charge = charge
|
||||
meta:set_string("", minetest.serialize(legacy_fields))
|
||||
end
|
||||
|
||||
-- This attempts to find out if mod is aware of technic.plus version property and marks mod as `plus_aware` if
|
||||
-- it tries to read `technic.plus` value. Marked tools wont receive automatic metadata compatibility functions.
|
||||
local plus_aware = {}
|
||||
do
|
||||
local original_mt = getmetatable(technic)
|
||||
local mt = original_mt and table.copy(original_mt) or {}
|
||||
local mt_index = mt.__index or rawget
|
||||
local plus = technic.plus
|
||||
rawset(technic, "plus", nil)
|
||||
|
||||
-- Extend `__index` lookup function for `technic` to collect mod names that are reading `technic.plus` property
|
||||
function mt:__index(key)
|
||||
if key == "plus" then
|
||||
local modname = minetest.get_current_modname()
|
||||
if modname then
|
||||
plus_aware[modname] = true
|
||||
end
|
||||
return plus
|
||||
end
|
||||
return mt_index(self, key)
|
||||
end
|
||||
setmetatable(technic, mt)
|
||||
|
||||
-- Restore version and metatable, this must happen after handling register_on_mods_loaded callbacks
|
||||
minetest.after(0, function()
|
||||
rawset(technic, "plus", plus)
|
||||
setmetatable(technic, original_mt)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Override `technic.register_power_tool` to handle old style registration that was only setting max charge value.
|
||||
local register_power_tool = technic.register_power_tool
|
||||
function technic.register_power_tool(itemname, def_or_max_charge)
|
||||
if type(def_or_max_charge) == "number" then
|
||||
minetest.log("warning", "Deprecated technic.register_power_tool use. Setting max_charge for "..itemname)
|
||||
technic.power_tools[itemname] = def_or_max_charge
|
||||
minetest.register_on_mods_loaded(function()
|
||||
minetest.log("warning", "Deprecated technic.register_power_tool use. Ensuring fields for "..itemname)
|
||||
local redef = minetest.registered_items[itemname]
|
||||
if redef and redef.wear_represents == "technic_RE_charge" then
|
||||
-- Override power tools that called register_power_tool but do not have on_refill function defined
|
||||
local overrides = {
|
||||
technic_max_charge = def_or_max_charge,
|
||||
technic_wear_factor = 65535 / def_or_max_charge,
|
||||
on_refill = function(stack)
|
||||
local tooldef = stack:get_definition()
|
||||
tooldef.technic_set_charge(stack, def_or_max_charge)
|
||||
return stack
|
||||
end,
|
||||
}
|
||||
-- Add legacy meta handlers if mod did not attempt to read technic.plus value
|
||||
local modname = itemname:match(":?(.+):")
|
||||
if plus_aware[modname] then
|
||||
overrides.technic_get_charge = redef.technic_get_charge or technic.get_charge
|
||||
overrides.technic_set_charge = redef.technic_set_charge or technic.set_charge
|
||||
minetest.log("warning", "Mod "..modname.." seems to be aware of technic.plus but "..
|
||||
itemname.." is still using deprecated registration, skipping meta charge compatibility.")
|
||||
elseif not redef.technic_get_charge and not redef.technic_set_charge then
|
||||
overrides.technic_get_charge = compat_technic_get_charge
|
||||
overrides.technic_set_charge = compat_technic_set_charge
|
||||
minetest.log("warning", "Using metadata charge values for "..itemname)
|
||||
end
|
||||
-- Override tool definition with added / new values
|
||||
minetest.override_item(itemname, overrides)
|
||||
minetest.log("warning", "Updated legacy Technic power tool definition for "..itemname)
|
||||
else
|
||||
minetest.log("error", "Technic compatibility overrides skipped for "..itemname..", charging might "..
|
||||
'cause crash. Upgrading to technic.register_power_tool("'..itemname..'", {itemdef}) recommended.')
|
||||
end
|
||||
end)
|
||||
else
|
||||
return register_power_tool(itemname, def_or_max_charge)
|
||||
end
|
||||
end
|
||||
|
||||
technic.set_RE_charge = assert(technic.set_charge)
|
||||
technic.get_RE_charge = assert(technic.get_charge)
|
||||
technic.use_RE_charge = assert(technic.use_charge)
|
||||
|
||||
-- Same as `technic.set_charge` but without calling through `itemdef.technic_set_charge`.
|
||||
function technic.set_RE_wear(stack, charge)
|
||||
minetest.log("warning", "Use of deprecated function technic.set_RE_wear with stack: "..stack:get_name())
|
||||
compat_set_RE_wear(stack, charge)
|
||||
end
|
||||
|
||||
-- Old utility function to recharge tools
|
||||
local function charge_tools(meta, batt_charge, charge_step)
|
||||
local src_stack = meta:get_inventory():get_stack("src", 1)
|
||||
local def = src_stack:get_definition()
|
||||
if not def or not def.technic_max_charge or src_stack:is_empty() then
|
||||
return batt_charge, false
|
||||
end
|
||||
local new_charge = math.min(def.technic_max_charge, def.technic_get_charge(src_stack) + charge_step)
|
||||
def.technic_set_charge(src_stack, new_charge)
|
||||
meta:get_inventory():set_stack("src", 1, src_stack)
|
||||
return batt_charge, (def.technic_max_charge == new_charge)
|
||||
end
|
||||
|
||||
function technic.charge_tools(...)
|
||||
minetest.log("warning", "Use of deprecated function technic.charge_tools")
|
||||
technic.charge_tools = charge_tools
|
||||
return charge_tools(...)
|
||||
end
|
80
mods/technic_plus_beta/technic/machines/init.lua
Normal file
80
mods/technic_plus_beta/technic/machines/init.lua
Normal file
|
@ -0,0 +1,80 @@
|
|||
local path = technic.modpath.."/machines"
|
||||
|
||||
technic.digilines = {
|
||||
rules = {
|
||||
-- digilines.rules.default
|
||||
{x= 1,y= 0,z= 0},{x=-1,y= 0,z= 0}, -- along x beside
|
||||
{x= 0,y= 0,z= 1},{x= 0,y= 0,z=-1}, -- along z beside
|
||||
{x= 1,y= 1,z= 0},{x=-1,y= 1,z= 0}, -- 1 node above along x diagonal
|
||||
{x= 0,y= 1,z= 1},{x= 0,y= 1,z=-1}, -- 1 node above along z diagonal
|
||||
{x= 1,y=-1,z= 0},{x=-1,y=-1,z= 0}, -- 1 node below along x diagonal
|
||||
{x= 0,y=-1,z= 1},{x= 0,y=-1,z=-1}, -- 1 node below along z diagonal
|
||||
-- added rules for digi cable
|
||||
{x = 0, y = -1, z = 0}, -- along y below
|
||||
},
|
||||
rules_allfaces = {
|
||||
{x= 1, y= 0, z= 0}, {x=-1, y= 0, z= 0}, -- along x beside
|
||||
{x= 0, y= 1, z= 0}, {x= 0, y=-1, z= 0}, -- along y above and below
|
||||
{x= 0, y= 0, z= 1}, {x= 0, y= 0, z=-1}, -- along z beside
|
||||
}
|
||||
}
|
||||
|
||||
-- Compatibility shim to allow old API usage
|
||||
dofile(path.."/compat/api.lua")
|
||||
|
||||
-- https://github.com/mt-mods/technic/issues/100
|
||||
dofile(path.."/compat/digtron.lua")
|
||||
|
||||
dofile(path.."/network.lua")
|
||||
|
||||
dofile(path.."/overload.lua")
|
||||
|
||||
dofile(path.."/register/init.lua")
|
||||
|
||||
-- Tiers
|
||||
dofile(path.."/LV/init.lua")
|
||||
dofile(path.."/MV/init.lua")
|
||||
dofile(path.."/HV/init.lua")
|
||||
|
||||
dofile(path.."/switching_station.lua")
|
||||
dofile(path.."/switching_station_globalstep.lua")
|
||||
|
||||
dofile(path.."/power_monitor.lua")
|
||||
dofile(path.."/supply_converter.lua")
|
||||
|
||||
dofile(path.."/other/init.lua")
|
||||
|
||||
|
||||
-- Metadata cleanup LBM, removes old metadata values from nodes
|
||||
minetest.register_lbm({
|
||||
name = "technic:metadata_cleanup",
|
||||
nodenames = {
|
||||
"group:technic_machine",
|
||||
"group:technic_all_tiers",
|
||||
"technic:switching_station",
|
||||
"technic:power_monitor",
|
||||
},
|
||||
action = function(pos, node)
|
||||
-- Delete all listed metadata key/value pairs from technic machines
|
||||
local keys = {
|
||||
"LV_EU_timeout", "MV_EU_timeout", "HV_EU_timeout",
|
||||
"LV_network", "MV_network", "HV_network",
|
||||
"active_pos", "supply", "demand",
|
||||
"battery_count", "battery_charge", "battery_charge_max",
|
||||
}
|
||||
local meta = minetest.get_meta(pos)
|
||||
for _,key in ipairs(keys) do
|
||||
-- Value of `""` will delete the key.
|
||||
meta:set_string(key, "")
|
||||
end
|
||||
if node.name == "technic:switching_station" then
|
||||
meta:set_string("active", "")
|
||||
|
||||
-- start nodetimer if not already started
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
if not timer:is_started() then
|
||||
timer:start(1.0)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
767
mods/technic_plus_beta/technic/machines/network.lua
Normal file
767
mods/technic_plus_beta/technic/machines/network.lua
Normal file
|
@ -0,0 +1,767 @@
|
|||
--
|
||||
-- Power network specific functions and data should live here
|
||||
--
|
||||
local S = technic.getter
|
||||
|
||||
local off_delay_seconds = tonumber(technic.config:get("switch_off_delay_seconds"))
|
||||
|
||||
local network_node_arrays = {"PR_nodes","BA_nodes","RE_nodes"}
|
||||
|
||||
technic.active_networks = {}
|
||||
local networks = {}
|
||||
technic.networks = networks
|
||||
local technic_cables = {}
|
||||
technic.cables = technic_cables
|
||||
|
||||
local poshash = minetest.hash_node_position
|
||||
local hashpos = minetest.get_position_from_hash
|
||||
|
||||
function technic.create_network(sw_pos)
|
||||
local network_id = poshash({x=sw_pos.x,y=sw_pos.y-1,z=sw_pos.z})
|
||||
technic.build_network(network_id)
|
||||
return network_id
|
||||
end
|
||||
|
||||
local function pos_in_array(pos, array)
|
||||
for _,pos2 in ipairs(array) do
|
||||
if pos.x == pos2.x and pos.y == pos2.y and pos.z == pos2.z then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function technic.merge_networks(net1, net2)
|
||||
-- TODO: Optimize for merging small network into larger by first checking network
|
||||
-- node counts for both networks and keep network id with most nodes.
|
||||
assert(type(net1) == "table", "Invalid net1 for technic.merge_networks")
|
||||
assert(type(net2) == "table", "Invalid net2 for technic.merge_networks")
|
||||
assert(net1 ~= net2, "Deadlock recipe: net1 & net2 equals for technic.merge_networks")
|
||||
-- Move data in cables table
|
||||
for node_id,cable_net_id in pairs(technic_cables) do
|
||||
if cable_net_id == net2.id then
|
||||
technic_cables[node_id] = net1.id
|
||||
end
|
||||
end
|
||||
-- Move data in machine tables
|
||||
for _,tablename in ipairs(network_node_arrays) do
|
||||
for _,pos in ipairs(net2[tablename]) do
|
||||
table.insert(net1[tablename], pos)
|
||||
end
|
||||
end
|
||||
-- Move data in all_nodes table
|
||||
for node_id,pos in pairs(net2.all_nodes) do
|
||||
net1.all_nodes[node_id] = pos
|
||||
end
|
||||
-- Merge queues for incomplete networks
|
||||
if net1.queue and net2.queue then
|
||||
for _,pos in ipairs(net2.queue) do
|
||||
if not pos_in_array(pos, net1.queue) then
|
||||
table.insert(net1.queue, pos)
|
||||
end
|
||||
end
|
||||
else
|
||||
net1.queue = net1.queue or net2.queue
|
||||
end
|
||||
-- Remove links to net2
|
||||
networks[net2.id] = nil
|
||||
technic.active_networks[net2.id] = nil
|
||||
end
|
||||
|
||||
function technic.activate_network(network_id, timeout)
|
||||
-- timeout is optional ttl for network in seconds, if not specified use default
|
||||
local network = networks[network_id]
|
||||
if network then
|
||||
-- timeout is absolute time in microseconds
|
||||
network.timeout = minetest.get_us_time() + ((timeout or off_delay_seconds) * 1000 * 1000)
|
||||
technic.active_networks[network_id] = network
|
||||
end
|
||||
end
|
||||
|
||||
function technic.sw_pos2tier(pos, load_node)
|
||||
-- Get cable tier for switching station or nil if no cable
|
||||
-- load_node true to use minetest.load_area to load node
|
||||
local cable_pos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||
if load_node then
|
||||
minetest.load_area(cable_pos)
|
||||
end
|
||||
return technic.get_cable_tier(minetest.get_node(cable_pos).name)
|
||||
end
|
||||
|
||||
-- Destroy network data
|
||||
function technic.remove_network(network_id)
|
||||
for pos_hash,cable_net_id in pairs(technic_cables) do
|
||||
if cable_net_id == network_id then
|
||||
technic_cables[pos_hash] = nil
|
||||
end
|
||||
end
|
||||
networks[network_id] = nil
|
||||
technic.active_networks[network_id] = nil
|
||||
end
|
||||
|
||||
local function switch_index(pos, net)
|
||||
for index, spos in ipairs(net.swpos) do
|
||||
if pos.x == spos.x and pos.y == spos.y and pos.z == spos.z then
|
||||
return index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function technic.switch_insert(pos, net)
|
||||
if not switch_index(pos, net) then
|
||||
table.insert(net.swpos, table.copy(pos))
|
||||
end
|
||||
return #net.swpos
|
||||
end
|
||||
|
||||
function technic.switch_remove(pos, net)
|
||||
local swindex = switch_index(pos, net)
|
||||
if swindex then
|
||||
table.remove(net.swpos, swindex)
|
||||
end
|
||||
return #net.swpos
|
||||
end
|
||||
|
||||
function technic.sw_pos2network(pos)
|
||||
return technic_cables[poshash({x=pos.x,y=pos.y-1,z=pos.z})]
|
||||
end
|
||||
|
||||
function technic.pos2network(pos)
|
||||
return technic_cables[poshash(pos)]
|
||||
end
|
||||
|
||||
function technic.network2pos(network_id)
|
||||
return hashpos(network_id)
|
||||
end
|
||||
|
||||
function technic.network2sw_pos(network_id)
|
||||
-- Return switching station position for network.
|
||||
-- It is not guaranteed that position actually contains switching station.
|
||||
local sw_pos = hashpos(network_id)
|
||||
sw_pos.y = sw_pos.y + 1
|
||||
return sw_pos
|
||||
end
|
||||
|
||||
function technic.network_infotext(network_id, text)
|
||||
local network = networks[network_id]
|
||||
if network then
|
||||
if text then
|
||||
network.infotext = text
|
||||
elseif network.queue then
|
||||
local count = 0
|
||||
for _ in pairs(network.all_nodes) do count = count + 1 end
|
||||
return S("Building Network: @1 Nodes", count)
|
||||
else
|
||||
return network.infotext
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local node_timeout = {}
|
||||
local default_timeout = 2
|
||||
|
||||
function technic.set_default_timeout(timeout)
|
||||
default_timeout = timeout or 2
|
||||
end
|
||||
|
||||
function technic.get_timeout(tier, pos)
|
||||
if node_timeout[tier] == nil then
|
||||
-- it is normal that some multi tier nodes always drop here when checking all LV, MV and HV tiers
|
||||
return 0
|
||||
end
|
||||
return node_timeout[tier][poshash(pos)] or 0
|
||||
end
|
||||
|
||||
local function touch_node(tier, pos, timeout)
|
||||
if node_timeout[tier] == nil then
|
||||
-- this should get built up during registration
|
||||
node_timeout[tier] = {}
|
||||
end
|
||||
node_timeout[tier][poshash(pos)] = timeout or default_timeout
|
||||
end
|
||||
technic.touch_node = touch_node
|
||||
|
||||
function technic.disable_machine(pos, node)
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
if nodedef then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("@1 Has No Network", nodedef.description))
|
||||
end
|
||||
if nodedef and nodedef.technic_disabled_machine_name then
|
||||
node.name = nodedef.technic_disabled_machine_name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if nodedef and nodedef.technic_on_disable then
|
||||
nodedef.technic_on_disable(pos, node)
|
||||
end
|
||||
local node_id = poshash(pos)
|
||||
for _,nodes in pairs(node_timeout) do
|
||||
nodes[node_id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function match_cable_tier_filter(name, tiers)
|
||||
-- Helper to check for set of cable tiers
|
||||
if tiers then
|
||||
for _, tier in ipairs(tiers) do if technic.is_tier_cable(name, tier) then return true end end
|
||||
return false
|
||||
end
|
||||
return technic.get_cable_tier(name) ~= nil
|
||||
end
|
||||
|
||||
local function get_neighbors(pos, tiers)
|
||||
local tier_machines = tiers and technic.machines[tiers[1]]
|
||||
local is_cable = match_cable_tier_filter(minetest.get_node(pos).name, tiers)
|
||||
local network = is_cable and technic.networks[technic.pos2network(pos)]
|
||||
local cables = {}
|
||||
local machines = {}
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y+1, z=pos.z},
|
||||
{x=pos.x, y=pos.y-1, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1},
|
||||
}
|
||||
for _,connected_pos in ipairs(positions) do
|
||||
local name = minetest.get_node(connected_pos).name
|
||||
if tier_machines and tier_machines[name] then
|
||||
table.insert(machines, connected_pos)
|
||||
elseif match_cable_tier_filter(name, tiers) then
|
||||
local cable_network = technic.networks[technic.pos2network(connected_pos)]
|
||||
table.insert(cables,{
|
||||
pos = connected_pos,
|
||||
network = cable_network,
|
||||
})
|
||||
if not network then network = cable_network end
|
||||
end
|
||||
end
|
||||
return network, cables, machines
|
||||
end
|
||||
|
||||
function technic.place_network_node(pos, tiers, name)
|
||||
-- Get connections and primary network if there's any
|
||||
local network, cables, machines = get_neighbors(pos, tiers)
|
||||
if not network then
|
||||
-- We're evidently not on a network, nothing to add ourselves to
|
||||
return
|
||||
end
|
||||
|
||||
-- Attach to primary network, this must be done before building branches from this position
|
||||
technic.add_network_node(pos, network)
|
||||
if not match_cable_tier_filter(name, tiers) then
|
||||
if technic.machines[tiers[1]][name] == technic.producer_receiver then
|
||||
-- FIXME: Multi tier machine like supply converter should also attach to other networks around pos.
|
||||
-- Preferably also with connection rules defined for machine.
|
||||
-- nodedef.connect_sides could be used to generate these rules.
|
||||
-- For now, assume that all multi network machines belong to technic.producer_receiver group:
|
||||
-- Get cables and networks around PR_RE machine
|
||||
local _, machine_cables, _ = get_neighbors(pos)
|
||||
for _,connection in ipairs(machine_cables) do
|
||||
if connection.network and connection.network.id ~= network.id then
|
||||
-- Attach PR_RE machine to secondary networks (last added is primary until above note is resolved)
|
||||
technic.add_network_node(pos, connection.network)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Check connected cables for foreign networks, overload if machine was connected to multiple networks
|
||||
for _, connection in ipairs(cables) do
|
||||
if connection.network and connection.network.id ~= network.id then
|
||||
technic.overload_network(connection.network.id)
|
||||
technic.overload_network(network.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Machine added, skip all network building
|
||||
return
|
||||
end
|
||||
|
||||
-- Attach neighbor machines if cable was added
|
||||
for _,machine_pos in ipairs(machines) do
|
||||
technic.add_network_node(machine_pos, network)
|
||||
end
|
||||
|
||||
-- Attach neighbor cables
|
||||
for _,connection in ipairs(cables) do
|
||||
if connection.network then
|
||||
if connection.network.id ~= network.id then
|
||||
-- Remove network if position belongs to another network
|
||||
-- FIXME: Network requires partial rebuild but avoid doing it here if possible.
|
||||
-- This might cause problems when merging two active networks into one
|
||||
technic.remove_network(network.id)
|
||||
technic.remove_network(connection.network.id)
|
||||
connection.network = nil
|
||||
end
|
||||
else
|
||||
-- There's cable that does not belong to any network, attach whole branch
|
||||
technic.add_network_node(connection.pos, network)
|
||||
technic.add_network_branch({connection.pos}, network)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove machine or cable from network
|
||||
local function remove_network_node(network_id, pos)
|
||||
local network = networks[network_id]
|
||||
if not network then return end
|
||||
-- Clear hash tables, cannot use table.remove
|
||||
local node_id = poshash(pos)
|
||||
technic_cables[node_id] = nil
|
||||
network.all_nodes[node_id] = nil
|
||||
-- TODO: All following things can be skipped if node is not machine
|
||||
-- check here if it is or is not cable
|
||||
-- or add separate function to remove cables and move responsibility to caller
|
||||
-- Clear indexed arrays, do NOT leave holes
|
||||
local machine_removed = false
|
||||
for _,tblname in ipairs(network_node_arrays) do
|
||||
local tbl = network[tblname]
|
||||
for i=#tbl,1,-1 do
|
||||
local mpos = tbl[i]
|
||||
if mpos.x == pos.x and mpos.y == pos.y and mpos.z == pos.z then
|
||||
table.remove(tbl, i)
|
||||
machine_removed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if machine_removed then
|
||||
-- Machine can still be in world, just not connected to any network. If so then disable it.
|
||||
local node = minetest.get_node(pos)
|
||||
technic.disable_machine(pos, node)
|
||||
end
|
||||
end
|
||||
|
||||
function technic.remove_network_node(pos, tiers, name)
|
||||
-- Get the network and neighbors
|
||||
local network, cables, machines = get_neighbors(pos, tiers)
|
||||
if not network then return end
|
||||
|
||||
if not match_cable_tier_filter(name, tiers) then
|
||||
-- Machine removed, skip cable checks to prevent unnecessary network cleanups
|
||||
for _,connection in ipairs(cables) do
|
||||
if connection.network then
|
||||
-- Remove machine from all networks around it
|
||||
remove_network_node(connection.network.id, pos)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if #cables == 1 then
|
||||
-- Dead end cable removed, remove it from the network
|
||||
remove_network_node(network.id, pos)
|
||||
-- Remove neighbor machines from network if cable was removed
|
||||
if match_cable_tier_filter(name, tiers) then
|
||||
for _,machine_pos in ipairs(machines) do
|
||||
local net, _, _ = get_neighbors(machine_pos, tiers)
|
||||
if not net then
|
||||
-- Remove machine from network if it does not have other connected cables
|
||||
remove_network_node(network.id, machine_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- TODO: Check branches around and switching stations for branches:
|
||||
-- remove branches that do not have switching station. Switching stations not tracked but could be easily tracked.
|
||||
-- remove branches not connected to another branch. Individual branches not tracked, requires simple AI heuristics.
|
||||
-- move branches that have switching station to new networks without checking or loading actual nodes in world.
|
||||
-- To do all this network must be aware of individual branches and switching stations, might not be worth it...
|
||||
-- For now remove whole network and let ABM rebuild it
|
||||
technic.remove_network(network.id)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Functions to traverse the electrical network
|
||||
--
|
||||
|
||||
-- Add a machine node to the LV/MV/HV network
|
||||
local function add_network_machine(nodes, pos, network_id, all_nodes, multitier)
|
||||
local node_id = poshash(pos)
|
||||
local net_id_old = technic_cables[node_id]
|
||||
if net_id_old == nil or (multitier and net_id_old ~= network_id and all_nodes[node_id] == nil) then
|
||||
-- Add machine to network only if it is not already added
|
||||
table.insert(nodes, pos)
|
||||
-- FIXME: Machines connecting to multiple networks should have way to store multiple network ids
|
||||
technic_cables[node_id] = network_id
|
||||
all_nodes[node_id] = pos
|
||||
return true
|
||||
elseif not multitier and net_id_old ~= network_id then
|
||||
-- Do not allow running from multiple networks, trigger overload
|
||||
technic.overload_network(network_id)
|
||||
technic.overload_network(net_id_old)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext",S("Network Overloaded"))
|
||||
end
|
||||
end
|
||||
|
||||
-- Add a wire node to the LV/MV/HV network
|
||||
local function add_cable_node(pos, network)
|
||||
local node_id = poshash(pos)
|
||||
if not technic_cables[node_id] then
|
||||
technic_cables[node_id] = network.id
|
||||
network.all_nodes[node_id] = pos
|
||||
if network.queue then
|
||||
table.insert(network.queue, pos)
|
||||
end
|
||||
elseif technic_cables[node_id] ~= network.id then
|
||||
-- Conflicting network connected, merge networks if both are still in building stage
|
||||
local net2 = networks[technic_cables[node_id]]
|
||||
if net2 and net2.queue then
|
||||
technic.merge_networks(network, net2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generic function to add found connected nodes to the right classification array
|
||||
local function add_network_node(network, pos, machines)
|
||||
local name = technic.get_or_load_node(pos).name
|
||||
|
||||
if technic.get_cable_tier(name) == network.tier then
|
||||
add_cable_node(pos, network)
|
||||
elseif machines[name] then
|
||||
if machines[name] == technic.producer then
|
||||
add_network_machine(network.PR_nodes, pos, network.id, network.all_nodes)
|
||||
elseif machines[name] == technic.receiver then
|
||||
add_network_machine(network.RE_nodes, pos, network.id, network.all_nodes)
|
||||
elseif machines[name] == technic.producer_receiver then
|
||||
if add_network_machine(network.PR_nodes, pos, network.id, network.all_nodes, true) then
|
||||
table.insert(network.RE_nodes, pos)
|
||||
end
|
||||
elseif machines[name] == technic.battery then
|
||||
add_network_machine(network.BA_nodes, pos, network.id, network.all_nodes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generic function to add single nodes to the right classification array of existing network
|
||||
function technic.add_network_node(pos, network)
|
||||
add_network_node(network, pos, technic.machines[network.tier])
|
||||
end
|
||||
|
||||
-- Traverse a network given a list of machines and a cable type name
|
||||
local function traverse_network(network, pos, machines)
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y+1, z=pos.z},
|
||||
{x=pos.x, y=pos.y-1, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1}}
|
||||
for i, cur_pos in pairs(positions) do
|
||||
if not network.all_nodes[poshash(cur_pos)] then
|
||||
add_network_node(network, cur_pos, machines)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function touch_nodes(list, tier)
|
||||
for _, pos in ipairs(list) do
|
||||
touch_node(tier, pos) -- Touch node
|
||||
end
|
||||
end
|
||||
|
||||
local function get_network(network_id, tier)
|
||||
local cached = networks[network_id]
|
||||
if cached and not cached.queue and cached.tier == tier then
|
||||
touch_nodes(cached.PR_nodes, tier)
|
||||
touch_nodes(cached.BA_nodes, tier)
|
||||
touch_nodes(cached.RE_nodes, tier)
|
||||
return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes
|
||||
end
|
||||
return technic.build_network(network_id)
|
||||
end
|
||||
|
||||
function technic.add_network_branch(queue, network)
|
||||
-- Adds whole branch to network, queue positions can be used to bypass sub branches
|
||||
local machines = technic.machines[network.tier]
|
||||
--print(string.format("technic.add_network_branch(%s, %s, %.17g)",queue,minetest.pos_to_string(sw_pos),network.id))
|
||||
local t1 = minetest.get_us_time()
|
||||
while next(queue) do
|
||||
local to_visit = {}
|
||||
for _, pos in ipairs(queue) do
|
||||
network.queue = to_visit
|
||||
traverse_network(network, pos, machines)
|
||||
end
|
||||
queue = to_visit
|
||||
if minetest.get_us_time() - t1 > 10000 then
|
||||
-- time limit exceeded
|
||||
break
|
||||
end
|
||||
end
|
||||
-- Set build queue for network if network build was not finished within time limits
|
||||
network.queue = #queue > 0 and queue
|
||||
end
|
||||
|
||||
-- Battery charge status updates for network
|
||||
local function update_battery(self, charge, max_charge, supply, demand)
|
||||
self.battery_charge = self.battery_charge + charge
|
||||
self.battery_charge_max = self.battery_charge_max + max_charge
|
||||
self.battery_supply = self.battery_supply + supply
|
||||
self.battery_demand = self.battery_demand + demand
|
||||
if demand ~= 0 then
|
||||
self.BA_count_active = self.BA_count_active + 1
|
||||
self.BA_charge_active = self.BA_charge_active + charge
|
||||
end
|
||||
end
|
||||
|
||||
-- Moving average function generator
|
||||
local function sma(period)
|
||||
local values = {}
|
||||
local index = 1
|
||||
local sum = 0
|
||||
return function(n)
|
||||
-- Add new value and return average
|
||||
sum = sum - (values[index] or 0) + n
|
||||
values[index] = n
|
||||
index = index ~= period and index + 1 or 1
|
||||
return sum / #values
|
||||
end
|
||||
end
|
||||
|
||||
function technic.build_network(network_id)
|
||||
local network = networks[network_id]
|
||||
if network and not network.queue then
|
||||
-- Network exists complete and cached
|
||||
return network.PR_nodes, network.BA_nodes, network.RE_nodes
|
||||
elseif not network then
|
||||
-- Build new network if network does not exist
|
||||
technic.remove_network(network_id)
|
||||
local sw_pos = technic.network2sw_pos(network_id)
|
||||
local tier = sw_pos and technic.sw_pos2tier(sw_pos)
|
||||
if not tier then
|
||||
-- Failed to get initial cable node for network
|
||||
return
|
||||
end
|
||||
network = {
|
||||
-- Build queue
|
||||
queue = {},
|
||||
-- Basic network data and lookup table for attached nodes
|
||||
id = network_id, tier = tier, all_nodes = {}, swpos = {},
|
||||
-- Indexed arrays for iteration by machine type
|
||||
PR_nodes = {}, RE_nodes = {}, BA_nodes = {},
|
||||
-- Power generation, usage and capacity related variables
|
||||
supply = 0, demand = 0, battery_charge = 0, battery_charge_max = 0,
|
||||
BA_count_active = 0, BA_charge_active = 0, battery_supply = 0, battery_demand = 0,
|
||||
-- Battery status update function
|
||||
update_battery = update_battery,
|
||||
-- Network activation and excution control
|
||||
timeout = 0, skip = 0, lag = 0, average_lag = sma(5)
|
||||
}
|
||||
-- Add first cable (one that is holding network id) and build network
|
||||
add_cable_node(technic.network2pos(network_id), network)
|
||||
end
|
||||
-- Continue building incomplete network
|
||||
technic.add_network_branch(network.queue, network)
|
||||
network.battery_count = #network.BA_nodes
|
||||
-- Add newly built network to cache array
|
||||
networks[network_id] = network
|
||||
if not network.queue then
|
||||
-- And return producers, batteries and receivers (should this simply return network?)
|
||||
return network.PR_nodes, network.BA_nodes, network.RE_nodes
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Execute technic power network
|
||||
--
|
||||
local node_technic_run = {}
|
||||
minetest.register_on_mods_loaded(function()
|
||||
for name, tiers in pairs(technic.machine_tiers) do
|
||||
local nodedef = minetest.registered_nodes[name]
|
||||
local on_construct = type(nodedef.on_construct) == "function" and nodedef.on_construct
|
||||
local on_destruct = type(nodedef.on_destruct) == "function" and nodedef.on_destruct
|
||||
local place_node = technic.place_network_node
|
||||
local remove_node = technic.remove_network_node
|
||||
minetest.override_item(name, {
|
||||
on_construct = on_construct
|
||||
and function(pos) on_construct(pos) place_node(pos, tiers, name) end
|
||||
or function(pos) place_node(pos, tiers, name) end,
|
||||
on_destruct = on_destruct
|
||||
and function(pos) on_destruct(pos) remove_node(pos, tiers, name) end
|
||||
or function(pos) remove_node(pos, tiers, name) end,
|
||||
})
|
||||
end
|
||||
for name, _ in pairs(technic.machine_tiers) do
|
||||
if type(minetest.registered_nodes[name].technic_run) == "function" then
|
||||
node_technic_run[name] = minetest.registered_nodes[name].technic_run
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function run_nodes(list, run_stage, network)
|
||||
for _, pos in ipairs(list) do
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node then
|
||||
minetest.load_area(pos, pos)
|
||||
node = minetest.get_node_or_nil(pos)
|
||||
end
|
||||
if node and node.name and node_technic_run[node.name] then
|
||||
node_technic_run[node.name](pos, node, run_stage, network)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function technic.network_run(network_id)
|
||||
--
|
||||
-- !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
|
||||
-- TODO: This function requires a lot of cleanup
|
||||
-- It is moved here from switching_station.lua and still
|
||||
-- contain a lot of switching station specific stuff which
|
||||
-- should be removed and/or refactored.
|
||||
--
|
||||
|
||||
local t0 = minetest.get_us_time()
|
||||
|
||||
local PR_nodes
|
||||
local BA_nodes
|
||||
local RE_nodes
|
||||
|
||||
local network = networks[network_id]
|
||||
if network then
|
||||
PR_nodes, BA_nodes, RE_nodes = get_network(network_id, network.tier)
|
||||
if not PR_nodes or technic.is_overloaded(network_id) then return end
|
||||
else
|
||||
--dprint("Not connected to a network")
|
||||
technic.network_infotext(network_id, S("@1 Has No Network", S("Switching Station")))
|
||||
return
|
||||
end
|
||||
|
||||
-- Reset battery data for updates
|
||||
network.battery_charge = 0
|
||||
network.battery_charge_max = 0
|
||||
network.battery_supply = 0
|
||||
network.battery_demand = 0
|
||||
network.BA_count_active = 0
|
||||
network.BA_charge_active = 0
|
||||
|
||||
run_nodes(PR_nodes, technic.producer, network)
|
||||
run_nodes(RE_nodes, technic.receiver, network)
|
||||
run_nodes(BA_nodes, technic.battery, network)
|
||||
|
||||
-- Strings for the meta data
|
||||
local eu_demand_str = network.tier.."_EU_demand"
|
||||
local eu_input_str = network.tier.."_EU_input"
|
||||
local eu_supply_str = network.tier.."_EU_supply"
|
||||
|
||||
-- Distribute charge equally across multiple batteries.
|
||||
local charge_distributed = math.floor(network.BA_charge_active / network.BA_count_active)
|
||||
for n, pos1 in pairs(BA_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
if (meta1:get_int(eu_demand_str) ~= 0) then
|
||||
meta1:set_int("internal_EU_charge", charge_distributed)
|
||||
end
|
||||
end
|
||||
|
||||
-- Get all the power from the PR nodes
|
||||
local PR_eu_supply = 0 -- Total power
|
||||
for _, pos1 in pairs(PR_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
PR_eu_supply = PR_eu_supply + meta1:get_int(eu_supply_str)
|
||||
end
|
||||
--dprint("Total PR supply:"..PR_eu_supply)
|
||||
|
||||
-- Get all the demand from the RE nodes
|
||||
local RE_eu_demand = 0
|
||||
for _, pos1 in pairs(RE_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
RE_eu_demand = RE_eu_demand + meta1:get_int(eu_demand_str)
|
||||
end
|
||||
--dprint("Total RE demand:"..RE_eu_demand)
|
||||
|
||||
technic.network_infotext(network_id, S("@1. Supply: @2 Demand: @3",
|
||||
S("Switching Station"), technic.EU_string(PR_eu_supply),
|
||||
technic.EU_string(RE_eu_demand)))
|
||||
|
||||
-- Data that will be used by the power monitor
|
||||
network.supply = PR_eu_supply
|
||||
network.demand = RE_eu_demand
|
||||
network.battery_count = #BA_nodes
|
||||
|
||||
-- If the PR supply is enough for the RE demand supply them all
|
||||
local BA_eu_demand = network.battery_demand
|
||||
if PR_eu_supply >= RE_eu_demand then
|
||||
--dprint("PR_eu_supply"..PR_eu_supply.." >= RE_eu_demand"..RE_eu_demand)
|
||||
for _, pos1 in pairs(RE_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
local eu_demand = meta1:get_int(eu_demand_str)
|
||||
meta1:set_int(eu_input_str, eu_demand)
|
||||
end
|
||||
-- We have a surplus, so distribute the rest equally to the BA nodes
|
||||
-- Let's calculate the factor of the demand
|
||||
PR_eu_supply = PR_eu_supply - RE_eu_demand
|
||||
local charge_factor = 0 -- Assume all batteries fully charged
|
||||
if BA_eu_demand > 0 then
|
||||
charge_factor = PR_eu_supply / BA_eu_demand
|
||||
end
|
||||
-- TODO: EU input for all batteries: math.floor(BA_eu_demand * charge_factor * #BA_nodes)
|
||||
for n, pos1 in pairs(BA_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
local eu_demand = meta1:get_int(eu_demand_str)
|
||||
meta1:set_int(eu_input_str, math.floor(eu_demand * charge_factor))
|
||||
--dprint("Charging battery:"..math.floor(eu_demand*charge_factor))
|
||||
end
|
||||
local t1 = minetest.get_us_time()
|
||||
local diff = t1 - t0
|
||||
if diff > 50000 then
|
||||
minetest.log("warning", "[technic] [+supply] technic_run took " .. diff .. " us at "
|
||||
.. minetest.pos_to_string(hashpos(network_id)))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- If the PR supply is not enough for the RE demand we will discharge the batteries too
|
||||
local BA_eu_supply = network.battery_supply
|
||||
if PR_eu_supply + BA_eu_supply >= RE_eu_demand then
|
||||
--dprint("PR_eu_supply "..PR_eu_supply.."+BA_eu_supply "..BA_eu_supply.." >= RE_eu_demand"..RE_eu_demand)
|
||||
for _, pos1 in pairs(RE_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
local eu_demand = meta1:get_int(eu_demand_str)
|
||||
meta1:set_int(eu_input_str, eu_demand)
|
||||
end
|
||||
-- We have a deficit, so distribute to the BA nodes
|
||||
-- Let's calculate the factor of the supply
|
||||
local charge_factor = 0 -- Assume all batteries depleted
|
||||
if BA_eu_supply > 0 then
|
||||
charge_factor = (PR_eu_supply - RE_eu_demand) / BA_eu_supply
|
||||
end
|
||||
for n,pos1 in pairs(BA_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
local eu_supply = meta1:get_int(eu_supply_str)
|
||||
meta1:set_int(eu_input_str, math.floor(eu_supply * charge_factor))
|
||||
--dprint("Discharging battery:"..math.floor(eu_supply*charge_factor))
|
||||
end
|
||||
local t1 = minetest.get_us_time()
|
||||
local diff = t1 - t0
|
||||
if diff > 50000 then
|
||||
minetest.log("warning", "[technic] [-supply] technic_run took " .. diff .. " us at "
|
||||
.. minetest.pos_to_string(hashpos(network_id)))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- If the PR+BA supply is not enough for the RE demand: Power only the batteries
|
||||
local charge_factor = 0 -- Assume all batteries fully charged
|
||||
if BA_eu_demand > 0 then
|
||||
charge_factor = PR_eu_supply / BA_eu_demand
|
||||
end
|
||||
for n, pos1 in pairs(BA_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
local eu_demand = meta1:get_int(eu_demand_str)
|
||||
meta1:set_int(eu_input_str, math.floor(eu_demand * charge_factor))
|
||||
end
|
||||
for n, pos1 in pairs(RE_nodes) do
|
||||
local meta1 = minetest.get_meta(pos1)
|
||||
meta1:set_int(eu_input_str, 0)
|
||||
end
|
||||
|
||||
local t1 = minetest.get_us_time()
|
||||
local diff = t1 - t0
|
||||
if diff > 50000 then
|
||||
minetest.log("warning", "[technic] technic_run took " .. diff .. " us at "
|
||||
.. minetest.pos_to_string(hashpos(network_id)))
|
||||
end
|
||||
|
||||
end
|
131
mods/technic_plus_beta/technic/machines/other/anchor.lua
Normal file
131
mods/technic_plus_beta/technic/machines/other/anchor.lua
Normal file
|
@ -0,0 +1,131 @@
|
|||
local S = technic.getter
|
||||
|
||||
local desc = S("Administrative World Anchor")
|
||||
|
||||
local function compute_forceload_positions(pos, meta)
|
||||
local radius = meta:get_int("radius")
|
||||
local minpos = vector.subtract(pos, vector.new(radius, radius, radius))
|
||||
local maxpos = vector.add(pos, vector.new(radius, radius, radius))
|
||||
local minbpos = {}
|
||||
local maxbpos = {}
|
||||
for _, coord in ipairs({"x","y","z"}) do
|
||||
minbpos[coord] = math.floor(minpos[coord] / 16) * 16
|
||||
maxbpos[coord] = math.floor(maxpos[coord] / 16) * 16
|
||||
end
|
||||
local flposes = {}
|
||||
for x = minbpos.x, maxbpos.x, 16 do
|
||||
for y = minbpos.y, maxbpos.y, 16 do
|
||||
for z = minbpos.z, maxbpos.z, 16 do
|
||||
table.insert(flposes, vector.new(x, y, z))
|
||||
end
|
||||
end
|
||||
end
|
||||
return flposes
|
||||
end
|
||||
|
||||
local function currently_forceloaded_positions(meta)
|
||||
local ser = meta:get_string("forceloaded")
|
||||
return ser == "" and {} or minetest.deserialize(ser)
|
||||
end
|
||||
|
||||
local function forceload_off(meta)
|
||||
local flposes = currently_forceloaded_positions(meta)
|
||||
meta:set_string("forceloaded", "")
|
||||
for _, p in ipairs(flposes) do
|
||||
minetest.forceload_free_block(p)
|
||||
end
|
||||
end
|
||||
|
||||
local function forceload_on(pos, meta)
|
||||
local want_flposes = compute_forceload_positions(pos, meta)
|
||||
local have_flposes = {}
|
||||
for _, p in ipairs(want_flposes) do
|
||||
if minetest.forceload_block(p) then
|
||||
table.insert(have_flposes, p)
|
||||
end
|
||||
end
|
||||
meta:set_string("forceloaded", #have_flposes == 0 and "" or minetest.serialize(have_flposes))
|
||||
end
|
||||
|
||||
local function set_display(pos, meta)
|
||||
meta:set_string("infotext", S(meta:get_int("enabled") ~= 0 and "@1 Enabled" or "@1 Disabled", desc))
|
||||
meta:set_string("formspec",
|
||||
"size[5,3.5]"..
|
||||
"item_image[0,0;1,1;technic:admin_anchor]"..
|
||||
"label[1,0;"..desc.."]"..
|
||||
"label[0,1;"..S("Owner: @1", meta:get_string("owner")).."]"..
|
||||
(meta:get_int("locked") == 0 and
|
||||
"button[3,1;2,1;lock;"..S("Unlocked").."]" or
|
||||
"button[3,1;2,1;unlock;"..S("Locked").."]")..
|
||||
"field[0.25,2.3;1,1;radius;"..S("Radius")..";${radius}]"..
|
||||
(meta:get_int("enabled") == 0 and
|
||||
"button[3,2;2,1;enable;"..S("Disabled").."]" or
|
||||
"button[3,2;2,1;disable;"..S("Enabled").."]")..
|
||||
"label[0,3;"..S("Keeping @1/@2 map blocks loaded",
|
||||
#currently_forceloaded_positions(meta), #compute_forceload_positions(pos, meta)).."]")
|
||||
end
|
||||
|
||||
minetest.register_node("technic:admin_anchor", {
|
||||
description = desc,
|
||||
drawtype = "normal",
|
||||
tiles = {"technic_admin_anchor.png"},
|
||||
is_ground_content = false,
|
||||
groups = {cracky=3, not_in_creative_inventory=1, pickaxey=1},
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
after_place_node = function (pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if placer and placer:is_player() then
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
end
|
||||
set_display(pos, meta)
|
||||
end,
|
||||
can_dig = function (pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
return meta:get_int("locked") == 0 or (player and player:is_player()
|
||||
and player:get_player_name() == meta:get_string("owner"))
|
||||
end,
|
||||
on_destruct = function (pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
forceload_off(meta)
|
||||
end,
|
||||
on_receive_fields = function (pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if (meta:get_int("locked") ~= 0 or fields.lock) and
|
||||
not (sender and sender:is_player() and
|
||||
sender:get_player_name() == meta:get_string("owner")) then
|
||||
return
|
||||
end
|
||||
if fields.unlock then meta:set_int("locked", 0) end
|
||||
if fields.lock then meta:set_int("locked", 1) end
|
||||
if fields.disable or fields.enable or fields.radius then
|
||||
forceload_off(meta)
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.radius and string.find(fields.radius, "^[0-9]+$") and tonumber(fields.radius) < 256 then
|
||||
meta:set_int("radius", fields.radius)
|
||||
end
|
||||
if meta:get_int("enabled") ~= 0 then
|
||||
forceload_on(pos, meta)
|
||||
end
|
||||
end
|
||||
set_display(pos, meta)
|
||||
end,
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("enabled", 1)
|
||||
forceload_on(pos, meta)
|
||||
set_display(pos, meta)
|
||||
end,
|
||||
action_off = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("enabled", 0)
|
||||
forceload_off(meta)
|
||||
set_display(pos, meta)
|
||||
end
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,206 @@
|
|||
|
||||
-- Fuel driven alloy furnace. This uses no EUs:
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:coal_alloy_furnace',
|
||||
recipe = {
|
||||
{mat.brick, mat.brick, mat.brick},
|
||||
{mat.brick, '', mat.brick},
|
||||
{mat.brick, mat.brick, mat.brick},
|
||||
}
|
||||
})
|
||||
|
||||
local machine_name = S("Fuel-Fired Alloy Furnace")
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,9]" or "size[8,9]"
|
||||
local formspec =
|
||||
size..
|
||||
"label[0,0;"..machine_name.."]"..
|
||||
"image[2,2;1,1;default_furnace_fire_bg.png]"..
|
||||
"list[context;fuel;2,3;1,1;]"..
|
||||
"list[context;src;2,1;2,1;]"..
|
||||
"list[context;dst;5,1;2,2;]"
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
formspec = formspec..
|
||||
mcl_formspec.get_itemslot_bg(2,3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(2,1,2,1)..
|
||||
mcl_formspec.get_itemslot_bg(5,1,2,2)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)
|
||||
else
|
||||
formspec = formspec..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
end
|
||||
|
||||
-- listrings
|
||||
formspec = formspec..
|
||||
"listring[context;dst]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;fuel]"..
|
||||
"listring[current_player;main]"
|
||||
|
||||
minetest.register_node("technic:coal_alloy_furnace", {
|
||||
description = machine_name,
|
||||
tiles = {"technic_coal_alloy_furnace_top.png", "technic_coal_alloy_furnace_bottom.png",
|
||||
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_side.png",
|
||||
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_front.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, pickaxey=2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", formspec)
|
||||
meta:set_string("infotext", machine_name)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 2)
|
||||
inv:set_size("dst", 4)
|
||||
end,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:coal_alloy_furnace_active", {
|
||||
description = machine_name,
|
||||
tiles = {"technic_coal_alloy_furnace_top.png", "technic_coal_alloy_furnace_bottom.png",
|
||||
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_side.png",
|
||||
"technic_coal_alloy_furnace_side.png", "technic_coal_alloy_furnace_front_active.png"},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 8,
|
||||
drop = "technic:coal_alloy_furnace",
|
||||
groups = {cracky=2, not_in_creative_inventory=1, pickaxey=2},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Machines: run coal alloy furnace",
|
||||
nodenames = {"technic:coal_alloy_furnace", "technic:coal_alloy_furnace_active"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local src_list = inv:get_list("src")
|
||||
if not src_list then
|
||||
return
|
||||
end
|
||||
|
||||
for i, name in pairs({
|
||||
"fuel_totaltime",
|
||||
"fuel_time",
|
||||
"src_totaltime",
|
||||
"src_time"}) do
|
||||
if not meta:get_float(name) then
|
||||
meta:set_float(name, 0.0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Get what to cook if anything
|
||||
local recipe = technic.get_recipe("alloy", src_list)
|
||||
|
||||
local was_active = false
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
was_active = true
|
||||
meta:set_int("fuel_time", meta:get_int("fuel_time") + 1)
|
||||
if recipe then
|
||||
meta:set_int("src_time", meta:get_int("src_time") + 1)
|
||||
if meta:get_int("src_time") >= recipe.time then
|
||||
meta:set_int("src_time", 0)
|
||||
technic.process_recipe(recipe, inv)
|
||||
end
|
||||
else
|
||||
meta:set_int("src_time", 0)
|
||||
end
|
||||
end
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
local percent = math.floor(meta:get_float("fuel_time") /
|
||||
meta:get_float("fuel_totaltime") * 100)
|
||||
meta:set_string("infotext", S("@1 Active", machine_name).." ("..percent.."%)")
|
||||
technic.swap_node(pos, "technic:coal_alloy_furnace_active")
|
||||
meta:set_string("formspec",
|
||||
size..
|
||||
"label[0,0;"..machine_name.."]"..
|
||||
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
||||
(100 - percent)..":default_furnace_fire_fg.png]"..
|
||||
"list[context;fuel;2,3;1,1;]"..
|
||||
"list[context;src;2,1;2,1;]"..
|
||||
"list[context;dst;5,1;2,2;]"..
|
||||
|
||||
(minetest.get_modpath("mcl_formspec") and
|
||||
mcl_formspec.get_itemslot_bg(2,3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(2,1,2,1)..
|
||||
mcl_formspec.get_itemslot_bg(5,1,2,2)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)
|
||||
or "list[current_player;main;0,5;8,4;]")..
|
||||
|
||||
-- listrings
|
||||
"listring[context;dst]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;fuel]"..
|
||||
"listring[current_player;main]")
|
||||
return
|
||||
end
|
||||
|
||||
if not technic.get_recipe("alloy", inv:get_list("src")) then
|
||||
if was_active then
|
||||
meta:set_string("infotext", S("@1 is empty", machine_name))
|
||||
technic.swap_node(pos, "technic:coal_alloy_furnace")
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Next take a hard look at the fuel situation
|
||||
local fuellist = inv:get_list("fuel")
|
||||
local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
|
||||
|
||||
if fuel.time <= 0 then
|
||||
meta:set_string("infotext", S("@1 Out Of Fuel", machine_name))
|
||||
technic.swap_node(pos, "technic:coal_alloy_furnace")
|
||||
meta:set_string("formspec", formspec)
|
||||
return
|
||||
end
|
||||
|
||||
meta:set_string("fuel_totaltime", fuel.time)
|
||||
meta:set_string("fuel_time", 0)
|
||||
|
||||
inv:set_stack("fuel", 1, afterfuel.items[1])
|
||||
end,
|
||||
})
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
local S = technic.getter
|
||||
|
||||
local default_furnace = minetest.registered_nodes["default:furnace"]
|
||||
|
||||
if default_furnace and default_furnace.description == "Furnace" then
|
||||
minetest.override_item("default:furnace", { description = S("Fuel-Fired Furnace") })
|
||||
end
|
246
mods/technic_plus_beta/technic/machines/other/constructor.lua
Normal file
246
mods/technic_plus_beta/technic/machines/other/constructor.lua
Normal file
|
@ -0,0 +1,246 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
local function deploy_node(inv, slot_name, pos, node, machine_node)
|
||||
if node.param2 > 3 then return end
|
||||
if node.name ~= "air" then
|
||||
if node.name == "ignore" or
|
||||
node.name == "default:chest_open" or
|
||||
node.name == "default:chest_locked_open" or
|
||||
node.name == "default:lava_source" or
|
||||
node.name == "default:lava_flowing" or
|
||||
node.name == "default:water_source" or
|
||||
node.name == "default:water_flowing" then
|
||||
return
|
||||
end
|
||||
local drops = minetest.get_node_drops(node.name, "")
|
||||
local remove_to = false
|
||||
for i, item in ipairs(drops) do
|
||||
if not inv:room_for_item(slot_name, item) then
|
||||
remove_to = i - 1
|
||||
break
|
||||
end
|
||||
inv:add_item(slot_name, item)
|
||||
end
|
||||
if remove_to then
|
||||
for i = 1, remove_to do
|
||||
inv:remove_item(slot_name, drops[i])
|
||||
end
|
||||
else
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
return
|
||||
end
|
||||
if not inv:is_empty(slot_name) then
|
||||
local stack = inv:get_list(slot_name)[1]
|
||||
local def = stack:get_definition()
|
||||
if def.type == "node" then
|
||||
minetest.set_node(pos, {
|
||||
name = stack:get_name(),
|
||||
param2 = machine_node.param2
|
||||
})
|
||||
stack:take_item()
|
||||
inv:set_stack(slot_name, 1, stack)
|
||||
elseif def.type == "craft" then
|
||||
if def.on_place then
|
||||
-- Use pcall to avoid nil placer errors.
|
||||
-- TODO: Do without pcall.
|
||||
local ok, stk = pcall(def.on_place, stack, nil, {
|
||||
-- Fake pointed_thing
|
||||
type = "node",
|
||||
above = pos,
|
||||
under = {x=pos.x, y=pos.y-1, z=pos.z},
|
||||
})
|
||||
if ok then
|
||||
inv:set_stack(slot_name, 1, stk or stack)
|
||||
return
|
||||
end
|
||||
end
|
||||
minetest.item_place_object(stack, nil, {
|
||||
-- Fake pointed_thing
|
||||
type = "node",
|
||||
above = pos,
|
||||
under = pos,
|
||||
})
|
||||
inv:set_stack(slot_name, 1, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = 'technic:constructor_mk1_off 1',
|
||||
recipe = {'technic:nodebreaker_off', 'technic:deployer_off'},
|
||||
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = 'technic:constructor_mk2_off 1',
|
||||
recipe = {'technic:constructor_mk1_off', 'technic:constructor_mk1_off'},
|
||||
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = 'technic:constructor_mk3_off 1',
|
||||
recipe = {'technic:constructor_mk2_off', 'technic:constructor_mk2_off'},
|
||||
|
||||
})
|
||||
|
||||
local function make_on(mark, length)
|
||||
return function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
local inv = meta:get_inventory()
|
||||
local dir = vector.new()
|
||||
if node.param2 == 3 then dir.x = 1 end
|
||||
if node.param2 == 2 then dir.z = 1 end
|
||||
if node.param2 == 1 then dir.x = -1 end
|
||||
if node.param2 == 0 then dir.z = -1 end
|
||||
|
||||
local place_pos = vector.new(pos)
|
||||
|
||||
if node.name == "technic:constructor_mk"..mark.."_off" then
|
||||
technic.swap_node(pos, "technic:constructor_mk"..mark.."_on")
|
||||
minetest.check_for_falling(pos)
|
||||
for i = 1, length do
|
||||
place_pos = vector.add(place_pos, dir)
|
||||
if owner ~= "" and minetest.is_protected(place_pos, owner) then
|
||||
return
|
||||
end
|
||||
local place_node = minetest.get_node(place_pos)
|
||||
deploy_node(inv, "slot"..i, place_pos, place_node, node)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function make_off(mark)
|
||||
return function(pos, node)
|
||||
if node.name == "technic:constructor_mk"..mark.."_on" then
|
||||
technic.swap_node(pos,"technic:constructor_mk"..mark.."_off")
|
||||
minetest.check_for_falling(pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_inventory_put(pos, listname, index, stack, player)
|
||||
if stack and minetest.get_item_group(stack:get_name(), "technic_constructor") == 1 then
|
||||
return 0
|
||||
end
|
||||
return technic.machine_inventory_put(pos, listname, index, stack, player)
|
||||
end
|
||||
|
||||
local function make_constructor(mark, length)
|
||||
minetest.register_node("technic:constructor_mk"..mark.."_off", {
|
||||
description = S("Constructor Mk@1", mark),
|
||||
tiles = {"technic_constructor_mk"..mark.."_top_off.png",
|
||||
"technic_constructor_mk"..mark.."_bottom_off.png",
|
||||
"technic_constructor_mk"..mark.."_side2_off.png",
|
||||
"technic_constructor_mk"..mark.."_side1_off.png",
|
||||
"technic_constructor_back.png",
|
||||
"technic_constructor_front_off.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
mesecon = 2, technic_constructor = 1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
mesecons = {effector = {action_on = make_on(mark, length)}},
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,9]" or "size[8,9]"
|
||||
local formspec = size..
|
||||
"label[0,0;"..S("Constructor Mk@1", mark).."]"
|
||||
for i = 1, length do
|
||||
formspec = formspec..
|
||||
"label[5,"..(i - 1)..";"..S("Slot @1", i).."]"..
|
||||
"list[context;slot"..i..";6,"..(i - 1)..";1,1;]"
|
||||
end
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
for i = 1, length do
|
||||
formspec = formspec..
|
||||
mcl_formspec.get_itemslot_bg(6,i-1,1,1)
|
||||
end
|
||||
formspec = formspec..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)
|
||||
else
|
||||
formspec = formspec..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
end
|
||||
-- listrings
|
||||
for i = 1, length do
|
||||
formspec = formspec..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;slot"..i.."]"
|
||||
end
|
||||
|
||||
meta:set_string("formspec", formspec)
|
||||
meta:set_string("infotext", S("Constructor Mk@1", mark))
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, length do
|
||||
inv:set_size("slot"..i, 1)
|
||||
end
|
||||
meta:set_string("owner", "?")
|
||||
end,
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("owner", (placer and placer:get_player_name() or "?"))
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
for i = 1, length do
|
||||
if not inv:is_empty("slot"..i) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_put = allow_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
on_rotate = function(pos, node, user, mode, new_param2)
|
||||
if mode ~= 1 then
|
||||
return false
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:constructor_mk"..mark.."_on", {
|
||||
tiles = {"technic_constructor_mk"..mark.."_top_on.png",
|
||||
"technic_constructor_mk"..mark.."_bottom_on.png",
|
||||
"technic_constructor_mk"..mark.."_side2_on.png",
|
||||
"technic_constructor_mk"..mark.."_side1_on.png",
|
||||
"technic_constructor_back.png",
|
||||
"technic_constructor_front_on.png"},
|
||||
paramtype2 = "facedir",
|
||||
drop = "technic:constructor_mk"..mark.."_off",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
mesecon=2, not_in_creative_inventory=1, technic_constructor=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
mesecons= {effector = {action_off = make_off(mark)}},
|
||||
sounds = technic.sounds.node_sound_stone_defaults(),
|
||||
allow_metadata_inventory_put = allow_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
on_rotate = false
|
||||
})
|
||||
end
|
||||
|
||||
make_constructor(1, 1)
|
||||
make_constructor(2, 2)
|
||||
make_constructor(3, 4)
|
12
mods/technic_plus_beta/technic/machines/other/init.lua
Normal file
12
mods/technic_plus_beta/technic/machines/other/init.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
local path = technic.modpath.."/machines/other"
|
||||
|
||||
-- Mesecons and tubes related
|
||||
dofile(path.."/injector.lua")
|
||||
dofile(path.."/constructor.lua")
|
||||
|
||||
-- Coal-powered machines
|
||||
dofile(path.."/coal_alloy_furnace.lua")
|
||||
dofile(path.."/coal_furnace.lua")
|
||||
|
||||
-- Force-loading
|
||||
dofile(path.."/anchor.lua")
|
180
mods/technic_plus_beta/technic/machines/other/injector.lua
Normal file
180
mods/technic_plus_beta/technic/machines/other/injector.lua
Normal file
|
@ -0,0 +1,180 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
local fs_helpers = pipeworks.fs_helpers
|
||||
|
||||
local tube_entry = "^pipeworks_tube_connection_metallic.png"
|
||||
|
||||
local mat = technic.materials
|
||||
|
||||
local param2_to_under = {
|
||||
[0] = {x= 0,y=-1,z= 0}, [1] = {x= 0,y= 0,z=-1},
|
||||
[2] = {x= 0,y= 0,z= 1}, [3] = {x=-1,y= 0,z= 0},
|
||||
[4] = {x= 1,y= 0,z= 0}, [5] = {x= 0,y= 1,z= 0}
|
||||
}
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,10]" or "size[8,9]"
|
||||
local base_formspec = size..
|
||||
"label[0,0;"..S("Self-Contained Injector").."]"..
|
||||
"list[context;main;0,2;8,2;]"..
|
||||
"listring[context;main]"
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
base_formspec = base_formspec..
|
||||
mcl_formspec.get_itemslot_bg(0,2,8,2)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,5.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,5.5,9,3)..
|
||||
"list[current_player;main;0,8.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,8.74,9,1)..
|
||||
"listring[current_player;main]"
|
||||
else
|
||||
base_formspec = base_formspec..
|
||||
"list[current_player;main;0,5;8,4;]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local function set_injector_formspec(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local formspec = base_formspec..
|
||||
fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
if meta:get_string("mode") == "whole stacks" then
|
||||
formspec = formspec.."button[0,1;4,1;mode_item;"..S("Stackwise").."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1;4,1;mode_stack;"..S("Itemwise").."]"
|
||||
end
|
||||
if minetest.get_node_timer(pos):is_started() then
|
||||
formspec = formspec.."button[4,1;4,1;disable;"..S("Enabled").."]"
|
||||
else
|
||||
formspec = formspec.."button[4,1;4,1;enable;"..S("Disabled").."]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
||||
minetest.register_node("technic:injector", {
|
||||
description = S("Self-Contained Injector"),
|
||||
tiles = {
|
||||
"technic_injector_top.png"..tube_entry,
|
||||
"technic_injector_bottom.png",
|
||||
"technic_injector_side.png"..tube_entry,
|
||||
"technic_injector_side.png"..tube_entry,
|
||||
"technic_injector_side.png"..tube_entry,
|
||||
"technic_injector_side.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice=1, tubedevice_receiver=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
tube = {
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_int("splitstacks") == 1 then
|
||||
stack = stack:peek_item(1)
|
||||
end
|
||||
return meta:get_inventory():room_for_item("main", stack)
|
||||
end,
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
return minetest.get_meta(pos):get_inventory():add_item("main", stack)
|
||||
end,
|
||||
connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
|
||||
},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Self-Contained Injector"))
|
||||
meta:set_string("mode", "single items")
|
||||
meta:get_inventory():set_size("main", 16)
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
set_injector_formspec(pos)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
return minetest.get_meta(pos):get_inventory():is_empty("main")
|
||||
end,
|
||||
on_receive_fields = function(pos, formanme, fields, sender)
|
||||
if fields.quit or not pipeworks.may_configure(pos, sender) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.mode_item then
|
||||
meta:set_string("mode", "single items")
|
||||
elseif fields.mode_stack then
|
||||
meta:set_string("mode", "whole stacks")
|
||||
elseif fields.disable then
|
||||
minetest.get_node_timer(pos):stop()
|
||||
elseif fields.enable then
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
set_injector_formspec(pos)
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local dir = param2_to_under[math.floor(node.param2 / 4)]
|
||||
local node_under = minetest.get_node(vector.add(pos, dir))
|
||||
if minetest.get_item_group(node_under.name, "tubedevice") > 0 then
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list("main")
|
||||
if not list then
|
||||
return true
|
||||
end
|
||||
local stackwise = meta:get_string("mode") == "whole stacks"
|
||||
for i,stack in ipairs(list) do
|
||||
if not stack:is_empty() then
|
||||
if stackwise then
|
||||
technic.tube_inject_item(pos, pos, dir, stack:to_table())
|
||||
stack:clear()
|
||||
else
|
||||
technic.tube_inject_item(pos, pos, dir, stack:take_item(1):to_table())
|
||||
end
|
||||
inv:set_stack("main", i, stack)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
on_rotate = function(pos, node, user, mode, new_param2)
|
||||
node.param2 = new_param2
|
||||
minetest.swap_node(pos, node)
|
||||
pipeworks.scan_for_tube_objects(pos)
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
after_place_node = pipeworks.after_place,
|
||||
after_dig_node = pipeworks.after_dig
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:injector 1",
|
||||
recipe = {
|
||||
{"", "technic:control_logic_unit",""},
|
||||
{"", mat.chest,""},
|
||||
{"", "pipeworks:tube_1",""},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Old injector conversion",
|
||||
name = "technic:old_injector_conversion",
|
||||
nodenames = {"technic:injector"},
|
||||
run_at_every_load = false,
|
||||
action = function(pos, node)
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
set_injector_formspec(pos)
|
||||
end
|
||||
})
|
31
mods/technic_plus_beta/technic/machines/overload.lua
Normal file
31
mods/technic_plus_beta/technic/machines/overload.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
--
|
||||
-- Network overloading (incomplete cheat mitigation)
|
||||
--
|
||||
|
||||
local overload_reset_time = technic.config:get_int("network_overload_reset_time")
|
||||
local overloaded_networks = {}
|
||||
local networks = technic.networks
|
||||
|
||||
function technic.overload_network(network_id)
|
||||
local network = networks[network_id]
|
||||
if network then
|
||||
network.supply = 0
|
||||
network.battery_charge = 0
|
||||
end
|
||||
overloaded_networks[network_id] = minetest.get_us_time() + (overload_reset_time * 1000 * 1000)
|
||||
end
|
||||
|
||||
function technic.reset_overloaded(network_id)
|
||||
local remaining = math.max(0, overloaded_networks[network_id] - minetest.get_us_time())
|
||||
if remaining == 0 then
|
||||
-- Clear cache, remove overload and restart network
|
||||
technic.remove_network(network_id)
|
||||
overloaded_networks[network_id] = nil
|
||||
end
|
||||
-- Returns 0 when network reset or remaining time if reset timer has not expired yet
|
||||
return remaining
|
||||
end
|
||||
|
||||
function technic.is_overloaded(network_id)
|
||||
return overloaded_networks[network_id]
|
||||
end
|
133
mods/technic_plus_beta/technic/machines/power_monitor.lua
Normal file
133
mods/technic_plus_beta/technic/machines/power_monitor.lua
Normal file
|
@ -0,0 +1,133 @@
|
|||
-- POWER MONITOR
|
||||
-- The power monitor can be used to monitor how much power is available on a network,
|
||||
-- similarly to the old "slave" switching stations.
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
-- Get registered cable or nil, returns nil if area is not loaded
|
||||
local function get_cable(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
return (node and technic.get_cable_tier(node.name)) and node
|
||||
end
|
||||
|
||||
-- return the position of connected cable or nil
|
||||
-- TODO: Make it support every possible orientation
|
||||
local function get_connected_cable_network(pos)
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
-- should probably also work sideways or upside down but for now it wont
|
||||
if param2 > 3 then return end
|
||||
-- Below?
|
||||
local checkpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||
local network_id = get_cable(checkpos) and technic.pos2network(checkpos)
|
||||
if network_id then
|
||||
return network_id
|
||||
end
|
||||
-- Behind?
|
||||
checkpos = vector.add(minetest.facedir_to_dir(param2),pos)
|
||||
network_id = get_cable(checkpos) and technic.pos2network(checkpos)
|
||||
return network_id
|
||||
end
|
||||
|
||||
-- return the position of the associated switching station or nil
|
||||
local function get_network(pos)
|
||||
local network_id = get_connected_cable_network(pos)
|
||||
local network = network_id and technic.networks[network_id]
|
||||
local swpos = network and technic.network2sw_pos(network_id)
|
||||
local is_powermonitor = swpos and minetest.get_node(swpos).name == "technic:switching_station"
|
||||
return (is_powermonitor and network.all_nodes[network_id]) and network
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:power_monitor",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"", "technic:machine_casing", mat.copper_ingot},
|
||||
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("technic:power_monitor",{
|
||||
description = S("Power Monitor"),
|
||||
tiles = {
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_sides.png"..cable_entry,
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_sides.png"..cable_entry,
|
||||
"technic_power_monitor_front.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_all_tiers=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom", "back"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Power Monitor"))
|
||||
meta:set_string("formspec", "field[channel;"..S("Digiline Channel")..";${channel}]")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not fields.channel then
|
||||
return
|
||||
end
|
||||
local plname = sender:get_player_name()
|
||||
if minetest.is_protected(pos, plname) and not minetest.check_player_privs(sender, "protection_bypass") then
|
||||
minetest.record_protection_violation(pos, plname)
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("channel", fields.channel)
|
||||
end,
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function() end
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function(pos, node, channel, msg)
|
||||
if msg ~= "GET" and msg ~= "get" then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
|
||||
local network = get_network(pos)
|
||||
if not network then return end
|
||||
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
supply = network.supply,
|
||||
demand = network.demand,
|
||||
lag = network.lag,
|
||||
battery_count = network.battery_count,
|
||||
battery_charge = network.battery_charge,
|
||||
battery_charge_max = network.battery_charge_max,
|
||||
})
|
||||
end
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:power_monitor"},
|
||||
label = "Machines: run power monitor",
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local network = get_network(pos)
|
||||
if network then
|
||||
meta:set_string("infotext", S("Power Monitor. Supply: @1 Demand: @2",
|
||||
technic.EU_string(network.supply), technic.EU_string(network.demand)))
|
||||
else
|
||||
meta:set_string("infotext",S("Power Monitor Has No Network"))
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
technic.register_recipe_type("alloy", {
|
||||
description = S("Alloying"),
|
||||
icon = "technic_mv_alloy_furnace_front.png",
|
||||
input_size = 2,
|
||||
})
|
||||
|
||||
function technic.register_alloy_recipe(data)
|
||||
data.time = data.time or 6
|
||||
technic.register_recipe("alloy", data)
|
||||
end
|
||||
|
||||
local recipes = {
|
||||
{"technic:copper_dust 7", "technic:tin_dust", mat.bronze_ingot.." 8", 12},
|
||||
{mat.copper_ingot.." 7", mat.tin_ingot, mat.bronze_ingot.." 8", 12},
|
||||
{"technic:wrought_iron_dust 2", "technic:coal_dust", "technic:carbon_steel_ingot 2", 6},
|
||||
{"technic:wrought_iron_ingot 2", "technic:coal_dust", "technic:carbon_steel_ingot 2", 6},
|
||||
{"technic:carbon_steel_dust 4", "technic:chromium_dust", "technic:stainless_steel_ingot 5", 7.5},
|
||||
{"technic:carbon_steel_ingot 4", "technic:chromium_ingot", "technic:stainless_steel_ingot 5", 7.5},
|
||||
{"technic:copper_dust 2", "technic:zinc_dust", "basic_materials:brass_ingot 3"},
|
||||
{mat.copper_ingot.." 2", "technic:zinc_ingot", "basic_materials:brass_ingot 3"},
|
||||
{mat.sand.." 2", "technic:coal_dust 2", "technic:silicon_wafer"},
|
||||
{"technic:silicon_wafer", "technic:gold_dust", "technic:doped_silicon_wafer"},
|
||||
-- from https://en.wikipedia.org/wiki/Carbon_black
|
||||
-- The highest volume use of carbon black is as a reinforcing filler in rubber products, especially tires.
|
||||
-- "[Compounding a] pure gum vulcanizate … with 50% of its weight of carbon black
|
||||
-- improves its tensile strength and wear resistance …"
|
||||
{"technic:raw_latex 4", "technic:coal_dust 2", "technic:rubber 6", 2},
|
||||
{"technic:raw_latex 2", mat.coal_lump, "technic:rubber 2", 2},
|
||||
{mat.ice, mat.bucket_empty, mat.bucket_water, 1 },
|
||||
{mat.obsidian, mat.bucket_empty, mat.bucket_lava, 1 },
|
||||
}
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
table.insert(recipes, {mat.clay, mat.dye_red, "bakedclay:red"})
|
||||
table.insert(recipes, {mat.clay, mat.dye_orange, "bakedclay:orange"})
|
||||
table.insert(recipes, {mat.clay, mat.dye_grey, "bakedclay:grey"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("digilines") then
|
||||
table.insert(recipes,
|
||||
{"technic:lv_cable", "digilines:wire_std_00000000 2", "technic:lv_digi_cable", 18})
|
||||
table.insert(recipes,
|
||||
{"technic:lv_cable_plate_1", "digilines:wire_std_00000000 2", "technic:lv_digi_cable_plate_1", 18})
|
||||
table.insert(recipes,
|
||||
{"technic:mv_cable", "digilines:wire_std_00000000 2", "technic:mv_digi_cable", 18})
|
||||
table.insert(recipes,
|
||||
{"technic:mv_cable_plate_1", "digilines:wire_std_00000000 2", "technic:mv_digi_cable_plate_1", 18})
|
||||
table.insert(recipes,
|
||||
{"technic:hv_cable", "digilines:wire_std_00000000 2", "technic:hv_digi_cable", 18})
|
||||
table.insert(recipes,
|
||||
{"technic:hv_cable_plate_1", "digilines:wire_std_00000000 2", "technic:hv_digi_cable_plate_1", 18})
|
||||
end
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_alloy_recipe({input = {data[1], data[2]}, output = data[3], time = data[4]})
|
||||
end
|
458
mods/technic_plus_beta/technic/machines/register/battery_box.lua
Normal file
458
mods/technic_plus_beta/technic/machines/register/battery_box.lua
Normal file
|
@ -0,0 +1,458 @@
|
|||
|
||||
local digilines_path = minetest.get_modpath("digilines")
|
||||
|
||||
local S = technic.getter
|
||||
local tube_entry = "^pipeworks_tube_connection_metallic.png"
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
local mat = technic.materials
|
||||
|
||||
-- Battery recipes:
|
||||
-- Tin-copper recipe:
|
||||
minetest.register_craft({
|
||||
output = "technic:battery",
|
||||
recipe = {
|
||||
{"group:wood", mat.copper_ingot, "group:wood"},
|
||||
{"group:wood", mat.tin_ingot, "group:wood"},
|
||||
{"group:wood", mat.copper_ingot, "group:wood"},
|
||||
}
|
||||
})
|
||||
-- Sulfur-lead-water recipes:
|
||||
-- With sulfur lumps:
|
||||
-- With water:
|
||||
minetest.register_craft({
|
||||
output = "technic:battery",
|
||||
recipe = {
|
||||
{"group:wood", "technic:sulfur_lump", "group:wood"},
|
||||
{"technic:lead_ingot", mat.bucket_water, "technic:lead_ingot"},
|
||||
{"group:wood", "technic:sulfur_lump", "group:wood"},
|
||||
},
|
||||
replacements = {
|
||||
{mat.bucket_water, mat.bucket_empty}
|
||||
}
|
||||
})
|
||||
-- With oil extract:
|
||||
minetest.register_craft({
|
||||
output = "technic:battery",
|
||||
recipe = {
|
||||
{"group:wood", "technic:sulfur_lump", "group:wood"},
|
||||
{"technic:lead_ingot", "homedecor:oil_extract", "technic:lead_ingot"},
|
||||
{"group:wood", "technic:sulfur_lump", "group:wood"},
|
||||
}
|
||||
})
|
||||
-- With sulfur dust:
|
||||
-- With water:
|
||||
minetest.register_craft({
|
||||
output = "technic:battery",
|
||||
recipe = {
|
||||
{"group:wood", "technic:sulfur_dust", "group:wood"},
|
||||
{"technic:lead_ingot", mat.bucket_water, "technic:lead_ingot"},
|
||||
{"group:wood", "technic:sulfur_dust", "group:wood"},
|
||||
},
|
||||
replacements = {
|
||||
{mat.bucket_water, mat.bucket_empty}
|
||||
}
|
||||
})
|
||||
-- With oil extract:
|
||||
minetest.register_craft({
|
||||
output = "technic:battery",
|
||||
recipe = {
|
||||
{"group:wood", "technic:sulfur_dust", "group:wood"},
|
||||
{"technic:lead_ingot", "homedecor:oil_extract", "technic:lead_ingot"},
|
||||
{"group:wood", "technic:sulfur_dust", "group:wood"},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_power_tool("technic:battery", {
|
||||
description = S("RE Battery"),
|
||||
inventory_image = "technic_battery.png",
|
||||
groups = { disable_repair = 1 },
|
||||
})
|
||||
|
||||
-- x+2 + (z+2)*2
|
||||
local dirtab = {
|
||||
[4] = 2,
|
||||
[5] = 3,
|
||||
[7] = 1,
|
||||
[8] = 0
|
||||
}
|
||||
|
||||
local tube = {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
if direction.y == 1
|
||||
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
|
||||
return stack
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if direction.y == 0 then
|
||||
return inv:add_item("src", stack)
|
||||
else
|
||||
return inv:add_item("dst", stack)
|
||||
end
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
if direction.y == 1
|
||||
or (direction.y == 0 and dirtab[direction.x+2+(direction.z+2)*2] == node.param2) then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if direction.y == 0 then
|
||||
return inv:room_for_item("src", stack)
|
||||
else
|
||||
return inv:room_for_item("dst", stack)
|
||||
end
|
||||
end,
|
||||
connect_sides = {left=1, right=1, back=1, top=1},
|
||||
}
|
||||
|
||||
function technic.register_battery_box(nodename, data)
|
||||
local colon, modname, name, def = technic.register_compat_v1_to_v2(nodename, data, "battery_box")
|
||||
local texture_prefix = modname.."_"..name
|
||||
nodename = modname..":"..name
|
||||
|
||||
local tier = def.tier
|
||||
local ltier = string.lower(tier)
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,9]" or "size[8,9]"
|
||||
local formspec =
|
||||
size..
|
||||
"image[1,1;1,2;technic_power_meter_bg.png]"..
|
||||
"list[context;src;3,1;1,1;]"..
|
||||
"image[4,1;1,1;technic_battery_reload.png]"..
|
||||
"list[context;dst;5,1;1,1;]"..
|
||||
"label[0,0;"..S("@1 Battery Box", S(tier)).."]"..
|
||||
"label[3,0;"..S("Charge").."]"..
|
||||
"label[5,0;"..S("Discharge").."]"..
|
||||
"label[1,3;"..S("Power level").."]"..
|
||||
(def.upgrade and
|
||||
"list[context;upgrade1;3.5,3;1,1;]"..
|
||||
"list[context;upgrade2;4.5,3;1,1;]"..
|
||||
"label[3.5,4;"..S("Upgrade Slots").."]"
|
||||
or "")
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
formspec = formspec..
|
||||
mcl_formspec.get_itemslot_bg(3,1,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(5,1,1,1)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
|
||||
-- upgrade
|
||||
(def.upgrade and
|
||||
mcl_formspec.get_itemslot_bg(3.5,3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(4.5,3,1,1)
|
||||
or "")
|
||||
else
|
||||
formspec = formspec..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
end
|
||||
|
||||
-- listrings
|
||||
formspec = formspec..
|
||||
"listring[context;dst]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"..
|
||||
(def.upgrade and
|
||||
"listring[context;upgrade1]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;upgrade2]"..
|
||||
"listring[current_player;main]"
|
||||
or "")
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Generate formspec with power meter
|
||||
--
|
||||
local function get_formspec(charge_ratio, channel)
|
||||
return formspec .. "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:" ..
|
||||
math.floor(charge_ratio * 100) .. ":technic_power_meter_fg.png]" ..
|
||||
(digilines_path and
|
||||
("field[0.3,4;2.2,1;channel;"..S("Digiline Channel")..";${channel}]"..
|
||||
"button[2,3.7;1,1;setchannel;"..S("Save").."]") or "")
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Update fields not affecting internal network calculations and behavior in any way
|
||||
--
|
||||
local function update_node(pos, update_formspec)
|
||||
-- Read metadata and calculate actual values based on upgrades
|
||||
local meta = minetest.get_meta(pos)
|
||||
local current_charge = meta:get_int("internal_EU_charge")
|
||||
local EU_upgrade = 0
|
||||
if def.upgrade then
|
||||
EU_upgrade = technic.handle_machine_upgrades(meta)
|
||||
end
|
||||
local max_charge = def.max_charge * (1 + EU_upgrade / 10)
|
||||
-- Select node textures
|
||||
local charge_ratio = current_charge / max_charge
|
||||
local charge_count = math.ceil(charge_ratio * 8)
|
||||
charge_count = math.min(charge_count, 8)
|
||||
charge_count = math.max(charge_count, 0)
|
||||
local last_count = meta:get_float("last_side_shown")
|
||||
if charge_count ~= last_count then
|
||||
technic.swap_node(pos, nodename .. charge_count)
|
||||
meta:set_float("last_side_shown", charge_count)
|
||||
end
|
||||
-- Update formspec and infotext
|
||||
local eu_input = meta:get_int(tier.."_EU_input")
|
||||
local infotext = S("@1 Battery Box: @2 / @3", tier,
|
||||
technic.EU_string(current_charge), technic.EU_string(max_charge))
|
||||
if eu_input == 0 then
|
||||
infotext = S("@1 Idle", infotext)
|
||||
end
|
||||
meta:set_string("infotext", infotext)
|
||||
if update_formspec then
|
||||
local channel = meta:get_string("channel")
|
||||
meta:set_string("formspec", get_formspec(charge_ratio, channel))
|
||||
end
|
||||
end
|
||||
|
||||
local function get_tool(inventory, listname)
|
||||
-- Get itemstack and check if it is registered tool
|
||||
if inventory:is_empty(listname) then
|
||||
return
|
||||
end
|
||||
-- Get itemstack and check if it is registered tool
|
||||
local toolstack = inventory:get_stack(listname, 1)
|
||||
local tooldef = toolstack:get_definition()
|
||||
if not tooldef.technic_max_charge then
|
||||
return
|
||||
end
|
||||
return toolstack, tooldef
|
||||
end
|
||||
|
||||
local function charge_tools(meta, batt_charge, charge_step)
|
||||
-- Get tool metadata
|
||||
local inv = meta:get_inventory()
|
||||
local toolstack, tooldef = get_tool(inv, "src")
|
||||
if not toolstack then
|
||||
return batt_charge, false
|
||||
end
|
||||
-- Do the charging
|
||||
local charge = tooldef.technic_get_charge(toolstack)
|
||||
if charge >= tooldef.technic_max_charge then
|
||||
return batt_charge, true
|
||||
elseif batt_charge <= 0 then
|
||||
return batt_charge, false
|
||||
end
|
||||
local oldcharge = charge
|
||||
charge_step = math.min(charge_step, batt_charge, tooldef.technic_max_charge - charge)
|
||||
charge = charge + charge_step
|
||||
if charge ~= oldcharge then
|
||||
tooldef.technic_set_charge(toolstack, charge)
|
||||
inv:set_stack("src", 1, toolstack)
|
||||
end
|
||||
return batt_charge - charge_step, (charge == tooldef.technic_max_charge)
|
||||
end
|
||||
|
||||
local function discharge_tools(meta, batt_charge, charge_step, batt_max_charge)
|
||||
-- Get tool metadata
|
||||
local inv = meta:get_inventory()
|
||||
local toolstack, tooldef = get_tool(inv, "dst")
|
||||
if not toolstack then
|
||||
return batt_charge, false
|
||||
end
|
||||
-- Do the discharging
|
||||
local charge = tooldef.technic_get_charge(toolstack)
|
||||
if charge <= 0 then
|
||||
return batt_charge, true
|
||||
elseif batt_charge >= batt_max_charge then
|
||||
return batt_charge, false
|
||||
end
|
||||
local oldcharge = charge
|
||||
charge_step = math.min(charge_step, batt_max_charge - batt_charge, charge)
|
||||
charge = charge - charge_step
|
||||
if charge ~= oldcharge then
|
||||
tooldef.technic_set_charge(toolstack, charge)
|
||||
inv:set_stack("dst", 1, toolstack)
|
||||
end
|
||||
return batt_charge + charge_step, (charge == 0)
|
||||
end
|
||||
|
||||
local function run(pos, node, run_state, network)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local eu_input = meta:get_int(tier.."_EU_input")
|
||||
local current_charge = meta:get_int("internal_EU_charge")
|
||||
|
||||
local EU_upgrade, tube_upgrade = 0, 0
|
||||
if def.upgrade then
|
||||
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
|
||||
end
|
||||
local max_charge = def.max_charge * (1 + EU_upgrade / 10)
|
||||
|
||||
-- Charge/discharge the battery with the input EUs
|
||||
if eu_input >= 0 then
|
||||
current_charge = math.min(current_charge + eu_input, max_charge)
|
||||
else
|
||||
current_charge = math.max(current_charge + eu_input, 0)
|
||||
end
|
||||
|
||||
-- Charging/discharging tools here
|
||||
local tool_full, tool_empty
|
||||
current_charge, tool_full = charge_tools(meta, current_charge, def.charge_step)
|
||||
current_charge, tool_empty = discharge_tools(meta, current_charge, def.discharge_step, max_charge)
|
||||
|
||||
if def.tube and (tool_full or tool_empty) then
|
||||
technic.handle_machine_pipeworks(pos, tube_upgrade, function(pos2, x_velocity, z_velocity)
|
||||
if tool_full then
|
||||
technic.send_items(pos2, x_velocity, z_velocity, "src")
|
||||
elseif tool_empty then
|
||||
technic.send_items(pos2, x_velocity, z_velocity, "dst")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- We allow batteries to charge on less than the demand
|
||||
local supply = math.min(def.discharge_rate, current_charge)
|
||||
local demand = math.min(def.charge_rate, max_charge - current_charge)
|
||||
network:update_battery(current_charge, max_charge, supply, demand)
|
||||
|
||||
meta:set_int(tier.."_EU_demand", demand)
|
||||
meta:set_int(tier.."_EU_supply", supply)
|
||||
meta:set_int("internal_EU_charge", current_charge)
|
||||
meta:set_int("internal_EU_charge_max", max_charge)
|
||||
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
if not timer:is_started() then
|
||||
timer:start(2)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_timer(pos, elapsed)
|
||||
if not technic.pos2network(pos) then return end
|
||||
update_node(pos)
|
||||
return true
|
||||
end
|
||||
|
||||
for i = 0, 8 do
|
||||
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, ["technic_"..ltier]=1, axey=2, handy=1}
|
||||
if i ~= 0 then
|
||||
groups.not_in_creative_inventory = 1
|
||||
end
|
||||
|
||||
if def.tube then
|
||||
groups.tubedevice = 1
|
||||
groups.tubedevice_receiver = 1
|
||||
end
|
||||
|
||||
local top_tex = texture_prefix.."_top.png"..tube_entry
|
||||
local front_tex = texture_prefix.."_front.png^technic_power_meter"..i..".png"
|
||||
local side_tex = texture_prefix.."_side.png"..tube_entry
|
||||
local bottom_tex = texture_prefix.."_bottom.png"..cable_entry
|
||||
if ltier == "lv" then
|
||||
top_tex = texture_prefix.."_top.png"
|
||||
front_tex = texture_prefix.."_side.png^technic_power_meter"..i..".png"
|
||||
side_tex = texture_prefix.."_side.png^technic_power_meter"..i..".png"
|
||||
end
|
||||
|
||||
minetest.register_node(colon..nodename..i, {
|
||||
description = S("@1 Battery Box", S(tier)),
|
||||
tiles = {
|
||||
top_tex,
|
||||
bottom_tex,
|
||||
side_tex,
|
||||
side_tex,
|
||||
side_tex,
|
||||
front_tex},
|
||||
groups = groups,
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom"},
|
||||
tube = def.tube and tube or nil,
|
||||
paramtype2 = "facedir",
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
drop = "technic:"..ltier.."_battery_box0",
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("@1 Battery Box", S(tier)))
|
||||
meta:set_int(tier.."_EU_demand", 0)
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
meta:set_int(tier.."_EU_input", 0)
|
||||
meta:set_float("internal_EU_charge", 0)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", 1)
|
||||
inv:set_size("upgrade1", 1)
|
||||
inv:set_size("upgrade2", 1)
|
||||
update_node(pos, true)
|
||||
end,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
technic_run = run,
|
||||
on_timer = on_timer,
|
||||
on_rightclick = function(pos) update_node(pos, true) end,
|
||||
on_rotate = function(pos, node, user, mode, new_param2)
|
||||
if mode ~= 1 then
|
||||
return false
|
||||
end
|
||||
end,
|
||||
after_place_node = def.tube and pipeworks.after_place,
|
||||
after_dig_node = technic.machine_after_dig_node,
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if fields.quit then
|
||||
return
|
||||
end
|
||||
local playername = player:get_player_name()
|
||||
if minetest.is_protected(pos, playername) then
|
||||
minetest.record_protection_violation(pos, playername)
|
||||
return
|
||||
elseif fields.setchannel then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("channel", fields.channel or "")
|
||||
update_node(pos, true)
|
||||
end
|
||||
end,
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function() end
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function(pos, node, channel, msg)
|
||||
if msg ~= "GET" and msg ~= "get" then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
local inv = meta:get_inventory()
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
demand = meta:get_int(tier.."_EU_demand"),
|
||||
supply = meta:get_int(tier.."_EU_supply"),
|
||||
input = meta:get_int(tier.."_EU_input"),
|
||||
charge = meta:get_int("internal_EU_charge"),
|
||||
max_charge = def.max_charge * (1 + technic.handle_machine_upgrades(meta) / 10),
|
||||
src = inv:get_stack("src", 1):to_table(),
|
||||
dst = inv:get_stack("dst", 1):to_table(),
|
||||
upgrade1 = inv:get_stack("upgrade1", 1):to_table(),
|
||||
upgrade2 = inv:get_stack("upgrade2", 1):to_table()
|
||||
})
|
||||
end
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
-- Register as a battery type
|
||||
-- Battery type machines function as power reservoirs and can both receive and give back power
|
||||
for i = 0, 8 do
|
||||
technic.register_machine(tier, nodename..i, technic.battery)
|
||||
end
|
||||
|
||||
end -- End registration
|
162
mods/technic_plus_beta/technic/machines/register/cables.lua
Normal file
162
mods/technic_plus_beta/technic/machines/register/cables.lua
Normal file
|
@ -0,0 +1,162 @@
|
|||
|
||||
local cable_tier = {}
|
||||
|
||||
function technic.is_tier_cable(nodename, tier)
|
||||
return cable_tier[nodename] == tier
|
||||
end
|
||||
|
||||
function technic.get_cable_tier(nodename)
|
||||
return cable_tier[nodename]
|
||||
end
|
||||
|
||||
function technic.register_cable_tier(name, tier)
|
||||
assert(technic.machines[tier], "Tier does not exist")
|
||||
assert(type(name) == "string", "Invalid node name")
|
||||
|
||||
cable_tier[name] = tier
|
||||
end
|
||||
|
||||
local function item_place_override_node(itemstack, placer, pointed, node)
|
||||
-- Call the default on_place function with a fake itemstack
|
||||
local temp_itemstack = ItemStack(itemstack)
|
||||
temp_itemstack:set_name(node.name)
|
||||
local original_count = temp_itemstack:get_count()
|
||||
temp_itemstack =
|
||||
minetest.item_place(temp_itemstack, placer, pointed, node.param2) or
|
||||
temp_itemstack
|
||||
-- Remove the same number of items from the real itemstack
|
||||
itemstack:take_item(original_count - temp_itemstack:get_count())
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function cable_defaults(nodename, data)
|
||||
assert(data.tier, "Technic cable registration requires `tier` field")
|
||||
assert(data.size, "Technic cable registration requires `size` field")
|
||||
assert(data.description, "Technic cable registration requires `description` field")
|
||||
|
||||
local def = table.copy(data)
|
||||
local tier = def.tier
|
||||
local ltier = string.lower(tier)
|
||||
local size = def.size
|
||||
|
||||
local place_network_node = technic.place_network_node
|
||||
local remove_network_node = technic.remove_network_node
|
||||
|
||||
def.connects_to = def.connects_to or {
|
||||
"group:technic_"..ltier.."_cable",
|
||||
"group:technic_"..ltier,
|
||||
"group:technic_all_tiers"
|
||||
}
|
||||
def.groups = def.groups or {
|
||||
snappy = 2,
|
||||
choppy = 2,
|
||||
oddly_breakable_by_hand = 2,
|
||||
swordy = 1,
|
||||
axey = 1,
|
||||
handy = 1,
|
||||
["technic_"..ltier.."_cable"] = 1
|
||||
}
|
||||
def.is_ground_content = false
|
||||
def.drop = def.drop or nodename
|
||||
def.sounds = def.sounds or technic.sounds.node_sound_wood_defaults()
|
||||
def.on_construct = def.on_construct or function(pos) place_network_node(pos, {tier}, nodename) end
|
||||
def.on_destruct = def.on_destruct or function(pos) remove_network_node(pos, {tier}, nodename) end
|
||||
def.paramtype = def.paramtype or "light"
|
||||
def.sunlight_propagates = not (def.sunlight_propagates == false and true)
|
||||
def.drawtype = def.drawtype or "nodebox"
|
||||
def.node_box = def.node_box or {
|
||||
type = "connected",
|
||||
fixed = {-size, -size, -size, size, size, size},
|
||||
connect_top = {-size, -size, -size, size, 0.5, size}, -- y+
|
||||
connect_bottom = {-size, -0.5, -size, size, size, size}, -- y-
|
||||
connect_front = {-size, -size, -0.5, size, size, size}, -- z-
|
||||
connect_back = {-size, -size, size, size, size, 0.5 }, -- z+
|
||||
connect_left = {-0.5, -size, -size, size, size, size}, -- x-
|
||||
connect_right = {-size, -size, -size, 0.5, size, size}, -- x+
|
||||
}
|
||||
return def
|
||||
end
|
||||
|
||||
function technic.register_cable_plate(nodename, data)
|
||||
local xyz = {"x","y","z"}
|
||||
local notconnects = {"left", "bottom", "front", "right", "top", "back"}
|
||||
local texture_basename = nodename:gsub(":", "_")
|
||||
for i = 1, 6 do
|
||||
-- Merge defaults and register cable plate
|
||||
local def = cable_defaults(nodename.."_"..i, data)
|
||||
local size = def.size
|
||||
def.tiles = def.tiles or {texture_basename..".png"}
|
||||
def.drop = nodename.."_1"
|
||||
def.node_box.fixed = {
|
||||
{-size, -size, -size, size, size, size},
|
||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
|
||||
}
|
||||
def.node_box.fixed[1][i] = 7/16 * (i-3.5)/math.abs(i-3.5)
|
||||
def.node_box.fixed[2][(i + 2) % 6 + 1] = 3/8 * (i-3.5)/math.abs(i-3.5)
|
||||
def.node_box["connect_"..notconnects[i]] = nil
|
||||
if i == 1 then
|
||||
def.on_place = function(itemstack, placer, pointed_thing)
|
||||
local count = 0
|
||||
for axis in pairs(xyz) do
|
||||
count = count + (pointed_thing.under[axis] == pointed_thing.above[axis] and 0 or 1)
|
||||
if count > 1 then
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
local pointed_thing_diff = vector.direction(pointed_thing.under, pointed_thing.above)
|
||||
local index = pointed_thing_diff.x + (pointed_thing_diff.y*2) + (pointed_thing_diff.z*3)
|
||||
local num = index < 0 and -index + 3 or index
|
||||
local crtl = placer:get_player_control()
|
||||
if (crtl.aux1 or crtl.sneak) and not (crtl.aux1 and crtl.sneak) and index ~= 0 then
|
||||
local fine_pointed = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
|
||||
fine_pointed = vector.direction(pointed_thing.above,fine_pointed)
|
||||
fine_pointed[xyz[index < 0 and -index or index]] = nil
|
||||
local key_a, a = next(fine_pointed)
|
||||
local key_b, b = next(fine_pointed, key_a)
|
||||
local far_key = math.abs(a) > math.abs(b) and key_a or key_b
|
||||
local far = fine_pointed[far_key]
|
||||
-- Plate facing
|
||||
-- X pair floor +X 4 -X 1 -> Z pair, Y pair
|
||||
-- Y pair floor +Y 5 -Y 2 -> X pair, Z pair
|
||||
-- Z pair floor +Z 6 -Z 3 -> X pair, Y pair
|
||||
if math.abs(far) < 0.3 then
|
||||
num = num < 4 and num + 3 or num - 3
|
||||
elseif far_key == "x" then
|
||||
num = far < 0 and 1 or 4
|
||||
elseif far_key == "y" then
|
||||
num = far < 0 and 2 or 5
|
||||
else
|
||||
num = far < 0 and 3 or 6
|
||||
end
|
||||
end
|
||||
local node = {name = nodename.."_"..(num ~= 0 and num or 1)}
|
||||
return item_place_override_node(itemstack, placer, pointed_thing, node)
|
||||
end
|
||||
else
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
def._mcl_blast_resistance = 1
|
||||
def._mcl_hardness = 0.8
|
||||
end
|
||||
def.on_rotate = function(pos, node, user, mode, new_param2)
|
||||
-- mode 1 is left-click, mode 2 is right-click
|
||||
local dir = mode == 1 and 1 or (mode == 2 and -1 or 0)
|
||||
local num = tonumber(node.name:sub(-1)) + dir - 1
|
||||
minetest.swap_node(pos, {name = nodename.."_"..(num % 6 + 1)})
|
||||
end
|
||||
minetest.register_node(nodename.."_"..i, def)
|
||||
cable_tier[nodename.."_"..i] = def.tier
|
||||
end
|
||||
end
|
||||
|
||||
function technic.register_cable(nodename, data)
|
||||
-- Merge defaults and register cable
|
||||
local def = cable_defaults(nodename, data)
|
||||
local texture_basename = nodename:gsub(":", "_")
|
||||
def.tiles = def.tiles or {texture_basename..".png"}
|
||||
def.inventory_image = def.inventory_image or def.inventory_image ~= false and texture_basename.."_wield.png" or nil
|
||||
def.wield_image = def.wield_image or def.wield_image ~= false and texture_basename.."_wield.png" or nil
|
||||
def._mcl_blast_resistance = 1
|
||||
def._mcl_hardness = 0.8
|
||||
minetest.register_node(nodename, def)
|
||||
cable_tier[nodename] = def.tier
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
technic.register_recipe_type("separating", {
|
||||
description = S("Separating"),
|
||||
icon = "technic_mv_centrifuge_front.png",
|
||||
output_size = 4,
|
||||
})
|
||||
|
||||
function technic.register_separating_recipe(data)
|
||||
data.time = data.time or 10
|
||||
technic.register_recipe("separating", data)
|
||||
end
|
||||
|
||||
local recipes = {
|
||||
{ "technic:bronze_dust 8", "technic:copper_dust 7", "technic:tin_dust" },
|
||||
{ "technic:stainless_steel_dust 5", "technic:wrought_iron_dust 4", "technic:chromium_dust" },
|
||||
{ "technic:brass_dust 3", "technic:copper_dust 2", "technic:zinc_dust" },
|
||||
{ "technic:chernobylite_dust", mat.sand, "technic:uranium3_dust" },
|
||||
{ mat.dirt.." 4", mat.sand, mat.gravel, mat.clay_lump.." 4" },
|
||||
}
|
||||
|
||||
local function uranium_dust(p)
|
||||
return "technic:uranium"..(p == 7 and "" or p).."_dust"
|
||||
end
|
||||
for p = 1, 34 do
|
||||
table.insert(recipes, { uranium_dust(p).." 2", uranium_dust(p-1), uranium_dust(p+1) })
|
||||
end
|
||||
|
||||
if minetest.get_modpath("bushes_classic") then
|
||||
for _, berry in ipairs({ "blackberry", "blueberry", "gooseberry", "raspberry", "strawberry" }) do
|
||||
table.insert(recipes, { "bushes:"..berry.."_bush", mat.stick.." 20", "bushes:"..berry.." 4" })
|
||||
end
|
||||
end
|
||||
|
||||
if minetest.get_modpath("farming") or minetest.get_modpath("mcl_farming") then
|
||||
if minetest.get_modpath("cottages") then
|
||||
-- work as a mechanized threshing floor
|
||||
table.insert(recipes, { "farming:wheat", "farming:seed_wheat", "cottages:straw_mat" })
|
||||
table.insert(recipes, { "farming:barley", "farming:seed_barley", "cottages:straw_mat" })
|
||||
else
|
||||
-- work in a less fancy and less efficient manner
|
||||
table.insert(recipes, { mat.wheat.." 4", mat.seed_wheat.." 3", mat.dry_shrub })
|
||||
table.insert(recipes, { "farming:barley 4", "farming:seed_barley 3", mat.dry_shrub })
|
||||
end
|
||||
end
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_separating_recipe({ input = { data[1] }, output = { data[2], data[3], data[4] } })
|
||||
end
|
220
mods/technic_plus_beta/technic/machines/register/common.lua
Normal file
220
mods/technic_plus_beta/technic/machines/register/common.lua
Normal file
|
@ -0,0 +1,220 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
-- handles the machine upgrades every tick
|
||||
function technic.handle_machine_upgrades(meta)
|
||||
-- Get the names of the upgrades
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
local srcstack = inv:get_stack("upgrade1", 1)
|
||||
local upg_item1 = srcstack and srcstack:get_name()
|
||||
|
||||
srcstack = inv:get_stack("upgrade2", 1)
|
||||
local upg_item2 = srcstack and srcstack:get_name()
|
||||
|
||||
-- Save some power by installing battery upgrades.
|
||||
-- Tube loading speed can be upgraded using control logic units.
|
||||
local EU_upgrade = 0
|
||||
local tube_upgrade = 0
|
||||
|
||||
if upg_item1 == "technic:control_logic_unit" then
|
||||
tube_upgrade = tube_upgrade + 1
|
||||
elseif upg_item1 == "technic:battery" then
|
||||
EU_upgrade = EU_upgrade + 1
|
||||
end
|
||||
|
||||
if upg_item2 == "technic:control_logic_unit" then
|
||||
tube_upgrade = tube_upgrade + 1
|
||||
elseif upg_item2 == "technic:battery" then
|
||||
EU_upgrade = EU_upgrade + 1
|
||||
end
|
||||
|
||||
return EU_upgrade, tube_upgrade
|
||||
end
|
||||
|
||||
-- handles the machine upgrades when set or removed
|
||||
local function on_machine_upgrade(meta, stack)
|
||||
local stack_name = stack:get_name()
|
||||
if stack_name == mat.chest then
|
||||
meta:set_int("public", 1)
|
||||
return 1
|
||||
elseif stack_name ~= "technic:control_logic_unit"
|
||||
and stack_name ~= "technic:battery" then
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
-- something is about to be removed
|
||||
local function on_machine_downgrade(meta, stack, list)
|
||||
if stack:get_name() == mat.chest then
|
||||
local inv = meta:get_inventory()
|
||||
local upg1, upg2 = inv:get_stack("upgrade1", 1), inv:get_stack("upgrade2", 1)
|
||||
|
||||
-- only set 0 if theres not a nother chest in the other list too
|
||||
if (not upg1 or not upg2 or upg1:get_name() ~= upg2:get_name()) then
|
||||
meta:set_int("public", 0)
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
|
||||
function technic.send_items(pos, x_velocity, z_velocity, output_name)
|
||||
-- Send items on their way in the pipe system.
|
||||
if output_name == nil then
|
||||
output_name = "dst"
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local i = 0
|
||||
for _, stack in ipairs(inv:get_list(output_name)) do
|
||||
i = i + 1
|
||||
if stack then
|
||||
local item0 = stack:to_table()
|
||||
if item0 then
|
||||
item0["count"] = 1
|
||||
technic.tube_inject_item(pos, pos, vector.new(x_velocity, 0, z_velocity), item0)
|
||||
stack:take_item(1)
|
||||
inv:set_stack(output_name, i, stack)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function technic.handle_machine_pipeworks(pos, tube_upgrade, send_function)
|
||||
if send_function == nil then
|
||||
send_function = technic.send_items
|
||||
end
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local pos1 = vector.new(pos)
|
||||
local x_velocity = 0
|
||||
local z_velocity = 0
|
||||
|
||||
-- Output is on the left side of the furnace
|
||||
if node.param2 == 3 then pos1.z = pos1.z - 1 z_velocity = -1 end
|
||||
if node.param2 == 2 then pos1.x = pos1.x - 1 x_velocity = -1 end
|
||||
if node.param2 == 1 then pos1.z = pos1.z + 1 z_velocity = 1 end
|
||||
if node.param2 == 0 then pos1.x = pos1.x + 1 x_velocity = 1 end
|
||||
|
||||
local output_tube_connected = false
|
||||
local node1 = minetest.get_node(pos1)
|
||||
if minetest.get_item_group(node1.name, "tubedevice") > 0 then
|
||||
output_tube_connected = true
|
||||
end
|
||||
local tube_time = meta:get_int("tube_time") + tube_upgrade
|
||||
if tube_time >= 2 then
|
||||
tube_time = 0
|
||||
if output_tube_connected then
|
||||
send_function(pos, x_velocity, z_velocity)
|
||||
end
|
||||
end
|
||||
meta:set_int("tube_time", tube_time)
|
||||
end
|
||||
|
||||
function technic.machine_can_dig(pos, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("src") or not inv:is_empty("dst") or not inv:is_empty("fuel") then
|
||||
if player then
|
||||
minetest.chat_send_player(player:get_player_name(),
|
||||
S("Machine cannot be removed because it is not empty"))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function technic.machine_after_dig_node(pos, oldnode, oldmetadata, player)
|
||||
if oldmetadata.inventory then
|
||||
if oldmetadata.inventory.upgrade1 and oldmetadata.inventory.upgrade1[1] then
|
||||
local stack = ItemStack(oldmetadata.inventory.upgrade1[1])
|
||||
if not stack:is_empty() then
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
if oldmetadata.inventory.upgrade2 and oldmetadata.inventory.upgrade2[1] then
|
||||
local stack = ItemStack(oldmetadata.inventory.upgrade2[1])
|
||||
if not stack:is_empty() then
|
||||
minetest.add_item(pos, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[oldnode.name].tube then
|
||||
pipeworks.after_dig(pos, oldnode, oldmetadata, player)
|
||||
end
|
||||
end
|
||||
|
||||
local function inv_change(pos, player, count, from_list, to_list, stack)
|
||||
local playername = player:get_player_name()
|
||||
local meta = minetest.get_meta(pos);
|
||||
local public = (meta:get_int("public") == 1)
|
||||
local to_upgrade = to_list == "upgrade1" or to_list == "upgrade2"
|
||||
local from_upgrade = from_list == "upgrade1" or from_list == "upgrade2"
|
||||
|
||||
if (not public or to_upgrade or from_upgrade) and minetest.is_protected(pos, playername) then
|
||||
minetest.chat_send_player(playername, S("Inventory move disallowed due to protection"))
|
||||
return 0
|
||||
end
|
||||
if to_upgrade then
|
||||
-- only place a single item into it, if it's empty
|
||||
local empty = meta:get_inventory():is_empty(to_list)
|
||||
if empty then
|
||||
return on_machine_upgrade(meta, stack)
|
||||
end
|
||||
return 0
|
||||
elseif from_upgrade then
|
||||
-- only called on take (not move)
|
||||
on_machine_downgrade(meta, stack, from_list)
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function technic.machine_inventory_put(pos, listname, index, stack, player)
|
||||
return inv_change(pos, player, stack:get_count(), nil, listname, stack)
|
||||
end
|
||||
|
||||
function technic.machine_inventory_take(pos, listname, index, stack, player)
|
||||
return inv_change(pos, player, stack:get_count(), listname, nil, stack)
|
||||
end
|
||||
|
||||
function technic.machine_inventory_move(pos, from_list, from_index,
|
||||
to_list, to_index, count, player)
|
||||
local stack = minetest.get_meta(pos):get_inventory():get_stack(from_list, from_index)
|
||||
return inv_change(pos, player, count, from_list, to_list, stack)
|
||||
end
|
||||
|
||||
function technic.machine_on_inventory_put(pos, listname, index, stack, player)
|
||||
minetest.log("action", string.format("%s puts %s into %s at %s",
|
||||
player:get_player_name(),
|
||||
stack:to_string(),
|
||||
minetest.get_node(pos).name,
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
||||
|
||||
function technic.machine_on_inventory_take(pos, listname, index, stack, player)
|
||||
minetest.log("action", string.format("%s takes %s from %s at %s",
|
||||
player:get_player_name(),
|
||||
stack:to_string(),
|
||||
minetest.get_node(pos).name,
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
||||
|
||||
function technic.machine_on_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local stack = minetest.get_meta(pos):get_inventory():get_stack(to_list, to_index)
|
||||
minetest.log("action", string.format("%s moves %s in %s at %s",
|
||||
player:get_player_name(),
|
||||
stack:to_string(),
|
||||
minetest.get_node(pos).name,
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
local has_mcl = minetest.get_modpath("mcl_core")
|
||||
|
||||
technic.register_recipe_type("compressing", {
|
||||
description = S("Compressing"),
|
||||
icon = "technic_hv_compressor_front.png",
|
||||
})
|
||||
|
||||
function technic.register_compressor_recipe(data)
|
||||
data.time = data.time or 4
|
||||
technic.register_recipe("compressing", data)
|
||||
end
|
||||
|
||||
local recipes = {
|
||||
{mat.snowblock, mat.ice},
|
||||
{mat.sand.." 2", mat.sandstone},
|
||||
{mat.desert_sand.." 2", mat.desert_sandstone},
|
||||
{mat.silver_sand.." 2", mat.silver_sandstone},
|
||||
{mat.desert_sandstone, mat.desert_stone},
|
||||
{"technic:mixed_metal_ingot", "technic:composite_plate"},
|
||||
{mat.copper_ingot.." 5", "technic:copper_plate"},
|
||||
{"technic:coal_dust 4", "technic:graphite"},
|
||||
{"technic:carbon_cloth", "technic:carbon_plate"},
|
||||
{"technic:uranium35_ingot 5", "technic:uranium_fuel"},
|
||||
{"technic:graphite 25", mat.diamond}
|
||||
}
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
-- the density of charcoal is ~1/10 of coal, otherwise it's pure carbon
|
||||
table.insert(recipes, {"ethereal:charcoal_lump 10", mat.coal_lump.." 1"})
|
||||
end
|
||||
|
||||
|
||||
-- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner
|
||||
if not has_mcl then
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"default:sand", "default:sand"},
|
||||
{"default:sand", "default:sand"},
|
||||
},
|
||||
})
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"default:desert_sand", "default:desert_sand"},
|
||||
{"default:desert_sand", "default:desert_sand"},
|
||||
},
|
||||
})
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"default:silver_sand", "default:silver_sand"},
|
||||
{"default:silver_sand", "default:silver_sand"},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_compressor_recipe({input = {data[1]}, output = data[2]})
|
||||
end
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
technic.register_recipe_type("extracting", {
|
||||
description = S("Extracting"),
|
||||
icon = "technic_mv_extractor_front.png",
|
||||
})
|
||||
|
||||
function technic.register_extractor_recipe(data)
|
||||
data.time = data.time or 4
|
||||
technic.register_recipe("extracting", data)
|
||||
end
|
||||
|
||||
if minetest.get_modpath("dye") then
|
||||
-- check if we are using dye or unifieddyes
|
||||
local unifieddyes = minetest.get_modpath("unifieddyes")
|
||||
|
||||
-- register recipes with the same crafting ratios as `dye` provides
|
||||
local dye_recipes = {
|
||||
{"technic:coal_dust", "dye:black 2"},
|
||||
{"default:blueberries", "dye:violet 2"},
|
||||
{"default:grass_1", "dye:green 1"},
|
||||
{"default:dry_shrub", "dye:brown 4"},
|
||||
{"default:junglegrass", "dye:green 2"},
|
||||
{"default:cactus", "dye:green 4"},
|
||||
{"default:coral_green", "dye:green 4"},
|
||||
{"default:coral_pink", "dye:pink 4"},
|
||||
{"default:coral_cyan", "dye:cyan 4"},
|
||||
{"default:coral_brown", "dye:brown 4"},
|
||||
{"default:coral_orange", "dye:orange 4"},
|
||||
{"default:coral_skeleton", "dye:white 8"},
|
||||
{"flowers:chrysanthemum_green", "dye:green 4"},
|
||||
{"flowers:geranium", "dye:blue 4"},
|
||||
{"flowers:dandelion_white", "dye:white 4"},
|
||||
{"flowers:dandelion_yellow", "dye:yellow 4"},
|
||||
{"flowers:tulip", "dye:orange 4"},
|
||||
{"flowers:tulip_black", "dye:black 8"},
|
||||
{"flowers:rose", "dye:red 4"},
|
||||
{"flowers:viola", "dye:violet 4"},
|
||||
{"bushes:blackberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:violet 4"},
|
||||
{"bushes:blueberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:magenta 4"},
|
||||
}
|
||||
|
||||
if minetest.get_modpath("hunger") and minetest.get_modpath("ethereal") then
|
||||
table.insert(dye_recipes, {"ethereal:willow_twig 12", "technic:aspirin_pill"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("farming") then
|
||||
-- Dyes ---
|
||||
-- better recipes for farming's crafting methods (twice the output)
|
||||
table.insert(dye_recipes, {"farming:chili_pepper", "dye:red 4"})
|
||||
table.insert(dye_recipes, {"farming:beans", "dye:green 4"})
|
||||
table.insert(dye_recipes, {"farming:grapes", "dye:violet 4"})
|
||||
table.insert(dye_recipes, {"farming:cocoa_beans", "dye:brown 4"})
|
||||
-- Some extra recipes:
|
||||
table.insert(dye_recipes, {"farming:onion", "dye:yellow 4"})
|
||||
table.insert(dye_recipes, {"farming:blueberries", "dye:blue 4"})
|
||||
table.insert(dye_recipes, {"farming:raspberries", "dye:red 4"})
|
||||
table.insert(dye_recipes, {"farming:blackberry", "dye:violet 4"})
|
||||
-- Himalayan rhubarb root can give yellow dye IRL
|
||||
table.insert(dye_recipes, {"farming:rhubarb", "dye:yellow 4"})
|
||||
-- https://pubmed.ncbi.nlm.nih.gov/25401128
|
||||
-- Biobleaching of industrial important dyes with peroxidase partially purified from garlic
|
||||
table.insert(dye_recipes, {"farming:garlic", "dye:white 2"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
table.insert(dye_recipes, {"ethereal:seaweed", "dye:dark_green 6"})
|
||||
table.insert(dye_recipes, {"ethereal:coral2", "dye:cyan 6"})
|
||||
table.insert(dye_recipes, {"ethereal:coral3", "dye:orange 6"})
|
||||
table.insert(dye_recipes, {"ethereal:coral4", "dye:pink 6"})
|
||||
table.insert(dye_recipes, {"ethereal:coral5", "dye:green 6"})
|
||||
table.insert(dye_recipes, {"ethereal:fern", "dye:dark_green 4"})
|
||||
table.insert(dye_recipes, {"ethereal:snowygrass", "dye:grey 4"})
|
||||
table.insert(dye_recipes, {"ethereal:crystalgrass", "dye:blue 4"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("bakedclay") then
|
||||
table.insert(dye_recipes, {"bakedclay:delphinium", "dye:cyan 8"})
|
||||
table.insert(dye_recipes, {"bakedclay:thistle", "dye:magenta 8"})
|
||||
table.insert(dye_recipes, {"bakedclay:lazarus", "dye:pink 8"})
|
||||
table.insert(dye_recipes, {"bakedclay:mannagrass", "dye:dark_green 8"})
|
||||
end
|
||||
|
||||
|
||||
if minetest.get_modpath("bonemeal") then
|
||||
table.insert(dye_recipes, {"bonemeal:bone", "dye:white 8"})
|
||||
table.insert(dye_recipes, {"bonemeal:bonemeal", "dye:white 4"})
|
||||
end
|
||||
|
||||
for _, data in ipairs(dye_recipes) do
|
||||
technic.register_extractor_recipe({input = {data[1]}, output = data[2]})
|
||||
end
|
||||
|
||||
-- overwrite the existing crafting recipes
|
||||
local dyes = {"white", "red", "yellow", "blue", "violet", "orange"}
|
||||
for _, color in ipairs(dyes) do
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"group:flower,color_"..color}
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "dye:"..color.." 1",
|
||||
recipe = {
|
||||
{"group:flower,color_"..color}
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"group:coal"}
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "dye:black 1",
|
||||
recipe = {
|
||||
{"group:coal"}
|
||||
},
|
||||
})
|
||||
|
||||
if unifieddyes then
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{"default:cactus"}
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "dye:green 1",
|
||||
recipe = {
|
||||
{"default:cactus"}
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
technic.register_recipe_type("freezing", {
|
||||
description = S("Freezing"),
|
||||
icon = "technic_mv_freezer_front.png",
|
||||
})
|
||||
|
||||
function technic.register_freezer_recipe(data)
|
||||
data.time = data.time or 5
|
||||
technic.register_recipe("freezing", data)
|
||||
end
|
||||
|
||||
local recipes = {
|
||||
{mat.bucket_water, { mat.ice, mat.bucket_empty } },
|
||||
{mat.bucket_river_water, { mat.ice, mat.bucket_empty } },
|
||||
{mat.dirt, mat.dirt_with_snow },
|
||||
{mat.bucket_lava, { mat.obsidian, mat.bucket_empty } }
|
||||
}
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_freezer_recipe({input = {data[1]}, output = data[2], hidden = true})
|
||||
end
|
||||
|
294
mods/technic_plus_beta/technic/machines/register/generator.lua
Normal file
294
mods/technic_plus_beta/technic/machines/register/generator.lua
Normal file
|
@ -0,0 +1,294 @@
|
|||
local S = technic.getter
|
||||
|
||||
local fs_helpers = pipeworks.fs_helpers
|
||||
local tube_entry = "^pipeworks_tube_connection_metallic.png"
|
||||
|
||||
local tube = {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:add_item("src", stack)
|
||||
end,
|
||||
can_insert = function(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if meta:get_int("splitstacks") == 1 then
|
||||
stack = stack:peek_item(1)
|
||||
end
|
||||
return inv:room_for_item("src", stack)
|
||||
end,
|
||||
connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
|
||||
}
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,10]" or "size[8,9]"
|
||||
|
||||
local function update_generator_formspec(meta, desc, percent, form_buttons)
|
||||
local generator_formspec = size..
|
||||
"label[0, 0;"..desc.."]"..
|
||||
"list[context;src;3,1;1,1;]"..
|
||||
"listring[context;src]"..
|
||||
"image[4,1;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
||||
(percent)..":default_furnace_fire_fg.png]"..
|
||||
form_buttons
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
generator_formspec = generator_formspec..
|
||||
mcl_formspec.get_itemslot_bg(3,1,1,1)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,5.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,5.5,9,3)..
|
||||
"list[current_player;main;0,8.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,8.74,9,1)..
|
||||
"listring[current_player;main]"
|
||||
else
|
||||
generator_formspec = generator_formspec..
|
||||
"list[current_player;main;0, 5;8, 4;]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
return meta:set_string("formspec", generator_formspec)
|
||||
end
|
||||
|
||||
function technic.register_generator(data)
|
||||
|
||||
local tier = data.tier
|
||||
local ltier = string.lower(tier)
|
||||
|
||||
local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, ["technic_"..ltier]=1, axey=2, handy=1}
|
||||
if data.tube then
|
||||
groups.tubedevice = 1
|
||||
groups.tubedevice_receiver = 1
|
||||
end
|
||||
local active_groups = {not_in_creative_inventory = 1}
|
||||
for k, v in pairs(groups) do active_groups[k] = v end
|
||||
|
||||
local desc = S("Fuel-Fired @1 Generator", S(tier))
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local burn_time = meta:get_int("burn_time")
|
||||
local burn_totaltime = meta:get_int("burn_totaltime")
|
||||
-- If more to burn and the energy produced was used: produce some more
|
||||
if burn_time > 0 then
|
||||
meta:set_int(tier.."_EU_supply", data.supply)
|
||||
burn_time = burn_time - 1
|
||||
meta:set_int("burn_time", burn_time)
|
||||
end
|
||||
-- Burn another piece of fuel
|
||||
if burn_time == 0 then
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("src") then
|
||||
local fuellist = inv:get_list("src")
|
||||
local fuel
|
||||
local afterfuel
|
||||
fuel, afterfuel = minetest.get_craft_result(
|
||||
{method = "fuel", width = 1,
|
||||
items = fuellist})
|
||||
if not fuel or fuel.time == 0 then
|
||||
meta:set_string("infotext", S("@1 Out Of Fuel", desc))
|
||||
technic.swap_node(pos, "technic:"..ltier.."_generator")
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
return
|
||||
end
|
||||
meta:set_int("burn_time", fuel.time)
|
||||
meta:set_int("burn_totaltime", fuel.time)
|
||||
inv:set_stack("src", 1, afterfuel.items[1])
|
||||
technic.swap_node(pos, "technic:"..ltier.."_generator_active")
|
||||
meta:set_int(tier.."_EU_supply", data.supply)
|
||||
else
|
||||
technic.swap_node(pos, "technic:"..ltier.."_generator")
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
end
|
||||
end
|
||||
if burn_totaltime == 0 then burn_totaltime = 1 end
|
||||
local percent = math.floor((burn_time / burn_totaltime) * 100)
|
||||
meta:set_string("infotext", desc.." ("..percent.."%)")
|
||||
|
||||
local form_buttons = ""
|
||||
if ltier ~= "lv" then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
update_generator_formspec(meta, desc, percent, form_buttons)
|
||||
end
|
||||
|
||||
local tentry = tube_entry
|
||||
if ltier == "lv" then tentry = "" end
|
||||
|
||||
minetest.register_node("technic:"..ltier.."_generator", {
|
||||
description = desc,
|
||||
tiles = {
|
||||
"technic_"..ltier.."_generator_top.png"..tentry,
|
||||
"technic_machine_bottom.png"..tentry,
|
||||
"technic_"..ltier.."_generator_side.png"..tentry,
|
||||
"technic_"..ltier.."_generator_side.png"..tentry,
|
||||
"technic_"..ltier.."_generator_side.png"..tentry,
|
||||
"technic_"..ltier.."_generator_front.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = groups,
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom", "back", "left", "right"},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
tube = data.tube and tube or nil,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
meta:set_string("infotext", desc)
|
||||
meta:set_int(data.tier.."_EU_supply", 0)
|
||||
meta:set_int("burn_time", 0)
|
||||
meta:set_int("tube_time", 0)
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
update_generator_formspec(meta, desc, 0, form_buttons)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", 1)
|
||||
end,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
technic_run = run,
|
||||
after_place_node = data.tube and pipeworks.after_place,
|
||||
after_dig_node = technic.machine_after_dig_node,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
local burn_totaltime = meta:get_int("burn_totaltime") or 0
|
||||
local burn_time = meta:get_int("burn_time")
|
||||
local percent = math.floor(burn_time / burn_totaltime * 100)
|
||||
update_generator_formspec(meta, desc, percent, form_buttons)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:"..ltier.."_generator_active", {
|
||||
description = desc,
|
||||
tiles = {
|
||||
"technic_"..ltier.."_generator_top.png"..tube_entry,
|
||||
"technic_machine_bottom.png"..tube_entry,
|
||||
"technic_"..ltier.."_generator_side.png"..tube_entry,
|
||||
"technic_"..ltier.."_generator_side.png"..tube_entry,
|
||||
"technic_"..ltier.."_generator_side.png"..tube_entry,
|
||||
"technic_"..ltier.."_generator_front_active.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = active_groups,
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom"},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
tube = data.tube and tube or nil,
|
||||
drop = "technic:"..ltier.."_generator",
|
||||
can_dig = technic.machine_can_dig,
|
||||
after_dig_node = technic.machine_after_dig_node,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
technic_run = run,
|
||||
technic_on_disable = function(pos, node)
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
timer:start(1)
|
||||
end,
|
||||
on_timer = function(pos)
|
||||
-- Connected back?
|
||||
if technic.get_timeout(tier, pos) > 0 then return false end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
|
||||
local burn_time = meta:get_int("burn_time") or 0
|
||||
|
||||
if burn_time <= 0 then
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
meta:set_int("burn_time", 0)
|
||||
technic.swap_node(pos, "technic:"..ltier.."_generator")
|
||||
return false
|
||||
end
|
||||
|
||||
local burn_totaltime = meta:get_int("burn_totaltime") or 0
|
||||
if burn_totaltime == 0 then burn_totaltime = 1 end
|
||||
burn_time = burn_time - 1
|
||||
meta:set_int("burn_time", burn_time)
|
||||
local percent = math.floor(burn_time / burn_totaltime * 100)
|
||||
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
update_generator_formspec(meta, desc, percent, form_buttons)
|
||||
return true
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
|
||||
local burn_totaltime = meta:get_int("burn_totaltime") or 0
|
||||
local burn_time = meta:get_int("burn_time")
|
||||
local percent = math.floor(burn_time / burn_totaltime * 100)
|
||||
|
||||
update_generator_formspec(meta, desc, percent, form_buttons)
|
||||
end,
|
||||
})
|
||||
|
||||
technic.register_machine(tier, "technic:"..ltier.."_generator", technic.producer)
|
||||
technic.register_machine(tier, "technic:"..ltier.."_generator_active", technic.producer)
|
||||
end
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
technic.register_recipe_type("grinding", {
|
||||
description = S("Grinding"),
|
||||
icon = "technic_hv_grinder_front.png",
|
||||
})
|
||||
|
||||
function technic.register_grinder_recipe(data)
|
||||
data.time = data.time or 3
|
||||
technic.register_recipe("grinding", data)
|
||||
end
|
||||
|
||||
local recipes = {
|
||||
-- Dusts
|
||||
{mat.coal_lump, "technic:coal_dust 2"},
|
||||
{mat.copper_lump, "technic:copper_dust 2"},
|
||||
{mat.desert_stone, mat.desert_sand},
|
||||
{mat.gold_lump, "technic:gold_dust 2"},
|
||||
{mat.iron_lump, "technic:wrought_iron_dust 2"},
|
||||
{mat.tin_lump, "technic:tin_dust 2"},
|
||||
{"technic:chromium_lump", "technic:chromium_dust 2"},
|
||||
{"technic:uranium_lump", "technic:uranium_dust 2"},
|
||||
{"technic:zinc_lump", "technic:zinc_dust 2"},
|
||||
{"technic:lead_lump", "technic:lead_dust 2"},
|
||||
{"technic:sulfur_lump", "technic:sulfur_dust 2"},
|
||||
{mat.stone, "technic:stone_dust"},
|
||||
{mat.sand, "technic:stone_dust"},
|
||||
{mat.desert_sand, "technic:stone_dust"},
|
||||
{mat.silver_sand, "technic:stone_dust"},
|
||||
|
||||
-- Other
|
||||
{mat.cobble, mat.gravel},
|
||||
{mat.gravel, mat.sand},
|
||||
{mat.sandstone, mat.sand.." 2"}, -- reverse recipe can be found in the compressor
|
||||
{mat.desert_sandstone, mat.desert_sand.." 2"}, -- reverse recipe can be found in the compressor
|
||||
{mat.silver_sandstone, mat.silver_sand.." 2"}, -- reverse recipe can be found in the compressor
|
||||
|
||||
{mat.ice, mat.snowblock},
|
||||
}
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
-- the density of charcoal is ~1/10 of coal, otherwise it's the same graphitic carbon
|
||||
table.insert(recipes, {"ethereal:charcoal_lump 5", "technic:coal_dust 1"})
|
||||
end
|
||||
|
||||
-- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe)
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{mat.sandstone}
|
||||
},
|
||||
})
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{mat.desert_sandstone}
|
||||
},
|
||||
})
|
||||
minetest.clear_craft({
|
||||
recipe = {
|
||||
{mat.silver_sandstone}
|
||||
},
|
||||
})
|
||||
|
||||
if minetest.get_modpath("farming") then
|
||||
table.insert(recipes, {mat.seed_wheat, "farming:flour 1"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("moreores") then
|
||||
table.insert(recipes, {"moreores:mithril_lump", "technic:mithril_dust 2"})
|
||||
table.insert(recipes, {"moreores:silver_lump", "technic:silver_dust 2"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
|
||||
table.insert(recipes, {"gloopores:alatro_lump", "technic:alatro_dust 2"})
|
||||
table.insert(recipes, {"gloopores:kalite_lump", "technic:kalite_dust 2"})
|
||||
table.insert(recipes, {"gloopores:arol_lump", "technic:arol_dust 2"})
|
||||
table.insert(recipes, {"gloopores:talinite_lump", "technic:talinite_dust 2"})
|
||||
table.insert(recipes, {"gloopores:akalin_lump", "technic:akalin_dust 2"})
|
||||
end
|
||||
|
||||
if minetest.get_modpath("homedecor") then
|
||||
table.insert(recipes, {"home_decor:brass_ingot", "technic:brass_dust 1"})
|
||||
end
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_grinder_recipe({input = {data[1]}, output = data[2]})
|
||||
end
|
||||
|
||||
-- dusts
|
||||
local function register_dust(name, ingot)
|
||||
local lname = string.lower(name)
|
||||
lname = string.gsub(lname, ' ', '_')
|
||||
minetest.register_craftitem("technic:"..lname.."_dust", {
|
||||
description = S("@1 Dust", S(name)),
|
||||
inventory_image = "technic_"..lname.."_dust.png",
|
||||
})
|
||||
if ingot then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
recipe = "technic:"..lname.."_dust",
|
||||
output = ingot,
|
||||
})
|
||||
technic.register_grinder_recipe({ input = {ingot}, output = "technic:"..lname.."_dust 1" })
|
||||
end
|
||||
end
|
||||
|
||||
-- Sorted alphibeticaly
|
||||
register_dust("Brass", "basic_materials:brass_ingot")
|
||||
register_dust("Bronze", mat.bronze_ingot)
|
||||
register_dust("Carbon Steel", "technic:carbon_steel_ingot")
|
||||
register_dust("Cast Iron", "technic:cast_iron_ingot")
|
||||
register_dust("Chernobylite", "technic:chernobylite_block")
|
||||
register_dust("Chromium", "technic:chromium_ingot")
|
||||
register_dust("Coal", nil)
|
||||
register_dust("Copper", mat.copper_ingot)
|
||||
register_dust("Lead", "technic:lead_ingot")
|
||||
register_dust("Gold", mat.gold_ingot)
|
||||
register_dust("Mithril", mat.mithril_ingot)
|
||||
register_dust("Silver", mat.silver_ingot)
|
||||
register_dust("Stainless Steel", "technic:stainless_steel_ingot")
|
||||
register_dust("Stone", mat.stone)
|
||||
register_dust("Sulfur", nil)
|
||||
register_dust("Tin", mat.tin_ingot)
|
||||
register_dust("Wrought Iron", "technic:wrought_iron_ingot")
|
||||
register_dust("Zinc", "technic:zinc_ingot")
|
||||
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
|
||||
register_dust("Akalin", "glooptest:akalin_ingot")
|
||||
register_dust("Alatro", "glooptest:alatro_ingot")
|
||||
register_dust("Arol", "glooptest:arol_ingot")
|
||||
register_dust("Kalite", nil)
|
||||
register_dust("Talinite", "glooptest:talinite_ingot")
|
||||
end
|
||||
|
||||
for p = 0, 35 do
|
||||
local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
|
||||
local psuffix = p == 7 and "" or p
|
||||
local ingot = "technic:uranium"..psuffix.."_ingot"
|
||||
local dust = "technic:uranium"..psuffix.."_dust"
|
||||
minetest.register_craftitem(dust, {
|
||||
description = S("@1%-Fissile Uranium Dust", string.format("%.1f", p/10)),
|
||||
inventory_image = "technic_uranium_dust.png",
|
||||
on_place_on_ground = minetest.craftitem_place_item,
|
||||
groups = {uranium_dust=1, not_in_creative_inventory=nici},
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
recipe = dust,
|
||||
output = ingot,
|
||||
})
|
||||
technic.register_grinder_recipe({ input = {ingot}, output = dust })
|
||||
end
|
||||
|
||||
local function uranium_dust(p)
|
||||
return "technic:uranium"..(p == 7 and "" or p).."_dust"
|
||||
end
|
||||
for pa = 0, 34 do
|
||||
for pb = pa+1, 35 do
|
||||
local pc = (pa+pb)/2
|
||||
if pc == math.floor(pc) then
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
recipe = { uranium_dust(pa), uranium_dust(pb) },
|
||||
output = uranium_dust(pc).." 2",
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "technic:coal_dust",
|
||||
burntime = 50,
|
||||
})
|
||||
|
||||
if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "technic:kalite_dust",
|
||||
burntime = 37.5,
|
||||
})
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
local S = technic.getter
|
||||
local moretrees = minetest.get_modpath("moretrees")
|
||||
local dye = minetest.get_modpath("dye")
|
||||
local mat = technic.materials
|
||||
|
||||
-- sawdust, the finest wood/tree grinding
|
||||
local sawdust = "technic:sawdust"
|
||||
minetest.register_craftitem(sawdust, {
|
||||
description = S("Sawdust"),
|
||||
inventory_image = "technic_sawdust.png",
|
||||
})
|
||||
minetest.register_craft({ type = "fuel", recipe = sawdust, burntime = 6 })
|
||||
technic.register_compressor_recipe({ input = {sawdust .. " 4"}, output = mat.wood })
|
||||
|
||||
-- tree/wood grindings
|
||||
local function register_tree_grinding(name, tree, wood, extract, grinding_color)
|
||||
local lname = string.lower(name)
|
||||
lname = string.gsub(lname, ' ', '_')
|
||||
local grindings_name = "technic:"..lname.."_grindings"
|
||||
if not minetest.registered_craftitems[grindings_name] then
|
||||
local inventory_image = "technic_"..lname.."_grindings.png"
|
||||
if grinding_color then
|
||||
inventory_image = inventory_image .. "^[colorize:" .. grinding_color
|
||||
end
|
||||
minetest.register_craftitem(grindings_name, {
|
||||
description = S("@1 Grinding", S(name)),
|
||||
inventory_image = inventory_image,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = grindings_name,
|
||||
burntime = 8,
|
||||
})
|
||||
end
|
||||
technic.register_grinder_recipe({ input = { tree }, output = grindings_name .. " 4" })
|
||||
technic.register_grinder_recipe({ input = { grindings_name }, output = sawdust .. " 4" })
|
||||
if wood then
|
||||
technic.register_grinder_recipe({ input = { wood }, output = grindings_name })
|
||||
end
|
||||
if extract then
|
||||
technic.register_extractor_recipe({ input = { grindings_name .. " 4" }, output = extract})
|
||||
technic.register_separating_recipe({
|
||||
input = { grindings_name .. " 4" },
|
||||
output = { sawdust .. " 4", extract }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local rubber_planks = moretrees and "moretrees:rubber_tree_planks"
|
||||
local default_extract = dye and "dye:brown 2"
|
||||
-- https://en.wikipedia.org/wiki/Catechu ancient brown dye from the wood of acacia trees
|
||||
local acacia_extract = dye and "dye:brown 8"
|
||||
|
||||
-- Specific recipes for acacia and rubber trees
|
||||
register_tree_grinding("Acacia", mat.acacia_tree, mat.acacia_wood, acacia_extract)
|
||||
register_tree_grinding("Rubber Tree", "moretrees:rubber_tree_trunk", rubber_planks, "technic:raw_latex 2")
|
||||
register_tree_grinding("Rubber Tree", "moretrees:rubber_tree_trunk_empty", nil, "technic:raw_latex")
|
||||
|
||||
-- Group recipe for all other trees
|
||||
register_tree_grinding("Common Tree", "group:tree", "group:wood", default_extract)
|
26
mods/technic_plus_beta/technic/machines/register/init.lua
Normal file
26
mods/technic_plus_beta/technic/machines/register/init.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
local path = technic.modpath.."/machines/register"
|
||||
|
||||
dofile(path.."/common.lua")
|
||||
|
||||
-- Wiring stuff
|
||||
dofile(path.."/cables.lua")
|
||||
dofile(path.."/battery_box.lua")
|
||||
|
||||
-- Generators
|
||||
dofile(path.."/solar_array.lua")
|
||||
dofile(path.."/generator.lua")
|
||||
|
||||
-- API for machines
|
||||
dofile(path.."/recipes.lua")
|
||||
dofile(path.."/machine_base.lua")
|
||||
|
||||
-- Recipes
|
||||
dofile(path.."/alloy_recipes.lua")
|
||||
dofile(path.."/grinder_recipes.lua")
|
||||
dofile(path.."/extractor_recipes.lua")
|
||||
dofile(path.."/compressor_recipes.lua")
|
||||
dofile(path.."/centrifuge_recipes.lua")
|
||||
dofile(path.."/freezer_recipes.lua")
|
||||
|
||||
-- Multi-Machine Recipes
|
||||
dofile(path.."/grindings.lua")
|
|
@ -0,0 +1,299 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
local fs_helpers = pipeworks.fs_helpers
|
||||
local tube_entry = "^pipeworks_tube_connection_metallic.png"
|
||||
|
||||
function technic.default_can_insert(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if meta:get_int("splitstacks") == 1 then
|
||||
stack = stack:peek_item(1)
|
||||
end
|
||||
return inv:room_for_item("src", stack)
|
||||
end
|
||||
|
||||
function technic.new_default_tube()
|
||||
return {
|
||||
insert_object = function(pos, node, stack, direction)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return inv:add_item("src", stack)
|
||||
end,
|
||||
can_insert = technic.default_can_insert,
|
||||
connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
|
||||
}
|
||||
end
|
||||
|
||||
local connect_default = {"bottom", "back", "left", "right"}
|
||||
|
||||
function technic.register_base_machine(nodename, data)
|
||||
local colon, modname, name, def = technic.register_compat_v1_to_v2(nodename, data)
|
||||
local texture_prefix = modname.."_"..name
|
||||
nodename = modname..":"..name
|
||||
|
||||
local typename = def.typename
|
||||
local input_size = technic.recipes[typename].input_size
|
||||
local tier = def.tier
|
||||
local ltier = string.lower(tier)
|
||||
local infotext_idle = S("@1 Idle", def.description)
|
||||
local infotext_active = S("@1 Active", def.description)
|
||||
local infotext_unpowered = S("@1 Unpowered", def.description)
|
||||
|
||||
local groups = {cracky = 2, technic_machine = 1, ["technic_"..ltier] = 1, pickaxey=2}
|
||||
if def.tube then
|
||||
groups.tubedevice = 1
|
||||
groups.tubedevice_receiver = 1
|
||||
end
|
||||
local active_groups = table.copy(groups)
|
||||
active_groups.not_in_creative_inventory = 1
|
||||
|
||||
local size = minetest.get_modpath("mcl_formspec") and "size[9,10]" or "size[8,9]"
|
||||
local formspec =
|
||||
size..
|
||||
"list[context;src;"..(4-input_size)..",1;"..input_size..",1;]"..
|
||||
"list[context;dst;5,1;2,2;]"..
|
||||
"label[0,0;"..def.description.."]"
|
||||
if def.upgrade then
|
||||
formspec = formspec..
|
||||
"list[context;upgrade1;1,3;1,1;]"..
|
||||
"list[context;upgrade2;2,3;1,1;]"..
|
||||
"label[1,4;"..S("Upgrade Slots").."]"
|
||||
end
|
||||
|
||||
if minetest.get_modpath("mcl_formspec") then
|
||||
formspec = formspec..
|
||||
mcl_formspec.get_itemslot_bg(4-input_size,1,input_size,1)..
|
||||
mcl_formspec.get_itemslot_bg(5,1,2,2)..
|
||||
-- player inventory
|
||||
"list[current_player;main;0,5.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,5.5,9,3)..
|
||||
"list[current_player;main;0,8.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,8.74,9,1)
|
||||
if def.upgrade then
|
||||
formspec = formspec..
|
||||
mcl_formspec.get_itemslot_bg(1,3,1,1)..
|
||||
mcl_formspec.get_itemslot_bg(2,3,1,1)
|
||||
end
|
||||
else
|
||||
formspec = formspec..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
end
|
||||
|
||||
-- listrings
|
||||
formspec = formspec..
|
||||
"listring[context;dst]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"
|
||||
if def.upgrade then
|
||||
formspec = formspec..
|
||||
"listring[context;upgrade1]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;upgrade2]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local tube = technic.new_default_tube()
|
||||
if def.can_insert then
|
||||
tube.can_insert = def.can_insert
|
||||
end
|
||||
if def.insert_object then
|
||||
tube.insert_object = def.insert_object
|
||||
end
|
||||
|
||||
local update_node = function(pos, meta, newnode, infotext, demand, src_time)
|
||||
technic.swap_node(pos, newnode)
|
||||
meta:set_string("infotext", infotext)
|
||||
meta:set_int(tier.."_EU_demand", demand)
|
||||
meta:set_int("src_time", src_time)
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local eu_input = meta:get_int(tier.."_EU_input")
|
||||
local machine_demand = def.demand
|
||||
|
||||
-- Setup meta def if it does not exist.
|
||||
if not eu_input then
|
||||
meta:set_int(tier.."_EU_demand", machine_demand[1])
|
||||
meta:set_int(tier.."_EU_input", 0)
|
||||
return
|
||||
end
|
||||
|
||||
local EU_upgrade, tube_upgrade = 0, 0
|
||||
if def.upgrade then
|
||||
EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
|
||||
end
|
||||
if def.tube then
|
||||
technic.handle_machine_pipeworks(pos, tube_upgrade)
|
||||
end
|
||||
|
||||
local inv = meta:get_inventory()
|
||||
local demand = machine_demand[EU_upgrade+1]
|
||||
local powered = eu_input >= demand
|
||||
local src_time = meta:get_int("src_time")
|
||||
if powered then
|
||||
src_time = src_time + math.floor(def.speed * 10 + 0.5)
|
||||
end
|
||||
while true do
|
||||
local recipe = inv:get_list("src") and technic.get_recipe(typename, inv:get_list("src"))
|
||||
if not recipe then
|
||||
update_node(pos, meta, nodename, infotext_idle, 0, 0)
|
||||
return
|
||||
end
|
||||
local recipe_time = math.floor(recipe.time * 10 + 0.5)
|
||||
if src_time < recipe_time then
|
||||
if powered then
|
||||
local infotext = infotext_active .. "\n" .. S("Demand: @1", technic.EU_string(demand))
|
||||
update_node(pos, meta, nodename.."_active", infotext, demand, src_time)
|
||||
else
|
||||
update_node(pos, meta, nodename, infotext_unpowered, demand, src_time)
|
||||
end
|
||||
return
|
||||
elseif not technic.process_recipe(recipe, inv) then
|
||||
update_node(pos, meta, nodename, infotext_idle, 0, recipe_time)
|
||||
return
|
||||
end
|
||||
src_time = src_time - recipe_time
|
||||
end
|
||||
end
|
||||
|
||||
local tentry = tube_entry
|
||||
if ltier == "lv" then
|
||||
tentry = ""
|
||||
end
|
||||
|
||||
minetest.register_node(colon..nodename, {
|
||||
description = def.description,
|
||||
tiles = {
|
||||
texture_prefix.."_top.png"..tentry,
|
||||
texture_prefix.."_bottom.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_front.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = groups,
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
tube = def.tube and tube or nil,
|
||||
connect_sides = def.connect_sides or connect_default,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
|
||||
meta:set_string("infotext", def.description)
|
||||
meta:set_int("tube_time", 0)
|
||||
meta:set_string("formspec", formspec..form_buttons)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", input_size)
|
||||
inv:set_size("dst", 4)
|
||||
inv:set_size("upgrade1", 1)
|
||||
inv:set_size("upgrade2", 1)
|
||||
end,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
technic_run = run,
|
||||
after_place_node = def.tube and pipeworks.after_place,
|
||||
after_dig_node = technic.machine_after_dig_node,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if fields.quit then return end
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
meta:set_string("formspec", formspec..form_buttons)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node(colon..nodename.."_active",{
|
||||
description = def.description,
|
||||
tiles = {
|
||||
texture_prefix.."_top.png"..tentry,
|
||||
texture_prefix.."_bottom.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_side.png"..tentry,
|
||||
texture_prefix.."_front_active.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
drop = nodename,
|
||||
groups = active_groups,
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = def.connect_sides or connect_default,
|
||||
legacy_facedir_simple = true,
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
tube = def.tube and tube or nil,
|
||||
can_dig = technic.machine_can_dig,
|
||||
allow_metadata_inventory_put = technic.machine_inventory_put,
|
||||
allow_metadata_inventory_take = technic.machine_inventory_take,
|
||||
allow_metadata_inventory_move = technic.machine_inventory_move,
|
||||
on_metadata_inventory_move = technic.machine_on_inventory_move,
|
||||
on_metadata_inventory_put = technic.machine_on_inventory_put,
|
||||
on_metadata_inventory_take = technic.machine_on_inventory_take,
|
||||
technic_run = run,
|
||||
technic_disabled_machine_name = nodename,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if fields.quit then return end
|
||||
if not pipeworks.may_configure(pos, sender) then return end
|
||||
fs_helpers.on_receive_fields(pos, fields)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local form_buttons = ""
|
||||
if not string.find(node.name, ":lv_") then
|
||||
form_buttons = fs_helpers.cycling_button(
|
||||
meta,
|
||||
pipeworks.button_base,
|
||||
"splitstacks",
|
||||
{
|
||||
pipeworks.button_off,
|
||||
pipeworks.button_on
|
||||
}
|
||||
)..pipeworks.button_label
|
||||
end
|
||||
meta:set_string("formspec", formspec..form_buttons)
|
||||
end,
|
||||
})
|
||||
|
||||
technic.register_machine(tier, nodename, technic.receiver)
|
||||
technic.register_machine(tier, nodename.."_active", technic.receiver)
|
||||
|
||||
end -- End registration
|
||||
|
263
mods/technic_plus_beta/technic/machines/register/recipes.lua
Normal file
263
mods/technic_plus_beta/technic/machines/register/recipes.lua
Normal file
|
@ -0,0 +1,263 @@
|
|||
|
||||
local have_ui = minetest.get_modpath("unified_inventory")
|
||||
local have_cg = minetest.get_modpath("craftguide")
|
||||
local have_mcl_cg = minetest.get_modpath("mcl_craftguide")
|
||||
local have_i3 = minetest.get_modpath("i3")
|
||||
|
||||
technic.recipes = {
|
||||
cooking = {input_size = 1, output_size = 1, recipes = {}},
|
||||
}
|
||||
|
||||
local temp_recipes = {} -- Used to store recipes before caching
|
||||
local recipe_cache = {} -- Cache used by technic.get_recipe
|
||||
|
||||
function technic.register_recipe_type(method, data)
|
||||
data = table.copy(data)
|
||||
data.input_size = data.input_size or 1
|
||||
data.output_size = data.output_size or 1
|
||||
data.recipes = {}
|
||||
if have_ui then
|
||||
unified_inventory.register_craft_type(method, {
|
||||
description = data.description,
|
||||
icon = data.icon,
|
||||
width = data.input_size,
|
||||
height = 1,
|
||||
})
|
||||
end
|
||||
if have_cg then
|
||||
craftguide.register_craft_type(method, {
|
||||
description = data.description,
|
||||
icon = data.icon,
|
||||
})
|
||||
end
|
||||
if have_mcl_cg then
|
||||
mcl_craftguide.register_craft_type(method, {
|
||||
description = data.description,
|
||||
icon = data.icon,
|
||||
})
|
||||
end
|
||||
if have_i3 then
|
||||
i3.register_craft_type(method, {
|
||||
description = data.description,
|
||||
icon = data.icon,
|
||||
})
|
||||
end
|
||||
technic.recipes[method] = data
|
||||
end
|
||||
|
||||
function technic.register_recipe(method, data)
|
||||
data.time = data.time or 1
|
||||
data.method = method
|
||||
if type(data.input) == "string" then
|
||||
data.input = {data.input}
|
||||
end
|
||||
if type(data.output) == "string" then
|
||||
data.output = {data.output}
|
||||
end
|
||||
table.insert(temp_recipes, data)
|
||||
end
|
||||
|
||||
local function get_recipe_key(method, items)
|
||||
local t = {}
|
||||
for i, stack in ipairs(items) do
|
||||
t[i] = ItemStack(stack):get_name()
|
||||
end
|
||||
table.sort(t)
|
||||
return method.."/"..table.concat(t, "/")
|
||||
end
|
||||
|
||||
function technic.get_recipe(method, items)
|
||||
local key = get_recipe_key(method, items)
|
||||
local recipe = recipe_cache[key]
|
||||
if not recipe then
|
||||
return
|
||||
end
|
||||
local new_input = {}
|
||||
for i, stack in ipairs(items) do
|
||||
local amount = recipe.input[stack:get_name()]
|
||||
if stack:get_count() < amount then
|
||||
return
|
||||
else
|
||||
new_input[i] = ItemStack(stack)
|
||||
new_input[i]:take_item(amount)
|
||||
end
|
||||
end
|
||||
return {
|
||||
time = recipe.time,
|
||||
new_input = new_input,
|
||||
output = recipe.output
|
||||
}
|
||||
end
|
||||
|
||||
local function add_to_craftguides(recipe)
|
||||
for _, output in ipairs(recipe.output) do
|
||||
if have_ui then
|
||||
unified_inventory.register_craft({
|
||||
type = recipe.method,
|
||||
output = output,
|
||||
items = table.copy(recipe.input),
|
||||
width = 0,
|
||||
})
|
||||
end
|
||||
if have_cg and craftguide.register_craft then
|
||||
craftguide.register_craft({
|
||||
type = recipe.method,
|
||||
result = output,
|
||||
items = {table.concat(recipe.input, ", ")},
|
||||
})
|
||||
end
|
||||
if have_mcl_cg then
|
||||
mcl_craftguide.register_craft({
|
||||
type = recipe.method,
|
||||
output = output,
|
||||
items = table.copy(recipe.input),
|
||||
width = 0,
|
||||
})
|
||||
end
|
||||
if have_i3 then
|
||||
i3.register_craft({
|
||||
type = recipe.method,
|
||||
result = output,
|
||||
items = {table.concat(recipe.input, ", ")},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_items_in_group(group)
|
||||
local items = {}
|
||||
local groups = group:split(",")
|
||||
for name, def in pairs(minetest.registered_items) do
|
||||
local match = true
|
||||
for _,g in pairs(groups) do
|
||||
if not def.groups[g] then
|
||||
match = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if match then
|
||||
items[#items+1] = name
|
||||
end
|
||||
end
|
||||
return items
|
||||
end
|
||||
|
||||
local function get_recipe_variants(items, index)
|
||||
index = index or 1
|
||||
if not items[index] then
|
||||
return
|
||||
end
|
||||
local list = {}
|
||||
local variants = get_recipe_variants(items, index + 1)
|
||||
if variants then
|
||||
for _,a in pairs(items[index]) do
|
||||
for _,b in pairs(variants) do
|
||||
list[#list+1] = a..","..b
|
||||
end
|
||||
end
|
||||
else
|
||||
for _,a in pairs(items[index]) do
|
||||
list[#list+1] = a
|
||||
end
|
||||
end
|
||||
if index == 1 then
|
||||
for i, str in pairs(list) do
|
||||
list[i] = str:split(",")
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
local function cache_recipe(data)
|
||||
-- Create the basic recipe
|
||||
local recipe = {time = data.time, input = {}, output = {}}
|
||||
for _, item in ipairs(data.input) do
|
||||
if item:match("^group:") then
|
||||
local split = item:split(" ")
|
||||
recipe.input[split[1]] = tonumber(split[2]) or 1
|
||||
else
|
||||
local stack = ItemStack(item)
|
||||
recipe.input[stack:get_name()] = stack:get_count()
|
||||
end
|
||||
end
|
||||
for i, item in ipairs(data.output) do
|
||||
recipe.output[i] = ItemStack(item):to_string()
|
||||
end
|
||||
if data.method ~= "cooking" then
|
||||
table.insert(technic.recipes[data.method].recipes, recipe)
|
||||
end
|
||||
-- Find all unique variants of the recipe and cache them
|
||||
-- If there are no group items, there will only be one
|
||||
local all_items, item_counts = {}, {}
|
||||
local has_group_item = false
|
||||
for item, count in pairs(recipe.input) do
|
||||
local group = item:match("^group:(.+)$")
|
||||
if group then
|
||||
table.insert(all_items, get_items_in_group(group))
|
||||
has_group_item = true
|
||||
else
|
||||
table.insert(all_items, {ItemStack(item):get_name()})
|
||||
end
|
||||
table.insert(item_counts, count)
|
||||
end
|
||||
if not has_group_item then
|
||||
local key = get_recipe_key(data.method, data.input)
|
||||
recipe_cache[key] = table.copy(recipe)
|
||||
return
|
||||
end
|
||||
for _,items in pairs(get_recipe_variants(all_items)) do
|
||||
local key = get_recipe_key(data.method, items)
|
||||
-- Non-group recipes take priority over group recipes
|
||||
if not has_group_item or not recipe_cache[key] then
|
||||
local input = {}
|
||||
for i, item in ipairs(items) do
|
||||
input[item] = item_counts[i]
|
||||
end
|
||||
recipe_cache[key] = {
|
||||
time = data.time,
|
||||
input = input,
|
||||
output = table.copy(recipe.output),
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function cache_all_recipes()
|
||||
-- Cache built in cooking recipes
|
||||
for item in pairs(minetest.registered_items) do
|
||||
local recipes = minetest.get_all_craft_recipes(item)
|
||||
for _,recipe in ipairs(recipes or {}) do
|
||||
if recipe.method == "cooking" then
|
||||
local result, new_input = minetest.get_craft_result(recipe)
|
||||
if result and result.time > 0 then
|
||||
local data = {
|
||||
method = "cooking",
|
||||
time = result.time,
|
||||
input = recipe.items,
|
||||
output = {result.item:to_string()},
|
||||
}
|
||||
local replacement = new_input.items[1]
|
||||
if not replacement:is_empty() then
|
||||
data.output[2] = replacement:to_string()
|
||||
end
|
||||
cache_recipe(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Cache custom recipes
|
||||
for _, data in pairs(temp_recipes) do
|
||||
if not data.hidden then
|
||||
add_to_craftguides(data)
|
||||
end
|
||||
cache_recipe(data)
|
||||
end
|
||||
temp_recipes = nil
|
||||
end
|
||||
|
||||
-- Slightly hacky way to be the first function called
|
||||
table.insert(minetest.registered_on_mods_loaded, 1, cache_all_recipes)
|
||||
minetest.callback_origins[cache_all_recipes] = {
|
||||
mod = "technic",
|
||||
name = "register_on_mods_loaded",
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
function technic.register_solar_array(nodename, data)
|
||||
local _, modname, name, def = technic.register_compat_v1_to_v2(nodename, data, "solar_array")
|
||||
assert(def.tier, "Technic register_solar_array requires `tier` field")
|
||||
|
||||
local tier = def.tier
|
||||
local ltier = string.lower(tier)
|
||||
local infotext = S("Arrayed Solar @1 Generator", S(tier))
|
||||
|
||||
local run = function(pos, node)
|
||||
-- The action here is to make the solar array produce power
|
||||
-- Power is dependent on the light level and the height above ground
|
||||
-- There are many ways to cheat by using other light sources like lamps.
|
||||
-- As there is no way to determine if light is sunlight that is just a shame.
|
||||
-- To take care of some of it solar panels do not work outside daylight hours or if
|
||||
-- built below 0m
|
||||
local pos1 = { y = pos.y + 1, x = pos.x, z = pos.z }
|
||||
|
||||
minetest.load_area(pos1)
|
||||
local light = minetest.get_node_light(pos1, nil)
|
||||
local time_of_day = minetest.get_timeofday()
|
||||
local meta = minetest.get_meta(pos)
|
||||
light = light or 0
|
||||
|
||||
-- turn on array only during day time and if sufficient light
|
||||
-- I know this is counter intuitive when cheating by using other light sources.
|
||||
if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > 0 then
|
||||
local charge_to_give = math.floor((light + pos.y) * def.power)
|
||||
charge_to_give = math.max(charge_to_give, 0)
|
||||
charge_to_give = math.min(charge_to_give, def.power * 50)
|
||||
meta:set_string("infotext", S("@1 Active (@2)", infotext, technic.EU_string(charge_to_give)))
|
||||
meta:set_int(tier.."_EU_supply", charge_to_give)
|
||||
else
|
||||
meta:set_string("infotext", S("@1 Idle", infotext))
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
end
|
||||
end
|
||||
|
||||
def.tiles = def.tiles or {
|
||||
modname.."_"..name.."_top.png",
|
||||
modname.."_"..name.."_bottom.png",
|
||||
modname.."_"..name.."_side.png",
|
||||
modname.."_"..name.."_side.png",
|
||||
modname.."_"..name.."_side.png",
|
||||
modname.."_"..name.."_side.png"
|
||||
}
|
||||
def.groups = def.groups or {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, ["technic_"..ltier]=1, axey=2, handy=1}
|
||||
def.is_ground_content = false
|
||||
def._mcl_blast_resistance = 1
|
||||
def._mcl_hardness = 0.8
|
||||
def.connect_sides = def.connect_sides or {"bottom"}
|
||||
def.sounds = def.sounds or technic.sounds.node_sound_wood_defaults()
|
||||
def.description = def.description or S("Arrayed Solar @1 Generator", S(tier))
|
||||
def.active = def.active or false
|
||||
def.drawtype = def.drawtype or "nodebox"
|
||||
def.paramtype = def.paramtype or "light"
|
||||
def.node_box = def.nodebox or {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
}
|
||||
def.on_construct = def.on_construct or function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int(tier.."_EU_supply", 0)
|
||||
end
|
||||
def.technic_run = def.technic_run or run
|
||||
|
||||
minetest.register_node(nodename, def)
|
||||
technic.register_machine(tier, nodename, technic.producer)
|
||||
end
|
219
mods/technic_plus_beta/technic/machines/supply_converter.lua
Normal file
219
mods/technic_plus_beta/technic/machines/supply_converter.lua
Normal file
|
@ -0,0 +1,219 @@
|
|||
-- The supply converter is a generic device which can convert from
|
||||
-- LV to MV and back, and HV to MV and back.
|
||||
-- The machine is configured by the wiring below and above it.
|
||||
--
|
||||
-- It works like this:
|
||||
-- The top side is setup as the receiver side, the bottom as the producer side.
|
||||
-- Once the receiver side is powered it will deliver power to the other side.
|
||||
-- Unused power is wasted just like any other producer!
|
||||
|
||||
local digilines_path = minetest.get_modpath("digilines")
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
local function set_supply_converter_formspec(meta)
|
||||
local formspec = "size[5,2.25]"..
|
||||
"field[0.3,0.5;2,1;power;"..S("Input Power")..";${power}]"
|
||||
if digilines_path then
|
||||
formspec = formspec..
|
||||
"field[2.3,0.5;3,1;channel;"..S("Digiline Channel")..";${channel}]"
|
||||
end
|
||||
-- The names for these toggle buttons are explicit about which
|
||||
-- state they'll switch to, so that multiple presses (arising
|
||||
-- from the ambiguity between lag and a missed press) only make
|
||||
-- the single change that the user expects.
|
||||
if meta:get_int("mesecon_mode") == 0 then
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
|
||||
end
|
||||
if meta:get_int("enabled") == 0 then
|
||||
formspec = formspec.."button[0,1.75;5,1;enable;"..S("@1 Disabled", S("Supply Converter")).."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1.75;5,1;disable;"..S("@1 Enabled", S("Supply Converter")).."]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
||||
local supply_converter_receive_fields = function(pos, formname, fields, sender)
|
||||
if not sender or minetest.is_protected(pos, sender:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local power = nil
|
||||
if fields.power then
|
||||
power = tonumber(fields.power) or 0
|
||||
power = math.max(power, 0)
|
||||
power = math.min(power, 10000)
|
||||
power = 100 * math.floor(power / 100)
|
||||
if power == meta:get_int("power") then power = nil end
|
||||
end
|
||||
if power then meta:set_int("power", power) end
|
||||
if fields.channel then meta:set_string("channel", fields.channel) end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
|
||||
if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
|
||||
set_supply_converter_formspec(meta)
|
||||
end
|
||||
|
||||
local mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 1)
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 0)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local digiline_def = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function() end
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function(pos, node, channel, msg)
|
||||
if type(msg) ~= "string" then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
msg = msg:lower()
|
||||
if msg == "get" then
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
enabled = meta:get_int("enabled"),
|
||||
power = meta:get_int("power"),
|
||||
mesecon_mode = meta:get_int("mesecon_mode")
|
||||
})
|
||||
return
|
||||
elseif msg == "off" then
|
||||
meta:set_int("enabled", 0)
|
||||
elseif msg == "on" then
|
||||
meta:set_int("enabled", 1)
|
||||
elseif msg == "toggle" then
|
||||
local onn = meta:get_int("enabled")
|
||||
onn = 1-onn -- Mirror onn with pivot 0.5, so switch between 1 and 0.
|
||||
meta:set_int("enabled", onn)
|
||||
elseif msg:sub(1, 5) == "power" then
|
||||
local power = tonumber(msg:sub(7))
|
||||
if not power then
|
||||
return
|
||||
end
|
||||
power = math.max(power, 0)
|
||||
power = math.min(power, 10000)
|
||||
power = 100 * math.floor(power / 100)
|
||||
meta:set_int("power", power)
|
||||
elseif msg:sub(1, 12) == "mesecon_mode" then
|
||||
meta:set_int("mesecon_mode", tonumber(msg:sub(14)))
|
||||
else
|
||||
return
|
||||
end
|
||||
set_supply_converter_formspec(meta)
|
||||
end
|
||||
},
|
||||
}
|
||||
|
||||
local run = function(pos, node, run_stage)
|
||||
-- run only in producer stage.
|
||||
if run_stage == technic.receiver then
|
||||
return
|
||||
end
|
||||
|
||||
local remain = 0.9
|
||||
-- Machine information
|
||||
local machine_name = S("Supply Converter")
|
||||
local meta = minetest.get_meta(pos)
|
||||
local enabled = meta:get_int("enabled") == 1 and
|
||||
(meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
|
||||
|
||||
local demand = enabled and meta:get_int("power") or 0
|
||||
|
||||
local pos_up = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local pos_down = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local name_up = minetest.get_node(pos_up).name
|
||||
local name_down = minetest.get_node(pos_down).name
|
||||
|
||||
local from = technic.get_cable_tier(name_up)
|
||||
local to = technic.get_cable_tier(name_down)
|
||||
|
||||
if from and to then
|
||||
local input = meta:get_int(from.."_EU_input")
|
||||
if (technic.get_timeout(from, pos) <= 0) or (technic.get_timeout(to, pos) <= 0) then
|
||||
-- Supply converter timed out, either RE or PR network is not running anymore
|
||||
input = 0
|
||||
end
|
||||
meta:set_int(from.."_EU_demand", demand)
|
||||
meta:set_int(from.."_EU_supply", 0)
|
||||
meta:set_int(to.."_EU_demand", 0)
|
||||
meta:set_int(to.."_EU_supply", input * remain)
|
||||
meta:set_string("infotext", S("@1 (@2 @3 -> @4 @5)", machine_name,
|
||||
technic.EU_string(input), from,
|
||||
technic.EU_string(input * remain), to))
|
||||
else
|
||||
meta:set_string("infotext", S("@1 Has Bad Cabling", machine_name))
|
||||
if to then
|
||||
meta:set_int(to.."_EU_supply", 0)
|
||||
end
|
||||
if from then
|
||||
meta:set_int(from.."_EU_demand", 0)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
minetest.register_node("technic:supply_converter", {
|
||||
description = S("Supply Converter"),
|
||||
tiles = {
|
||||
"technic_supply_converter_tb.png"..cable_entry,
|
||||
"technic_supply_converter_tb.png"..cable_entry,
|
||||
"technic_supply_converter_side.png",
|
||||
"technic_supply_converter_side.png",
|
||||
"technic_supply_converter_side.png",
|
||||
"technic_supply_converter_side.png"
|
||||
},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
|
||||
technic_machine=1, technic_all_tiers=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"top", "bottom"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_receive_fields = supply_converter_receive_fields,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Supply Converter"))
|
||||
meta:set_int("power", 10000)
|
||||
meta:set_int("enabled", 1)
|
||||
meta:set_int("mesecon_mode", 0)
|
||||
meta:set_int("mesecon_effect", 0)
|
||||
set_supply_converter_formspec(meta)
|
||||
end,
|
||||
mesecons = mesecons,
|
||||
digiline = digiline_def,
|
||||
technic_run = run,
|
||||
technic_on_disable = run,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:supply_converter 1',
|
||||
recipe = {
|
||||
{'basic_materials:gold_wire', 'technic:rubber', 'technic:doped_silicon_wafer'},
|
||||
{'technic:mv_transformer', 'technic:machine_casing', 'technic:lv_transformer'},
|
||||
{'technic:mv_cable', 'technic:rubber', 'technic:lv_cable'},
|
||||
},
|
||||
replacements = { {"basic_materials:gold_wire", "basic_materials:empty_spool"}, },
|
||||
})
|
||||
|
||||
for tier, machines in pairs(technic.machines) do
|
||||
technic.register_machine(tier, "technic:supply_converter", technic.producer_receiver)
|
||||
end
|
||||
|
198
mods/technic_plus_beta/technic/machines/switching_station.lua
Normal file
198
mods/technic_plus_beta/technic/machines/switching_station.lua
Normal file
|
@ -0,0 +1,198 @@
|
|||
-- See also technic/doc/api.md
|
||||
|
||||
local mesecons_path = minetest.get_modpath("mesecons")
|
||||
local digilines_path = minetest.get_modpath("digilines")
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local cable_entry = "^technic_cable_connection_overlay.png"
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:switching_station",
|
||||
recipe = {
|
||||
{"", "technic:lv_transformer", ""},
|
||||
{mat.copper_ingot, "technic:machine_casing", mat.copper_ingot},
|
||||
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"}
|
||||
}
|
||||
})
|
||||
|
||||
local function start_network(pos)
|
||||
local tier = technic.sw_pos2tier(pos)
|
||||
if not tier then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("@1 Has No Network", S("Switching Station")))
|
||||
else
|
||||
local network_id = technic.sw_pos2network(pos) or technic.create_network(pos)
|
||||
local network = network_id and technic.networks[network_id]
|
||||
if network and technic.switch_insert(pos, network) > 0 then
|
||||
technic.activate_network(network_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mesecon_def
|
||||
if mesecons_path then
|
||||
mesecon_def = {effector = {
|
||||
rules = mesecon.rules.default,
|
||||
}}
|
||||
end
|
||||
|
||||
minetest.register_node("technic:switching_station",{
|
||||
description = S("Switching Station"),
|
||||
tiles = {
|
||||
"technic_water_mill_top_active.png",
|
||||
"technic_water_mill_top_active.png"..cable_entry,
|
||||
"technic_water_mill_top_active.png",
|
||||
"technic_water_mill_top_active.png",
|
||||
"technic_water_mill_top_active.png",
|
||||
"technic_water_mill_top_active.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_all_tiers=1, axey=2, handy=1},
|
||||
is_ground_content = false,
|
||||
_mcl_blast_resistance = 1,
|
||||
_mcl_hardness = 0.8,
|
||||
connect_sides = {"bottom"},
|
||||
sounds = technic.sounds.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Switching Station"))
|
||||
meta:set_string("formspec", "field[channel;"..S("Digiline Channel")..";${channel}]")
|
||||
start_network(pos)
|
||||
|
||||
-- start nodetimer
|
||||
minetest.get_node_timer(pos):start(1.0)
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
-- Remove network when last switching stations is removed
|
||||
local network_id = technic.sw_pos2network(pos)
|
||||
local network = network_id and technic.networks[network_id]
|
||||
if network and technic.switch_remove(pos, network) < 1 then
|
||||
technic.remove_network(network_id)
|
||||
end
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
if not fields.channel then
|
||||
return
|
||||
end
|
||||
local plname = sender:get_player_name()
|
||||
if minetest.is_protected(pos, plname) then
|
||||
minetest.record_protection_violation(pos, plname)
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("channel", fields.channel)
|
||||
end,
|
||||
|
||||
-- nodetimer for network activation
|
||||
on_timer = function(pos)
|
||||
local network_id = technic.sw_pos2network(pos)
|
||||
-- Check if network is overloaded / conflicts with another network
|
||||
if network_id then
|
||||
local infotext
|
||||
local meta = minetest.get_meta(pos)
|
||||
if technic.is_overloaded(network_id) then
|
||||
local remaining = technic.reset_overloaded(network_id)
|
||||
if remaining > 0 then
|
||||
infotext = S("@1 Network Overloaded, Restart in @2ms", S("Switching Station"), remaining / 1000)
|
||||
else
|
||||
infotext = S("@1 Restarting Network", S("Switching Station"))
|
||||
end
|
||||
technic.network_infotext(network_id, infotext)
|
||||
else
|
||||
-- Network exists and is not overloaded, reactivate network
|
||||
technic.activate_network(network_id)
|
||||
infotext = technic.network_infotext(network_id)
|
||||
-- If mesecon signal enabled and power supply or demand changed then send them via digilines.
|
||||
if mesecons_path and digilines_path and mesecon.is_powered(pos) then
|
||||
local network = technic.networks[network_id]
|
||||
if meta:get_int("supply") ~= network.supply or meta:get_int("demand") ~= network.demand then
|
||||
meta:set_int("supply", network.supply)
|
||||
meta:set_int("demand", network.demand)
|
||||
local channel = meta:get_string("channel")
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
supply = network.supply,
|
||||
demand = network.demand
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
meta:set_string("infotext", infotext)
|
||||
else
|
||||
-- Network does not exist yet, attempt to create new network here
|
||||
start_network(pos)
|
||||
end
|
||||
|
||||
-- restart the nodetimer again
|
||||
return true
|
||||
end,
|
||||
|
||||
-- mesecons
|
||||
mesecons = mesecon_def,
|
||||
|
||||
-- digiline
|
||||
digiline = {
|
||||
receptor = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function() end
|
||||
},
|
||||
effector = {
|
||||
rules = technic.digilines.rules,
|
||||
action = function(pos, node, channel, msg)
|
||||
if msg ~= "GET" and msg ~= "get" then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if channel ~= meta:get_string("channel") then
|
||||
return
|
||||
end
|
||||
local network_id = technic.sw_pos2network(pos)
|
||||
local network = network_id and technic.networks[network_id]
|
||||
if network then
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
supply = network.supply,
|
||||
demand = network.demand,
|
||||
lag = network.lag
|
||||
})
|
||||
else
|
||||
digilines.receptor_send(pos, technic.digilines.rules, channel, {
|
||||
error = "No network",
|
||||
})
|
||||
end
|
||||
end
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-----------------------------------------------
|
||||
-- The action code for the switching station --
|
||||
-----------------------------------------------
|
||||
|
||||
-- Timeout ABM
|
||||
-- Timeout for a node in case it was disconnected from the network
|
||||
-- A node must be touched by the station continuously in order to function
|
||||
minetest.register_abm({
|
||||
label = "Machines: timeout check",
|
||||
nodenames = {"group:technic_machine"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not technic.machine_tiers[node.name] then
|
||||
-- https://github.com/mt-mods/technic/issues/123
|
||||
return
|
||||
end
|
||||
-- Check for machine timeouts for all tiers
|
||||
local tiers = technic.machine_tiers[node.name]
|
||||
local timed_out = true
|
||||
for _, tier in ipairs(tiers) do
|
||||
local timeout = technic.get_timeout(tier, pos)
|
||||
if timeout > 0 then
|
||||
technic.touch_node(tier, pos, timeout - 1)
|
||||
timed_out = false
|
||||
end
|
||||
end
|
||||
-- If all tiers for machine timed out take action
|
||||
if timed_out then
|
||||
technic.disable_machine(pos, node)
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,76 @@
|
|||
local S = technic.getter
|
||||
|
||||
-- the interval between technic_run calls
|
||||
local technic_run_interval = 1.0
|
||||
local set_default_timeout = technic.set_default_timeout
|
||||
|
||||
-- iterate over all collected switching stations and execute the technic_run function
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
timer = timer + dtime
|
||||
if timer < technic_run_interval or not technic.powerctrl_state then
|
||||
return
|
||||
end
|
||||
timer = 0
|
||||
|
||||
local max_lag = technic.get_max_lag()
|
||||
-- slow down technic execution if the lag is higher than usual
|
||||
if max_lag > 5.0 then
|
||||
technic_run_interval = 5.0
|
||||
elseif max_lag > 2.0 then
|
||||
technic_run_interval = 4.0
|
||||
elseif max_lag > 1.5 then
|
||||
technic_run_interval = 3.0
|
||||
elseif max_lag > 1.0 then
|
||||
technic_run_interval = 1.5
|
||||
else
|
||||
-- normal run_interval
|
||||
technic_run_interval = 1.0
|
||||
end
|
||||
set_default_timeout(math.ceil(technic_run_interval) + 1)
|
||||
|
||||
local now = minetest.get_us_time()
|
||||
|
||||
for network_id, network in pairs(technic.active_networks) do
|
||||
if network.timeout > now and not technic.is_overloaded(network_id) then
|
||||
-- station active
|
||||
if network.skip > 0 then
|
||||
network.skip = network.skip - 1
|
||||
else
|
||||
local start = minetest.get_us_time()
|
||||
technic.network_run(network_id)
|
||||
local switch_diff = network.average_lag(minetest.get_us_time() - start)
|
||||
|
||||
-- set lag in microseconds into the "lag" meta field
|
||||
network.lag = switch_diff
|
||||
|
||||
-- overload detection
|
||||
if switch_diff > 250000 then
|
||||
network.skip = 30
|
||||
elseif switch_diff > 150000 then
|
||||
network.skip = 20
|
||||
elseif switch_diff > 75000 then
|
||||
network.skip = 10
|
||||
elseif switch_diff > 50000 then
|
||||
network.skip = 2
|
||||
end
|
||||
|
||||
if network.skip > 0 then
|
||||
-- calculate efficiency in percent and display it
|
||||
local efficiency = math.floor(1/network.skip*100)
|
||||
technic.network_infotext(network_id,
|
||||
S("Polyfuse triggered, current efficiency: @1%, generated lag: @2 ms",
|
||||
efficiency, math.floor(switch_diff/1000)))
|
||||
|
||||
-- remove laggy network from active index
|
||||
-- it will be reactivated when a player is near it
|
||||
technic.active_networks[network_id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- network timed out
|
||||
technic.active_networks[network_id] = nil
|
||||
end
|
||||
end
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue