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")
|
Loading…
Add table
Add a link
Reference in a new issue