Grace period before reactor meltdown

The meltdown check now doesn't trigger meltdown immediately on reactor
structure being compromised.  Instead, there's a grace period of up to
100 s, during which the reactor can be repaired.  The check doesn't just
look at whether the structure is damaged at all: it looks at how damaged
it is, counting the number of faulty nodes.  The amount of damage is
integrated over time, and the grace period is actually 100 node-seconds,
so greater damage causes meltdown more quickly.  If the active core is
dug then it melts down immediately, preventing the tactic of digging
the core to avert meltdown.

Incidentally move the meltdown check into its own ABM, from the
technic_run callback, so that it applies even when the reactor is not
connected to a switching station.
This commit is contained in:
Zefram 2014-07-25 14:24:25 +01:00
parent ec008d7045
commit 67b90f3ad1
1 changed files with 35 additions and 13 deletions

View File

@ -54,7 +54,7 @@ local nodebox = {
{ -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 }, { -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 },
} }
local check_reactor_structure = function(pos) local reactor_structure_badness = function(pos)
-- The reactor consists of a 9x9x9 cube structure -- The reactor consists of a 9x9x9 cube structure
-- A cross section through the middle: -- A cross section through the middle:
-- CCCC CCCC -- CCCC CCCC
@ -119,19 +119,41 @@ local check_reactor_structure = function(pos)
end end
end end
end end
if waterlayer >= 25 and if waterlayer > 25 then waterlayer = 25 end
steellayer >= 96 and if steellayer > 96 then steellayer = 96 end
blastlayer >= 216 and if blastlayer > 216 then blastlayer = 216 end
concretelayer >= 384 then if concretelayer > 384 then concretelayer = 384 end
return true return (25 - waterlayer) + (96 - steellayer) + (216 - blastlayer) + (384 - concretelayer)
end
end end
local explode_reactor = function(pos) local function meltdown_reactor(pos)
print("A reactor exploded at "..minetest.pos_to_string(pos)) print("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 end
minetest.register_abm({
nodenames = {"technic:hv_nuclear_reactor_core_active"},
interval = 1,
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", accum_badness - 1)
end
else
accum_badness = accum_badness + badness
if accum_badness >= 100 then
meltdown_reactor(pos)
else
meta:set_int("structure_accumulated_badness", accum_badness)
end
end
end,
})
local run = function(pos, node) local run = function(pos, node)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local machine_name = S("Nuclear %s Generator Core"):format("HV") local machine_name = S("Nuclear %s Generator Core"):format("HV")
@ -152,7 +174,7 @@ local run = function(pos, node)
-- Check that the reactor is complete as well -- Check that the reactor is complete as well
-- as the correct number of correct fuel -- as the correct number of correct fuel
if correct_fuel_count == 6 and if correct_fuel_count == 6 and
check_reactor_structure(pos) then reactor_structure_badness(pos) == 0 then
meta:set_int("burn_time", 1) meta:set_int("burn_time", 1)
technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active") technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active")
meta:set_int("HV_EU_supply", power_supply) meta:set_int("HV_EU_supply", power_supply)
@ -167,10 +189,8 @@ local run = function(pos, node)
meta:set_int("burn_time", 0) meta:set_int("burn_time", 0)
meta:set_string("infotext", S("%s Idle"):format(machine_name)) meta:set_string("infotext", S("%s Idle"):format(machine_name))
technic.swap_node(pos, "technic:hv_nuclear_reactor_core") technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
meta:set_int("structure_accumulated_badness", 0)
elseif burn_time > 0 then elseif burn_time > 0 then
if not check_reactor_structure(pos) then
explode_reactor(pos)
end
burn_time = burn_time + 1 burn_time = burn_time + 1
meta:set_int("burn_time", burn_time) meta:set_int("burn_time", burn_time)
local percent = math.floor(burn_time / burn_ticks * 100) local percent = math.floor(burn_time / burn_ticks * 100)
@ -229,6 +249,7 @@ minetest.register_node("technic:hv_nuclear_reactor_core_active", {
fixed = nodebox fixed = nodebox
}, },
can_dig = technic.machine_can_dig, can_dig = technic.machine_can_dig,
after_dig_node = meltdown_reactor,
allow_metadata_inventory_put = technic.machine_inventory_put, allow_metadata_inventory_put = technic.machine_inventory_put,
allow_metadata_inventory_take = technic.machine_inventory_take, allow_metadata_inventory_take = technic.machine_inventory_take,
allow_metadata_inventory_move = technic.machine_inventory_move, allow_metadata_inventory_move = technic.machine_inventory_move,
@ -249,6 +270,7 @@ minetest.register_node("technic:hv_nuclear_reactor_core_active", {
meta:set_int("HV_EU_supply", 0) meta:set_int("HV_EU_supply", 0)
meta:set_int("burn_time", 0) meta:set_int("burn_time", 0)
technic.swap_node(pos, "technic:hv_nuclear_reactor_core") technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
meta:set_int("structure_accumulated_badness", 0)
return return
end end