est31
2015-06-18 a793747d92d9b1d93153c7fb4e0c82fe90624c78
technic/machines/HV/nuclear_reactor.lua
@@ -32,7 +32,8 @@
   "invsize[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;]"
   "list[current_player;main;0,5;8,4;]"..
   "listring[]"
-- "Boxy sphere"
local nodebox = {
@@ -319,7 +320,7 @@
      local meta = minetest.get_meta(pos)
      
      -- Connected back?
      if meta:get_int("HV_EU_timeout") > 0 then return end
      if meta:get_int("HV_EU_timeout") > 0 then return false end
      
      local burn_time = meta:get_int("burn_time") or 0
@@ -329,12 +330,11 @@
         technic.swap_node(pos, "technic:hv_nuclear_reactor_core")
         meta:set_int("structure_accumulated_badness", 0)
         siren_clear(pos, meta)
         return
         return false
      end
      
      meta:set_int("burn_time", burn_time + 1)
      local timer = minetest.get_node_timer(pos)
           timer:start(1)
      return true
   end,
})
@@ -543,7 +543,7 @@
-- and the group value signifies the strength of the radiation source.
-- The group value is the distance in millimetres from a node at which
-- an unshielded player will be damaged by 0.25 HP/s.  Or, equivalently,
-- it is 500 times the square root of the damage rate in HP/s that an
-- it is 2000 times the square root of the damage rate in HP/s that an
-- unshielded player 1 m away will take.
--
-- Shielding is assessed by sampling every 0.25 m along the path
@@ -570,47 +570,52 @@
local assumed_abdomen_offset = vector.new(0, 1, 0)
local assumed_abdomen_offset_length = vector.length(assumed_abdomen_offset)
local cache_scaled_shielding = {}
minetest.register_abm({
   nodenames = {"group:radioactive"},
   interval = 1,
   chance = 1,
   action = function (pos, node)
      local strength = minetest.registered_nodes[node.name].groups.radioactive
      for _, o in ipairs(minetest.get_objects_inside_radius(pos, strength*0.001 + assumed_abdomen_offset_length)) do
         if o:is_player() then
            local rel = vector.subtract(vector.add(o:getpos(), assumed_abdomen_offset), pos)
            local dist_sq = vector.length_square(rel)
            local dist = math.sqrt(dist_sq)
            local dirstep = dist == 0 and vector.new(0,0,0) or vector.divide(rel, dist*4)
            local intpos = pos
            local shielding = 0
            for intdist = 0.25, dist, 0.25 do
               intpos = vector.add(intpos, dirstep)
               local intnodepos = vector.round(intpos)
               if not vector.equals(intnodepos, pos) then
                  local sname = minetest.get_node(intnodepos).name
                  local sval = cache_scaled_shielding[sname]
                  if not sval then
                     sval = math.sqrt(node_radiation_resistance(sname)) * -0.025
                     cache_scaled_shielding[sname] = sval
local damage_enabled = minetest.setting_getbool("enable_damage")
if damage_enabled then
   minetest.register_abm({
      nodenames = {"group:radioactive"},
      interval = 1,
      chance = 1,
      action = function (pos, node)
         local strength = minetest.registered_nodes[node.name].groups.radioactive
         for _, o in ipairs(minetest.get_objects_inside_radius(pos, strength*0.001 + assumed_abdomen_offset_length)) do
            if o:is_player() then
               local rel = vector.subtract(vector.add(o:getpos(), assumed_abdomen_offset), pos)
               local dist_sq = vector.length_square(rel)
               local dist = math.sqrt(dist_sq)
               local dirstep = dist == 0 and vector.new(0,0,0) or vector.divide(rel, dist*4)
               local intpos = pos
               local shielding = 0
               for intdist = 0.25, dist, 0.25 do
                  intpos = vector.add(intpos, dirstep)
                  local intnodepos = vector.round(intpos)
                  if not vector.equals(intnodepos, pos) then
                     local sname = minetest.get_node(intnodepos).name
                     local sval = cache_scaled_shielding[sname]
                     if not sval then
                        sval = math.sqrt(node_radiation_resistance(sname)) * -0.025
                        cache_scaled_shielding[sname] = sval
                     end
                     shielding = shielding + sval
                  end
                  shielding = shielding + sval
               end
            end
            local dmg_rate = 0.25e-6 * strength*strength * math.exp(shielding) / math.max(0.75, dist_sq)
            if dmg_rate >= 0.25 then
               local dmg_int = math.floor(dmg_rate)
               if math.random() < dmg_rate-dmg_int then
                  dmg_int = dmg_int + 1
               end
               if dmg_int > 0 then
                  o:set_hp(math.max(o:get_hp() - dmg_int, 0))
               local dmg_rate = 0.25e-6 * strength*strength * math.exp(shielding) / math.max(0.75, dist_sq)
               if dmg_rate >= 0.25 then
                  local dmg_int = math.floor(dmg_rate)
                  if math.random() < dmg_rate-dmg_int then
                     dmg_int = dmg_int + 1
                  end
                  if dmg_int > 0 then
                     o:set_hp(math.max(o:get_hp() - dmg_int, 0))
                  end
               end
            end
         end
      end
   end,
})
      end,
   })
end
-- radioactive materials that can result from destroying a reactor