summaryrefslogtreecommitdiff
path: root/technic/radiation.lua
diff options
context:
space:
mode:
authorShadowNinja <shadowninja@minetest.net>2016-03-21 20:46:13 -0400
committerShadowNinja <shadowninja@minetest.net>2017-01-28 17:51:14 -0500
commit06dec2032628b475c4f02dfc9e92a58788d0912d (patch)
tree94a7ae1b9b85d0ef0a5f0e04a6f1d9b1d60d0e57 /technic/radiation.lua
parent1da213a5e470a726dce5db0ea1d8665527cccd33 (diff)
Add longer-term radiation damage
Radiation now slowly damages you for a while after exposure, with the effect's time and intensity proportional to the amount of radiation received. The radioactivity of some items is reduced to account for the increased damage.
Diffstat (limited to 'technic/radiation.lua')
-rw-r--r--technic/radiation.lua68
1 files changed, 51 insertions, 17 deletions
diff --git a/technic/radiation.lua b/technic/radiation.lua
index 2dec38b..ac3f166 100644
--- a/technic/radiation.lua
+++ b/technic/radiation.lua
@@ -230,39 +230,53 @@ readily available in cubes. The multiplicative factor in the
formula scales down the difference between shielded and unshielded
safe distances, avoiding the latter becoming impractically large.
-Damage is processed at rates down to 0.25 HP/s, which in the absence of
+Damage is processed at rates down to 0.2 HP/s, which in the absence of
shielding is attained at the distance specified by the "radioactive"
-group value. Computed damage rates below 0.25 HP/s result in no
+group value. Computed damage rates below 0.2 HP/s result in no
damage at all to the player. This gives the player an opportunity
to be safe, and limits the range at which source/player interactions
need to be considered.
--]]
local abdomen_offset = 1
local cache_scaled_shielding = {}
-local rad_dmg_cutoff = 0.25
+local rad_dmg_cutoff = 0.2
+local radiated_players = {}
-local function dmg_player(pos, o, strength)
- local pl_pos = o:getpos()
+local function apply_fractional_damage(o, dmg)
+ local dmg_int = math.floor(dmg)
+ -- The closer you are to getting one more damage point,
+ -- the more likely it will be added.
+ if math.random() < dmg - dmg_int then
+ dmg_int = dmg_int + 1
+ end
+ if dmg_int > 0 then
+ local new_hp = math.max(o:get_hp() - dmg_int, 0)
+ o:set_hp(new_hp)
+ return new_hp == 0
+ end
+ return false
+end
+
+local function dmg_player(pos, player, strength)
+ local pl_pos = player:getpos()
pl_pos.y = pl_pos.y + abdomen_offset
local shielding = 0
local dist = vector.distance(pos, pl_pos)
+
for ray_pos in technic.trace_node_ray(pos,
vector.direction(pos, pl_pos), dist) do
local shield_name = minetest.get_node(ray_pos).name
shielding = shielding + node_radiation_resistance(shield_name) * 0.1
end
+
local dmg = (strength * strength) /
(math.max(0.75, dist * dist) * math.exp(shielding))
+
if dmg < rad_dmg_cutoff then return end
- local dmg_int = math.floor(dmg)
- -- The closer you are to getting one more damage point,
- -- the more likely it will be added.
- if math.random() < dmg - 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
+ apply_fractional_damage(player, dmg)
+
+ local pn = player:get_player_name()
+ radiated_players[pn] = (radiated_players[pn] or 0) + dmg
end
local rad_dmg_mult_sqrt = math.sqrt(1 / rad_dmg_cutoff)
@@ -277,7 +291,6 @@ local function dmg_abm(pos, node)
end
end
-
if minetest.setting_getbool("enable_damage") then
minetest.register_abm({
nodenames = {"group:radioactive"},
@@ -285,6 +298,27 @@ if minetest.setting_getbool("enable_damage") then
chance = 1,
action = dmg_abm,
})
+
+ minetest.register_globalstep(function(dtime)
+ for pn, dmg in pairs(radiated_players) do
+ dmg = dmg - (dtime / 8)
+ local player = minetest.get_player_by_name(pn)
+ local killed
+ if player and dmg > rad_dmg_cutoff then
+ killed = apply_fractional_damage(player, (dmg * dtime) / 8)
+ else
+ dmg = nil
+ end
+ -- on_dieplayer will have already set this if the player died
+ if not killed then
+ radiated_players[pn] = dmg
+ end
+ end
+ end)
+
+ minetest.register_on_dieplayer(function(player)
+ radiated_players[player:get_player_name()] = nil
+ end)
end
-- Radioactive materials that can result from destroying a reactor
@@ -323,7 +357,7 @@ for _, state in pairs({"flowing", "source"}) do
liquid = 2,
hot = 3,
igniter = (griefing and 1 or 0),
- radioactive = (state == "source" and 16 or 8),
+ radioactive = (state == "source" and 12 or 6),
not_in_creative_inventory = (state == "flowing" and 1 or nil),
},
})
@@ -343,7 +377,7 @@ minetest.register_node("technic:chernobylite_block", {
description = S("Chernobylite Block"),
tiles = {"technic_chernobylite_block.png"},
is_ground_content = true,
- groups = {cracky=1, radioactive=6, level=2},
+ groups = {cracky=1, radioactive=4, level=2},
sounds = default.node_sound_stone_defaults(),
light_source = 2,
})