| | |
| | | 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 digiline_remote_path = minetest.get_modpath("digiline_remote") |
| | | |
| | | local S = technic.getter |
| | | |
| | | local reactor_desc = S("@1 Nuclear Reactor Core", S("HV")), |
| | | |
| | | 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({ |
| | |
| | | } |
| | | }) |
| | | |
| | | local reactor_formspec = |
| | | "invsize[8,9;]".. |
| | | local function make_reactor_formspec(meta) |
| | | local f = "size[8,9]".. |
| | | "label[0,0;"..S("Nuclear Reactor Rod Compartment").."]".. |
| | | "list[current_name;src;2,1;3,2;]".. |
| | | "list[current_player;main;0,5;8,4;]".. |
| | | "listring[]" |
| | | |
| | | -- "Boxy sphere" |
| | | local node_box = { |
| | | {-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}, |
| | | } |
| | | "listring[]".. |
| | | "button[5.5,1.5;2,1;start;Start]".. |
| | | "checkbox[5.5,2.5;autostart;automatic Start;"..meta:get_string("autostart").."]" |
| | | if not digiline_remote_path 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;Save]".. |
| | | "field[1,4;4,1;remote_channel;Digiline Remote Channel;${remote_channel}]" |
| | | end |
| | | |
| | | local SS_OFF = 0 |
| | | local SS_DANGER = 1 |
| | |
| | | |
| | | local function melt_down_reactor(pos) |
| | | minetest.log("action", "A reactor melted down at "..minetest.pos_to_string(pos)) |
| | | minetest.set_node(pos, {name="technic:corium_source"}) |
| | | minetest.set_node(pos, {name = "technic:corium_source"}) |
| | | end |
| | | |
| | | |
| | | local function start_reactor(pos, meta) |
| | | local correct_fuel_count = 6 |
| | | local msg_fuel_missing = "Error: You need to insert " .. correct_fuel_count .. " pieces of Uranium Fuel." |
| | | |
| | | if minetest.get_node(pos).name ~= "technic:hv_nuclear_reactor_core" then |
| | | return msg_fuel_missing |
| | | end |
| | | local inv = meta:get_inventory() |
| | | if inv:is_empty("src") then |
| | | return msg_fuel_missing |
| | | end |
| | | local src_list = inv:get_list("src") |
| | | local fuel_count = 0 |
| | | for _, src_stack in pairs(src_list) do |
| | | if src_stack and src_stack:get_name() == fuel_type then |
| | | fuel_count = fuel_count + 1 |
| | | end |
| | | end |
| | | -- Check that the has the correct fuel |
| | | if fuel_count ~= correct_fuel_count then |
| | | return msg_fuel_missing |
| | | end |
| | | |
| | | -- Check that the reactor is complete |
| | | if reactor_structure_badness(pos) ~= 0 then |
| | | return "Error: The power plant seems to be built incorrectly." |
| | | 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 nil |
| | | end |
| | | |
| | | |
| | | minetest.register_abm({ |
| | | label = "Machines: reactor melt-down check", |
| | | nodenames = {"technic:hv_nuclear_reactor_core_active"}, |
| | | interval = 4, |
| | | chance = 1, |
| | |
| | | local accum_badness = meta:get_int("structure_accumulated_badness") |
| | | if badness == 0 then |
| | | if accum_badness ~= 0 then |
| | | meta:set_int("structure_accumulated_badness", accum_badness - 4) |
| | | meta:set_int("structure_accumulated_badness", math.max(accum_badness - 4, 0)) |
| | | siren_clear(pos, meta) |
| | | end |
| | | else |
| | |
| | | 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 |
| | | local inv = meta:get_inventory() |
| | | if not inv:is_empty("src") then |
| | | 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 and |
| | | reactor_structure_badness(pos) == 0 then |
| | | 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 |
| | | if digiline_remote_path and meta:get_int("HV_EU_supply") == power_supply then |
| | | digiline_remote.send_to_node(pos, meta:get_string("remote_channel"), |
| | | "fuel used", 6, true) |
| | | end |
| | | if meta:get_string("autostart") == "true" then |
| | | if not start_reactor(pos, meta) then |
| | | return |
| | | end |
| | | end |
| | |
| | | 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, "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.remote_channel then |
| | | meta:set_string("remote_channel", fields.remote_channel) |
| | | end |
| | | if fields.start then |
| | | local start_error_msg = start_reactor(pos, meta) |
| | | if not start_error_msg then |
| | | minetest.chat_send_player(player_name, "Start successful") |
| | | else |
| | | minetest.chat_send_player(player_name, start_error_msg) |
| | | 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_remote_def = function(pos, channel, msg) |
| | | local meta = minetest.get_meta(pos) |
| | | if meta:get_string("enable_digiline") ~= "true" or |
| | | channel ~= 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 |
| | | digiline_remote.send_to_node(pos, 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 |
| | | }, 6, true) |
| | | 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 start_error_msg = start_reactor(pos, meta) |
| | | if not start_error_msg then |
| | | digiline_remote.send_to_node(pos, channel, "Start successful", 6, true) |
| | | else |
| | | digiline_remote.send_to_node(pos, channel, start_error_msg, 6, true) |
| | | end |
| | | end |
| | | end |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core", { |
| | | description = reactor_desc, |
| | | tiles = {"technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {cracky=1, technic_machine=1, technic_hv=1}, |
| | | 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, digiline_remote_receive = 1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drawtype = "nodebox", |
| | | paramtype = "light", |
| | | paramtype2 = "facedir", |
| | | stack_max = 1, |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = node_box |
| | | }, |
| | | 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", reactor_formspec) |
| | | meta:set_string("formspec", make_reactor_formspec(meta)) |
| | | if digiline_remote_path then |
| | | meta:set_string("remote_channel", |
| | | "nucelear_reactor"..minetest.pos_to_string(pos)) |
| | | end |
| | | local inv = meta:get_inventory() |
| | | inv:set_size("src", 6) |
| | | end, |
| | | _on_digiline_remote_receive = digiline_remote_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, |
| | |
| | | }) |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core_active", { |
| | | tiles = {"technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {cracky=1, technic_machine=1, technic_hv=1, |
| | | radioactive=6, not_in_creative_inventory=1}, |
| | | 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, digiline_remote_receive = 1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop = "technic:hv_nuclear_reactor_core", |
| | | drawtype = "nodebox", |
| | | light_source = 14, |
| | | paramtype = "light", |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = node_box |
| | | }, |
| | | paramtype2 = "facedir", |
| | | on_receive_fields = nuclear_reactor_receive_fields, |
| | | _on_digiline_remote_receive = digiline_remote_def, |
| | | can_dig = technic.machine_can_dig, |
| | | after_dig_node = melt_down_reactor, |
| | | on_destruct = function(pos) siren_set_state(pos, SS_OFF) end, |
| | |
| | | technic_run = run, |
| | | technic_on_disable = function(pos, node) |
| | | local timer = minetest.get_node_timer(pos) |
| | | timer:start(1) |
| | | timer:start(1) |
| | | end, |
| | | on_timer = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |