mirror of
https://github.com/minetest-mods/technic.git
synced 2025-06-30 23:30:38 +02:00
Partial rewrite
This commit is contained in:
19
technic/machines/HV/battery_box.lua
Normal file
19
technic/machines/HV/battery_box.lua
Normal file
@ -0,0 +1,19 @@
|
||||
-- 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_cable0', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_battery_box({
|
||||
tier = "HV",
|
||||
max_charge = 1500000,
|
||||
charge_rate = 100000,
|
||||
discharge_rate = 400000,
|
||||
charge_step = 10000,
|
||||
discharge_step = 40000,
|
||||
})
|
||||
|
12
technic/machines/HV/cables.lua
Normal file
12
technic/machines/HV/cables.lua
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_cable0 3',
|
||||
recipe = {
|
||||
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
|
||||
{'technic:mv_cable0', 'technic:mv_cable0', 'technic:mv_cable0'},
|
||||
{'technic:rubber', 'technic:rubber', 'technic:rubber'},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_cable("HV", 3/16)
|
||||
|
206
technic/machines/HV/forcefield.lua
Normal file
206
technic/machines/HV/forcefield.lua
Normal file
@ -0,0 +1,206 @@
|
||||
-- Forcefield mod by ShadowNinja
|
||||
-- Modified by kpoppel
|
||||
--
|
||||
-- Forcefields are powerful barriers but they consume huge amounts of power.
|
||||
-- Forcefield Generator is a HV machine.
|
||||
|
||||
-- How expensive is the generator?
|
||||
-- Leaves room for upgrades lowering the power drain?
|
||||
local forcefield_power_drain = 10
|
||||
local forcefield_step_interval = 1
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:forcefield_emitter_off',
|
||||
recipe = {
|
||||
{'default:mese', 'technic:deployer_off', 'default:mese' },
|
||||
{'technic:deployer_off', 'technic:motor', 'technic:deployer_off'},
|
||||
{'default:mese', 'technic:deployer_off', 'default:mese' },
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- 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, range, active)
|
||||
local vm = VoxelManip()
|
||||
local p1 = {x = pos.x-range, y = pos.y-range, z = pos.z-range}
|
||||
local p2 = {x = pos.x+range, y = pos.y+range, z = pos.z+range}
|
||||
local MinEdge, MaxEdge = vm:read_from_map(p1, p2)
|
||||
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
|
||||
if x*x+y*y+z*z <= range * range + range and
|
||||
x*x+y*y+z*z >= (range-1) * (range-1) + (range-1) then
|
||||
if active and data[vi] == c_air then
|
||||
data[vi] = c_field
|
||||
elseif not active and data[vi] == 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()
|
||||
vm:update_map()
|
||||
end
|
||||
|
||||
local get_forcefield_formspec = function(range)
|
||||
return "size[3,1.5]"..
|
||||
"field[1,0.5;2,1;range;Range;"..range.."]"..
|
||||
"button[0,1;3,1;toggle;Enable/Disable]"
|
||||
end
|
||||
|
||||
local forcefield_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local range = fields.range
|
||||
|
||||
if fields.toggle then
|
||||
if meta:get_int("enabled") == 1 then
|
||||
meta:set_int("enabled", 0)
|
||||
else
|
||||
meta:set_int("enabled", 1)
|
||||
end
|
||||
end
|
||||
|
||||
-- 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 meta:get_int("range") ~= range then
|
||||
update_forcefield(pos, meta:get_int("range"), false)
|
||||
meta:set_int("range", range)
|
||||
meta:set_string("formspec", get_forcefield_formspec(range))
|
||||
end
|
||||
end
|
||||
|
||||
local mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("enabled", 0)
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("enabled", 1)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
minetest.register_node("technic:forcefield_emitter_off", {
|
||||
description = "Forcefield emitter",
|
||||
tiles = {"technic_forcefield_emitter_off.png"},
|
||||
groups = {cracky = 1},
|
||||
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_string("formspec", get_forcefield_formspec(10))
|
||||
meta:set_string("infotext", "Forcefield emitter");
|
||||
end,
|
||||
mesecons = mesecons
|
||||
})
|
||||
|
||||
minetest.register_node("technic:forcefield_emitter_on", {
|
||||
description = "Forcefield emitter on (you hacker you)",
|
||||
tiles = {"technic_forcefield_emitter_on.png"},
|
||||
groups = {cracky = 1, not_in_creative_inventory=1},
|
||||
drop = "technic:forcefield_emitter_off",
|
||||
on_receive_fields = forcefield_receive_fields,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local range = meta:get_int("range")
|
||||
meta:set_string("formspec", get_forcefield_formspec(range))
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_forcefield(pos, meta:get_int("range"), false)
|
||||
end,
|
||||
mesecons = mesecons
|
||||
})
|
||||
|
||||
minetest.register_node("technic:forcefield", {
|
||||
description = "Forcefield (you hacker you)",
|
||||
sunlight_propagates = true,
|
||||
drawtype = "glasslike",
|
||||
groups = {not_in_creative_inventory=1, unbreakable=1},
|
||||
paramtype = "light",
|
||||
light_source = 15,
|
||||
drop = '',
|
||||
tiles = {{
|
||||
name = "technic_forcefield_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1.0,
|
||||
},
|
||||
}},
|
||||
})
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:forcefield_emitter_on", "technic:forcefield_emitter_off"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local eu_input = meta:get_int("HV_EU_input")
|
||||
local eu_demand = meta:get_int("HV_EU_demand")
|
||||
local enabled = meta:get_int("enabled")
|
||||
-- Power off automatically if no longer connected to a switching station
|
||||
technic.switching_station_timeout_count(pos, "HV")
|
||||
|
||||
local power_requirement = math.floor(
|
||||
4 * math.pi * math.pow(meta:get_int("range"), 2)
|
||||
) * forcefield_power_drain
|
||||
|
||||
if meta:get_int("enabled") == 0 then
|
||||
if node.name == "technic:forcefield_emitter_on" then
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
update_forcefield(pos, meta:get_int("range"), false)
|
||||
hacky_swap_node(pos, "technic:forcefield_emitter_off")
|
||||
meta:set_string("infotext", "Forcefield Generator Disabled")
|
||||
return
|
||||
end
|
||||
elseif eu_input < power_requirement then
|
||||
meta:set_string("infotext", "Forcefield Generator Unpowered")
|
||||
if node.name == "technic:forcefield_emitter_on" then
|
||||
update_forcefield(pos, meta:get_int("range"), false)
|
||||
hacky_swap_node(pos, "technic:forcefield_emitter_off")
|
||||
end
|
||||
elseif eu_input >= power_requirement then
|
||||
if node.name == "technic:forcefield_emitter_off" then
|
||||
hacky_swap_node(pos, "technic:forcefield_emitter_on")
|
||||
meta:set_string("infotext", "Forcefield Generator Active")
|
||||
end
|
||||
update_forcefield(pos, meta:get_int("range"), true)
|
||||
end
|
||||
meta:set_int("HV_EU_demand", power_requirement)
|
||||
end
|
||||
})
|
||||
|
||||
if minetest.get_modpath("mesecons_mvps") then
|
||||
mesecon:register_mvps_stopper("technic:forcefield")
|
||||
end
|
||||
-- TODO: Register a stopper for frames
|
||||
|
||||
technic.register_machine("HV", "technic:forcefield_emitter_on", technic.receiver)
|
||||
technic.register_machine("HV", "technic:forcefield_emitter_off", technic.receiver)
|
||||
|
12
technic/machines/HV/init.lua
Normal file
12
technic/machines/HV/init.lua
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
technic.register_tier("HV", "High Voltage")
|
||||
|
||||
local path = technic.modpath.."/machines/HV"
|
||||
|
||||
dofile(path.."/cables.lua")
|
||||
dofile(path.."/quarry.lua")
|
||||
dofile(path.."/forcefield.lua")
|
||||
dofile(path.."/battery_box.lua")
|
||||
dofile(path.."/solar_array.lua")
|
||||
dofile(path.."/nuclear_reactor.lua")
|
||||
|
259
technic/machines/HV/nuclear_reactor.lua
Normal file
259
technic/machines/HV/nuclear_reactor.lua
Normal file
@ -0,0 +1,259 @@
|
||||
-- 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. (10000EU 86400 ticks (24h))
|
||||
-- Provides HV EUs that can be down converted as needed.
|
||||
--
|
||||
-- The nuclear reactor core needs water and a protective shield to work.
|
||||
-- This is checked now and then and if the machine is tampered with... BOOM!
|
||||
|
||||
local burn_ticks = 7 * 24 * 60 * 60 -- (seconds).
|
||||
local power_supply = 100000 -- EUs
|
||||
local fuel_type = "technic:uranium_fuel" -- The reactor burns this stuff
|
||||
|
||||
|
||||
-- FIXME: recipe must make more sense like a rod recepticle, steam chamber, HV generator?
|
||||
minetest.register_craft({
|
||||
output = 'technic:hv_nuclear_reactor_core',
|
||||
recipe = {
|
||||
{'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
|
||||
{'technic:stainless_steel_ingot', '', 'technic:stainless_steel_ingot'},
|
||||
{'technic:stainless_steel_ingot', 'technic:hv_cable', 'technic:stainless_steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
local generator_formspec =
|
||||
"invsize[8,9;]"..
|
||||
"label[0,0;Nuclear Reactor Rod Compartment]"..
|
||||
"list[current_name;src;2,1;3,2;]"..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
|
||||
-- "Boxy sphere"
|
||||
local nodebox = {
|
||||
{ -0.353, -0.353, -0.353, 0.353, 0.353, 0.353 }, -- Box
|
||||
{ -0.495, -0.064, -0.064, 0.495, 0.064, 0.064 }, -- Circle +-x
|
||||
{ -0.483, -0.128, -0.128, 0.483, 0.128, 0.128 },
|
||||
{ -0.462, -0.191, -0.191, 0.462, 0.191, 0.191 },
|
||||
{ -0.433, -0.249, -0.249, 0.433, 0.249, 0.249 },
|
||||
{ -0.397, -0.303, -0.303, 0.397, 0.303, 0.303 },
|
||||
{ -0.305, -0.396, -0.305, 0.305, 0.396, 0.305 }, -- Circle +-y
|
||||
{ -0.250, -0.432, -0.250, 0.250, 0.432, 0.250 },
|
||||
{ -0.191, -0.461, -0.191, 0.191, 0.461, 0.191 },
|
||||
{ -0.130, -0.482, -0.130, 0.130, 0.482, 0.130 },
|
||||
{ -0.066, -0.495, -0.066, 0.066, 0.495, 0.066 },
|
||||
{ -0.064, -0.064, -0.495, 0.064, 0.064, 0.495 }, -- Circle +-z
|
||||
{ -0.128, -0.128, -0.483, 0.128, 0.128, 0.483 },
|
||||
{ -0.191, -0.191, -0.462, 0.191, 0.191, 0.462 },
|
||||
{ -0.249, -0.249, -0.433, 0.249, 0.249, 0.433 },
|
||||
{ -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 },
|
||||
}
|
||||
|
||||
minetest.register_node("technic:hv_nuclear_reactor_core", {
|
||||
description = "Nuclear Reactor",
|
||||
tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drawtype="nodebox",
|
||||
paramtype = "light",
|
||||
stack_max = 1,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = nodebox
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Nuclear Reactor Core")
|
||||
meta:set_int("HV_EU_supply", 0)
|
||||
-- Signal to the switching station that this device burns some
|
||||
-- sort of fuel and needs special handling
|
||||
meta:set_int("HV_EU_from_fuel", 1)
|
||||
meta:set_int("burn_time", 0)
|
||||
meta:set_string("formspec", generator_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("src", 6)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("src") then
|
||||
minetest.chat_send_player(player:get_player_name(),
|
||||
"Machine cannot be removed because it is not empty");
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("technic:hv_nuclear_reactor_core_active", {
|
||||
description = "HV Uranium Reactor",
|
||||
tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
|
||||
"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drop="technic:hv_nuclear_reactor_core",
|
||||
drawtype="nodebox",
|
||||
light_source = 15,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = nodebox
|
||||
},
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("src") then
|
||||
minetest.chat_send_player(player:get_player_name(),
|
||||
"Machine cannot be removed because it is not empty");
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local check_reactor_structure = function(pos)
|
||||
-- The reactor consists of a 9x9x9 cube structure
|
||||
-- A cross section through the middle:
|
||||
-- CCCC CCCC
|
||||
-- CBBB BBBC
|
||||
-- CBSS SSBC
|
||||
-- CBSWWWSBC
|
||||
-- CBSW#WSBC
|
||||
-- CBSW|WSBC
|
||||
-- CBSS|SSBC
|
||||
-- CBBB|BBBC
|
||||
-- CCCC|CCCC
|
||||
-- C = Concrete, B = Blast resistant concrete, S = Stainless Steel,
|
||||
-- W = water node, # = reactor core, | = HV cable
|
||||
-- The man-hole and the HV cable is only in the middle
|
||||
-- The man-hole is optional
|
||||
|
||||
local vm = VoxelManip()
|
||||
local pos1 = vector.subtract(pos, 4)
|
||||
local pos2 = vector.add(pos, 4)
|
||||
local MinEdge, MaxEdge = vm:read_from_map(pos1, pos2)
|
||||
local data = vm:get_data()
|
||||
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
|
||||
|
||||
local c_concrete = minetest.get_content_id("technic:concrete")
|
||||
local c_blast_concrete = minetest.get_content_id("technic:blast_resistant_concrete")
|
||||
local c_stainless_steel = minetest.get_content_id("technic:stainless_steel_block")
|
||||
local c_water_source = minetest.get_content_id("default:water_source")
|
||||
local c_water_flowing = minetest.get_content_id("default:water_flowing")
|
||||
|
||||
local concretelayer, blastlayer, steellayer, waterlayer = 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
|
||||
-- If the position is in the outer layer
|
||||
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 data[area:index(x, y, z)] == c_concrete then
|
||||
concretelayer = concretelayer + 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 data[area:index(x, y, z)] == c_blast_concrete then
|
||||
blastlayer = blastlayer + 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 data[area:index(x, y, z)] == c_stainless_steel then
|
||||
steellayer = steellayer + 1
|
||||
end
|
||||
elseif x == pos1.x+3 or x == pos2.x-3 or
|
||||
y == pos1.y+3 or y == pos2.y-3 or
|
||||
z == pos1.z+3 or z == pos2.z-3 then
|
||||
local cid = data[area:index(x, y, z)]
|
||||
if cid == c_water_source or cid == c_water_flowing then
|
||||
waterlayer = waterlayer + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if waterlayer >= 25 and
|
||||
steellayer >= 96 and
|
||||
blastlayer >= 216 and
|
||||
concretelayer >= 384 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local explode_reactor = function(pos)
|
||||
print("A reactor exploded at "..minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
local function damage_nearby_players(pos)
|
||||
local objs = minetest.get_objects_inside_radius(pos, 4)
|
||||
for _, o in pairs(objs) do
|
||||
if o:is_player() then
|
||||
o:set_hp(math.max(o:get_hp() - 2, 0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:hv_nuclear_reactor_core", "technic:hv_nuclear_reactor_core_active"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
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
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("src") then
|
||||
local srclist = inv:get_list("src")
|
||||
local correct_fuel_count = 0
|
||||
for _, srcstack in pairs(srclist) do
|
||||
if srcstack then
|
||||
if srcstack:get_name() == fuel_type then
|
||||
correct_fuel_count = correct_fuel_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Check that the reactor is complete as well
|
||||
-- as the correct number of correct fuel
|
||||
if correct_fuel_count == 6 and
|
||||
check_reactor_structure(pos) then
|
||||
meta:set_int("burn_time", 1)
|
||||
hacky_swap_node(pos, "technic:hv_nuclear_reactor_core_active")
|
||||
meta:set_int("HV_EU_supply", power_supply)
|
||||
for idx, srcstack in pairs(srclist) do
|
||||
srcstack:take_item()
|
||||
inv:set_stack("src", idx, srcstack)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
meta:set_int("HV_EU_supply", 0)
|
||||
meta:set_int("burn_time", 0)
|
||||
meta:set_string("infotext", "Nuclear Reactor Core (idle)")
|
||||
hacky_swap_node(pos, "technic:hv_nuclear_reactor_core")
|
||||
elseif burn_time > 0 then
|
||||
damage_nearby_players(pos)
|
||||
if not check_reactor_structure(pos) then
|
||||
explode_reactor(pos)
|
||||
end
|
||||
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", "Nuclear Reactor Core ("..percent.."%)")
|
||||
meta:set_int("HV_EU_supply", power_supply)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core", technic.producer)
|
||||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core_active", technic.producer)
|
||||
|
200
technic/machines/HV/quarry.lua
Normal file
200
technic/machines/HV/quarry.lua
Normal file
@ -0,0 +1,200 @@
|
||||
|
||||
minetest.register_craft({
|
||||
recipe = {
|
||||
{"default:steelblock", "pipeworks:filter", "default:steelblock"},
|
||||
{"default:steelblock", "technic:motor", "default:steelblock"},
|
||||
{"default:steelblock", "technic:diamond_drill_head", "default:steelblock"}},
|
||||
output = "technic:quarry",
|
||||
})
|
||||
|
||||
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
|
||||
local quarry_max_depth = 100
|
||||
|
||||
local function get_quarry_formspec(size)
|
||||
return "size[3,1.5]"..
|
||||
"field[1,0.5;2,1;size;Radius;"..size.."]"..
|
||||
"button[0,1;3,1;toggle;Enable/Disable]"
|
||||
end
|
||||
|
||||
local function quarry_receive_fields(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local size = tonumber(fields.size)
|
||||
|
||||
if fields.toggle then
|
||||
if meta:get_int("enabled") == 0 then
|
||||
meta:set_int("enabled", 1)
|
||||
else
|
||||
meta:set_int("enabled", 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Smallest size is 2. Anything less is asking for trouble.
|
||||
-- Largest is 8. It is a matter of pratical node handling.
|
||||
size = math.max(size, 2)
|
||||
size = math.min(size, 8)
|
||||
|
||||
if meta:get_int("size") ~= size then
|
||||
meta:set_int("size", size)
|
||||
meta:set_string("formspec", get_quarry_formspec(size))
|
||||
end
|
||||
end
|
||||
|
||||
local function get_quarry_center(pos, size)
|
||||
local node = minetest.get_node(pos)
|
||||
local back_dir = minetest.facedir_to_dir(node.param2)
|
||||
local relative_center = vector.multiply(back_dir, size + 1)
|
||||
local center = vector.add(pos, relative_center)
|
||||
return center
|
||||
end
|
||||
|
||||
local function gen_next_digpos(center, digpos, size)
|
||||
digpos.x = digpos.x + 1
|
||||
if digpos.x > center.x + size then
|
||||
digpos.x = center.x - size
|
||||
digpos.z = digpos.z + 1
|
||||
end
|
||||
if digpos.z > center.z + size then
|
||||
digpos.x = center.x - size
|
||||
digpos.z = center.z - size
|
||||
digpos.y = digpos.y - 1
|
||||
end
|
||||
end
|
||||
|
||||
local function find_next_digpos(data, area, center, dig_y, size)
|
||||
local c_air = minetest.get_content_id("air")
|
||||
|
||||
for y = center.y + quarry_dig_above_nodes, dig_y - 1, -1 do
|
||||
for z = center.z - size, center.z + size do
|
||||
for x = center.x - size, center.x + size do
|
||||
if data[area:index(x, y, z)] ~= c_air then
|
||||
return vector.new(x, y, z)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function quarry_dig(pos, center, size)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local drops = {}
|
||||
local dig_y = meta:get_int("dig_y")
|
||||
local owner = meta:get_int("owner")
|
||||
|
||||
local vm = VoxelManip()
|
||||
local p1 = vector.new(
|
||||
center.x - size,
|
||||
center.y + quarry_dig_above_nodes,
|
||||
center.z - size)
|
||||
local p2 = vector.new(
|
||||
center.x + size,
|
||||
dig_y - 1, -- One node lower in case we have finished the current layer
|
||||
center.z + size)
|
||||
local e1, e2 = vm:read_from_map(p1, p2)
|
||||
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
||||
local data = vm:get_data()
|
||||
|
||||
local digpos = find_next_digpos(data, area, center, dig_y, size)
|
||||
|
||||
if digpos then
|
||||
if digpos.y < pos.y - quarry_max_depth then
|
||||
meta:set_int("dig_y", digpos.y)
|
||||
return drops
|
||||
end
|
||||
if minetest.is_protected and minetest.is_protected(digpos, owner) then
|
||||
meta:set_int("enabled", 0)
|
||||
return
|
||||
end
|
||||
dig_y = digpos.y
|
||||
local node = minetest.get_node(digpos)
|
||||
drops = minetest.get_node_drops(node.name, "")
|
||||
minetest.dig_node(digpos)
|
||||
if minetest.get_node(digpos).name == node.name then
|
||||
-- We tried to dig something undigable like a
|
||||
-- filled chest. Notice that we check for a node
|
||||
-- change, not for air. This is so that we get drops
|
||||
-- from things like concrete posts with platforms,
|
||||
-- which turn into regular concrete posts when dug.
|
||||
drops = {}
|
||||
end
|
||||
elseif not (dig_y < pos.y - quarry_max_depth) then
|
||||
dig_y = dig_y - 16
|
||||
end
|
||||
|
||||
meta:set_int("dig_y", dig_y)
|
||||
return drops
|
||||
end
|
||||
|
||||
local function send_items(items, pos, node)
|
||||
for _, item in pairs(items) do
|
||||
local tube_item = tube_item(vector.new(pos), item)
|
||||
tube_item:get_luaentity().start_pos = vector.new(pos)
|
||||
tube_item:setvelocity(vector.new(0, 1, 0))
|
||||
tube_item:setacceleration({x=0, y=0, z=0})
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("technic:quarry", {
|
||||
description = "Quarry",
|
||||
tiles = {"default_steel_block.png", "default_steel_block.png",
|
||||
"default_steel_block.png", "default_steel_block.png",
|
||||
"default_steel_block.png^default_tool_mesepick.png", "default_steel_block.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, tubedevice=1},
|
||||
tube = {
|
||||
connect_sides = {top = 1},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local size = 4
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Quarry")
|
||||
meta:set_string("formspec", get_quarry_formspec(4))
|
||||
meta:set_int("size", size)
|
||||
meta:set_int("dig_y", pos.y)
|
||||
end,
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
tube_scanforobjects(pos)
|
||||
end,
|
||||
after_dig_node = tube_scanforobjects,
|
||||
on_receive_fields = quarry_receive_fields,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:quarry"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local size = meta:get_int("size")
|
||||
local eu_input = meta:get_int("HV_EU_input")
|
||||
local demand = 10000
|
||||
local center = get_quarry_center(pos, size)
|
||||
local dig_y = meta:get_int("dig_y")
|
||||
|
||||
technic.switching_station_timeout_count(pos, "HV")
|
||||
|
||||
if meta:get_int("enabled") == 0 then
|
||||
meta:set_string("infotext", "Quarry Disabled")
|
||||
meta:set_int("HV_EU_demand", 0)
|
||||
return
|
||||
end
|
||||
|
||||
if eu_input < demand then
|
||||
meta:set_string("infotext", "Quarry Unpowered")
|
||||
elseif eu_input >= demand then
|
||||
meta:set_string("infotext", "Quarry Active")
|
||||
|
||||
local items = quarry_dig(pos, center, size)
|
||||
send_items(items, pos, node)
|
||||
|
||||
if dig_y < pos.y - quarry_max_depth then
|
||||
meta:set_string("infotext", "Quarry Finished")
|
||||
end
|
||||
end
|
||||
meta:set_int("HV_EU_demand", demand)
|
||||
end
|
||||
})
|
||||
|
||||
technic.register_machine("HV", "technic:quarry", technic.receiver)
|
||||
|
14
technic/machines/HV/solar_array.lua
Normal file
14
technic/machines/HV/solar_array.lua
Normal file
@ -0,0 +1,14 @@
|
||||
-- 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:solar_array_hv 1',
|
||||
recipe = {
|
||||
{'technic:solar_array_mv', 'technic:solar_array_mv', 'technic:solar_array_mv'},
|
||||
{'default:steel_ingot', 'technic:hv_transformer', 'default:steel_ingot'},
|
||||
{'', 'technic:hv_cable0', ''},
|
||||
}
|
||||
})
|
||||
|
||||
technic.register_solar_array({tier="HV", power=100})
|
||||
|
Reference in New Issue
Block a user