Tweak radioactivity

This simplifies radioactivity by removing the 1000 and 0.25 multipliers.
It also increases the effectiveness of protection (I think it was too low
before -- most of the advantage of adding protective layers was just from
the increased distance).
This commit is contained in:
ShadowNinja 2016-03-21 03:14:08 -04:00
parent 8ccb6d97ec
commit 26de2f7c88
3 changed files with 54 additions and 49 deletions

@ -194,14 +194,16 @@ for p = 0, 35 do
-- a natural (0.7%-fissile) uranium block having the activity of -- a natural (0.7%-fissile) uranium block having the activity of
-- 9 uranium ore blocks (due to 9 ingots per block). The group -- 9 uranium ore blocks (due to 9 ingots per block). The group
-- value is proportional to the square root of the activity, and -- value is proportional to the square root of the activity, and
-- uranium ore has radioactive=1000. This yields radioactive=2065 -- uranium ore has radioactive=1. This yields radioactive=1.0
-- for a fully-depleted uranium block and radioactive=5286 for -- for a fully-depleted uranium block and radioactive=2.6 for
-- a 3.5%-fissile uranium block. -- a 3.5%-fissile uranium block.
local radioactivity = math.floor(math.sqrt((1+5.55*p/35) * 18 / (1+5.55*7/35)) + 0.5);
(ov or minetest.register_node)(block, { (ov or minetest.register_node)(block, {
description = string.format(S("%.1f%%-Fissile Uranium Block"), p/10), description = string.format(S("%.1f%%-Fissile Uranium Block"), p/10),
tiles = {"technic_uranium_block.png"}, tiles = {"technic_uranium_block.png"},
is_ground_content = true, is_ground_content = true,
groups = {uranium_block=1, not_in_creative_inventory=nici, cracky=1, level=2, radioactive=math.floor(1000*math.sqrt((1+5.55*p/35) * 9 / (1+5.55*7/35)) + 0.5)}, groups = {uranium_block=1, not_in_creative_inventory=nici,
cracky=1, level=2, radioactive=radioactivity},
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}); });
if not ov then if not ov then
@ -219,3 +221,4 @@ for p = 0, 35 do
}) })
end end
end end

@ -318,7 +318,7 @@ minetest.register_node("technic:hv_nuclear_reactor_core", {
minetest.register_node("technic:hv_nuclear_reactor_core_active", { minetest.register_node("technic:hv_nuclear_reactor_core_active", {
tiles = {"technic_hv_nuclear_reactor_core.png"}, tiles = {"technic_hv_nuclear_reactor_core.png"},
groups = {cracky=1, technic_machine=1, technic_hv=1, groups = {cracky=1, technic_machine=1, technic_hv=1,
radioactive=11000, not_in_creative_inventory=1}, radioactive=6, not_in_creative_inventory=1},
legacy_facedir_simple = true, legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
drop = "technic:hv_nuclear_reactor_core", drop = "technic:hv_nuclear_reactor_core",
@ -395,7 +395,7 @@ or complex internal structure should show no radiation resistance.
Fractional resistance values are permitted. Fractional resistance values are permitted.
--]] --]]
local default_radiation_resistance_per_node = { local rad_resistance_node = {
["default:brick"] = 13, ["default:brick"] = 13,
["default:bronzeblock"] = 45, ["default:bronzeblock"] = 45,
["default:clay"] = 15, ["default:clay"] = 15,
@ -524,7 +524,7 @@ local default_radiation_resistance_per_node = {
["tnt:tnt"] = 11, ["tnt:tnt"] = 11,
["tnt:tnt_burning"] = 11, ["tnt:tnt_burning"] = 11,
} }
local default_radiation_resistance_per_group = { local rad_resistance_group = {
concrete = 16, concrete = 16,
tree = 3.4, tree = 3.4,
uranium_block = 500, uranium_block = 500,
@ -532,24 +532,31 @@ local default_radiation_resistance_per_group = {
} }
local cache_radiation_resistance = {} local cache_radiation_resistance = {}
local function node_radiation_resistance(node_name) local function node_radiation_resistance(node_name)
local eff = cache_radiation_resistance[node_name] local resistance = cache_radiation_resistance[node_name]
if eff then return eff end if resistance then
return resistance
end
local def = minetest.registered_nodes[node_name] local def = minetest.registered_nodes[node_name]
eff = def and def.radiation_resistance or if not def then
default_radiation_resistance_per_node[node_name] cache_radiation_resistance[node_name] = 0
if def and not eff then return 0
end
resistance = def.radiation_resistance or
rad_resistance_node[node_name]
if not resistance then
resistance = 0
for g, v in pairs(def.groups) do for g, v in pairs(def.groups) do
if v > 0 and default_radiation_resistance_per_group[g] then if v > 0 and rad_resistance_group[g] then
eff = default_radiation_resistance_per_group[g] resistance = resistance + rad_resistance_group[g]
break
end end
end end
end end
if not eff then eff = 0 end resistance = math.sqrt(resistance)
cache_radiation_resistance[node_name] = eff cache_radiation_resistance[node_name] = resistance
return eff return resistance
end end
--[[ --[[
Radioactive nodes cause damage to nearby players. The damage Radioactive nodes cause damage to nearby players. The damage
effect depends on the intrinsic strength of the radiation source, effect depends on the intrinsic strength of the radiation source,
@ -570,10 +577,10 @@ the maximum distance one can get from the node center within the node.
A radioactive node is identified by being in the "radioactive" group, A radioactive node is identified by being in the "radioactive" group,
and the group value signifies the strength of the radiation source. and the group value signifies the strength of the radiation source.
The group value is 1000 times the distance from a node at which The group value is the distance from a node at which an unshielded
an unshielded player will be damaged by 0.25 HP/s. Or, equivalently, player will be damaged by 1 HP/s. Or, equivalently, it is the square
it is 2000 times the square root of the damage rate in HP/s that an root of the damage rate in HP/s that an unshielded player one node
unshielded player 1 node away will take. away will take.
Shielding is assessed by adding the shielding values of all nodes Shielding is assessed by adding the shielding values of all nodes
between the source node and the player, ignoring the source node itself. between the source node and the player, ignoring the source node itself.
@ -595,45 +602,40 @@ damage at all to the player. This gives the player an opportunity
to be safe, and limits the range at which source/player interactions to be safe, and limits the range at which source/player interactions
need to be considered. need to be considered.
--]] --]]
local abdomen_offset = vector.new(0, 1, 0) local abdomen_offset = 1
local abdomen_offset_length = vector.length(abdomen_offset)
local cache_scaled_shielding = {} local cache_scaled_shielding = {}
local rad_dmg_cutoff = 0.25
local function dmg_player(pos, o, strength) local function dmg_player(pos, o, strength)
local pl_pos = vector.add(o:getpos(), abdomen_offset) local pl_pos = o:getpos()
pl_pos.y = pl_pos.y + abdomen_offset
local shielding = 0 local shielding = 0
local dist = vector.distance(pos, pl_pos) local dist = vector.distance(pos, pl_pos)
for ray_pos in technic.trace_node_ray(pos, for ray_pos in technic.trace_node_ray(pos,
vector.direction(pos, pl_pos), dist) do vector.direction(pos, pl_pos), dist) do
if not vector.equals(ray_pos, pos) then local shield_name = minetest.get_node(ray_pos).name
local shield_name = minetest.get_node(ray_pos).name shielding = shielding + node_radiation_resistance(shield_name) * 0.1
local shield_val = cache_scaled_shielding[sname]
if not shield_val then
shield_val = math.sqrt(node_radiation_resistance(shield_name)) * 0.025
cache_scaled_shielding[shield_name] = shield_val
end
shielding = shielding + shield_val
end
end end
local dmg = (0.25e-6 * strength * strength) / local dmg = (strength * strength) /
(math.max(0.75, dist * dist) * math.exp(shielding)) (math.max(0.75, dist * dist) * math.exp(shielding))
if dmg >= 0.25 then if dmg < rad_dmg_cutoff then return end
local dmg_int = math.floor(dmg) local dmg_int = math.floor(dmg)
-- The closer you are to getting one more damage point, -- The closer you are to getting one more damage point,
-- the more likely it will be added. -- the more likely it will be added.
if math.random() < dmg - dmg_int then if math.random() < dmg - dmg_int then
dmg_int = dmg_int + 1 dmg_int = dmg_int + 1
end end
if dmg_int > 0 then if dmg_int > 0 then
o:set_hp(math.max(o:get_hp() - dmg_int, 0)) o:set_hp(math.max(o:get_hp() - dmg_int, 0))
end
end end
end end
local rad_dmg_mult_sqrt = math.sqrt(1 / rad_dmg_cutoff)
local function dmg_abm(pos, node) local function dmg_abm(pos, node)
local strength = minetest.get_item_group(node.name, "radioactive") local strength = minetest.get_item_group(node.name, "radioactive")
local max_dist = strength * rad_dmg_mult_sqrt
for _, o in pairs(minetest.get_objects_inside_radius(pos, for _, o in pairs(minetest.get_objects_inside_radius(pos,
strength * 0.001 + abdomen_offset_length)) do max_dist + abdomen_offset)) do
if o:is_player() then if o:is_player() then
dmg_player(pos, o, strength) dmg_player(pos, o, strength)
end end
@ -686,7 +688,7 @@ for _, state in pairs({"flowing", "source"}) do
liquid = 2, liquid = 2,
hot = 3, hot = 3,
igniter = (griefing and 1 or 0), igniter = (griefing and 1 or 0),
radioactive = (state == "source" and 32000 or 16000), radioactive = (state == "source" and 16 or 8),
not_in_creative_inventory = (state == "flowing" and 1 or nil), not_in_creative_inventory = (state == "flowing" and 1 or nil),
}, },
}) })
@ -706,7 +708,7 @@ minetest.register_node("technic:chernobylite_block", {
description = S("Chernobylite Block"), description = S("Chernobylite Block"),
tiles = {"technic_chernobylite_block.png"}, tiles = {"technic_chernobylite_block.png"},
is_ground_content = true, is_ground_content = true,
groups = {cracky=1, radioactive=5000, level=2}, groups = {cracky=1, radioactive=6, level=2},
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
light_source = 2, light_source = 2,
}) })

@ -5,7 +5,7 @@ minetest.register_node( ":technic:mineral_uranium", {
description = S("Uranium Ore"), description = S("Uranium Ore"),
tiles = { "default_stone.png^technic_mineral_uranium.png" }, tiles = { "default_stone.png^technic_mineral_uranium.png" },
is_ground_content = true, is_ground_content = true,
groups = {cracky=3, radioactive=1000}, groups = {cracky=3, radioactive=1},
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
drop = "technic:uranium_lump", drop = "technic:uranium_lump",
}) })
@ -74,7 +74,7 @@ minetest.register_node(":technic:uranium_block", {
description = S("Uranium Block"), description = S("Uranium Block"),
tiles = { "technic_uranium_block.png" }, tiles = { "technic_uranium_block.png" },
is_ground_content = true, is_ground_content = true,
groups = {uranium_block=1, cracky=1, level=2, radioactive=3000}, groups = {uranium_block=1, cracky=1, level=2, radioactive=2},
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}) })