diff options
author | number Zero <silverunicorn2011@yandex.ru> | 2016-04-08 21:53:43 +0300 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2017-02-25 20:55:15 -0500 |
commit | 1810f417d2028f84dbed31038edf674cbfc50e1c (patch) | |
tree | ef5f81b1808724eb35cefe0798289915a9792ed4 /technic/radiation.lua | |
parent | 4888581bee50a72d68feb4401c37540405f92062 (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
Diffstat (limited to 'technic/radiation.lua')
-rw-r--r-- | technic/radiation.lua | 56 |
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 |