summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornumber Zero <silverunicorn2011@yandex.ru>2016-04-08 21:53:43 +0300
committerShadowNinja <shadowninja@minetest.net>2017-02-25 20:55:15 -0500
commit1810f417d2028f84dbed31038edf674cbfc50e1c (patch)
treeef5f81b1808724eb35cefe0798289915a9792ed4
parent4888581bee50a72d68feb4401c37540405f92062 (diff)
Radiation improved
Now it is applied to mobs too. Moreover, it should now respect "radiation" armor group, or fall back to "fleshy" group to detect vulnerable things
-rw-r--r--technic/radiation.lua56
1 files changed, 44 insertions, 12 deletions
diff --git a/technic/radiation.lua b/technic/radiation.lua
index ac3f166..033f4a8 100644
--- a/technic/radiation.lua
+++ b/technic/radiation.lua
@@ -257,14 +257,12 @@ local function apply_fractional_damage(o, dmg)
return false
end
-local function dmg_player(pos, player, strength)
- local pl_pos = player:getpos()
- pl_pos.y = pl_pos.y + abdomen_offset
+local function calculate_base_damage(node_pos, object_pos, strength)
local shielding = 0
- local dist = vector.distance(pos, pl_pos)
+ local dist = vector.distance(node_pos, object_pos)
- for ray_pos in technic.trace_node_ray(pos,
- vector.direction(pos, pl_pos), dist) do
+ for ray_pos in technic.trace_node_ray(node_pos,
+ vector.direction(node_pos, object_pos), dist) do
local shield_name = minetest.get_node(ray_pos).name
shielding = shielding + node_radiation_resistance(shield_name) * 0.1
end
@@ -273,10 +271,46 @@ local function dmg_player(pos, player, strength)
(math.max(0.75, dist * dist) * math.exp(shielding))
if dmg < rad_dmg_cutoff then return end
- apply_fractional_damage(player, dmg)
+ return dmg
+end
+
+local function calculate_damage_multiplier(object)
+ local ag = object.get_armor_groups and object:get_armor_groups()
+ if not ag then
+ return 0
+ end
+ if ag.radiation then
+ return 0.01 * ag.radiation
+ end
+ if ag.fleshy then
+ return math.sqrt(0.01 * ag.fleshy)
+ end
+ return 0
+end
- local pn = player:get_player_name()
- radiated_players[pn] = (radiated_players[pn] or 0) + dmg
+local function calculate_object_center(object)
+ if object:is_player() then
+ return {x=0, y=abdomen_offset, z=0}
+ end
+ return {x=0, y=0, z=0}
+end
+
+local function dmg_object(pos, object, strength)
+ local obj_pos = vector.add(object:getpos(), calculate_object_center(object))
+ local dmg = calculate_base_damage(pos, obj_pos, strength)
+ if not dmg then
+ return
+ end
+ local mul = calculate_damage_multiplier(object)
+ if mul == 0 then
+ return
+ end
+ dmg = dmg * mul
+ apply_fractional_damage(object, dmg)
+ if object:is_player() then
+ local pn = object:get_player_name()
+ radiated_players[pn] = (radiated_players[pn] or 0) + dmg
+ end
end
local rad_dmg_mult_sqrt = math.sqrt(1 / rad_dmg_cutoff)
@@ -285,9 +319,7 @@ local function dmg_abm(pos, node)
local max_dist = strength * rad_dmg_mult_sqrt
for _, o in pairs(minetest.get_objects_inside_radius(pos,
max_dist + abdomen_offset)) do
- if o:is_player() then
- dmg_player(pos, o, strength)
- end
+ dmg_object(pos, o, strength)
end
end