313 lines
9.9 KiB
Lua
313 lines
9.9 KiB
Lua
local S = minetest.get_translator("surface_effect")
|
|
|
|
surface_effect.dump = function(o)
|
|
if type(o) == 'table' then
|
|
local s = '{ '
|
|
for k,v in pairs(o) do
|
|
if type(k) ~= 'number' then k = '"'..k..'"' end
|
|
s = s .. '['..k..'] = ' .. surface_effect.dump(v) .. ','
|
|
end
|
|
return s .. '} '
|
|
else
|
|
return tostring(o)
|
|
end
|
|
end
|
|
|
|
surface_effect.setHud = function(player)
|
|
local name = player:get_player_name()
|
|
|
|
if type(surface_effect.nplayer[name]) == 'nil' then
|
|
surface_effect.nplayer[name] = {
|
|
radiation_damage = false,
|
|
id_varning_text = false,
|
|
id_mask = false,
|
|
id_status_chemical = false,
|
|
}
|
|
minetest.log("action", "Load nplayer: " .. surface_effect.dump(surface_effect.nplayer))
|
|
end
|
|
end
|
|
|
|
--Состояние костюма химической защиты вывод в процентах.
|
|
surface_effect.getHazmatState = function(player)
|
|
local name, inv = armor:get_valid_player(player)
|
|
|
|
if not name then
|
|
return -- Armor not initialized yet
|
|
end
|
|
|
|
if not inv:contains_item("armor", "hazmat_suit:suit_hazmat") then
|
|
return -- Skip checking every stack
|
|
end
|
|
|
|
for i=1, inv:get_size("armor") do
|
|
local stack = inv:get_stack("armor", i)
|
|
|
|
if stack:get_name() == "hazmat_suit:suit_hazmat" then
|
|
local arm = 65535 / 100
|
|
local percent = (65535 - stack:get_wear()) / arm
|
|
|
|
--stack:add_wear(1)
|
|
--inv:set_stack("armor", i, stack)
|
|
--armor:save_armor_inventory(player)
|
|
return math.round(percent)
|
|
end
|
|
end
|
|
end
|
|
|
|
surface_effect.checkHazmat = function(player)
|
|
local armor = armor:get_weared_armor_elements (player)
|
|
surface_effect.getHazmatState(player)
|
|
|
|
if armor ~= 'nil' then
|
|
if type(armor) == 'nil' then return false end
|
|
|
|
if armor.head == "hazmat_suit:suit_hazmat" then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
surface_effect.radiaton_off = function(player)
|
|
local name = player:get_player_name()
|
|
|
|
if surface_effect.nplayer[name]["radiation_damage"] == true then
|
|
player:hud_remove(surface_effect.nplayer[name]['id_varning_text'])
|
|
|
|
surface_effect.nplayer[name]["radiation_damage"] = false
|
|
surface_effect.nplayer[name]["id_varning_text"] = false
|
|
end
|
|
end
|
|
|
|
--Защита от радиацйии
|
|
surface_effect.technic_forcefield_radiation_protection = function(pos, player)
|
|
if not minetest.get_modpath("technic") then return false end
|
|
|
|
local radius = 20
|
|
local protectors = minetest.find_nodes_in_area(
|
|
{x = pos.x - radius , y = pos.y - radius , z = pos.z - radius},
|
|
{x = pos.x + radius , y = pos.y + radius , z = pos.z + radius},
|
|
{"technic:forcefield_emitter_on"})
|
|
|
|
if #protectors > 0 then
|
|
local npos = protectors[1]
|
|
local meta = minetest.get_meta(npos)
|
|
local pos1 = vector.subtract(pos, npos)
|
|
local range = meta:get_int("range")
|
|
|
|
if math.round(pos1.x) < range and math.round(pos1.x) > 0 - range and
|
|
math.round(pos1.y) < range and math.round(pos1.y) > 0 - range and
|
|
math.round(pos1.z) < range and math.round(pos1.z) > 0 - range
|
|
then
|
|
surface_effect.radiaton_off(player)
|
|
return true
|
|
end
|
|
|
|
return false
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
surface_effect.mask = function(player)
|
|
local name = player:get_player_name()
|
|
|
|
if surface_effect.checkHazmat(player) == true and surface_effect.nplayer[name]["id_mask"] == false then
|
|
local id = player:hud_add({
|
|
name = "Radiation effect",
|
|
hud_elem_type = "image",
|
|
position = {x = 0.5, y = 0.5},
|
|
scale = {
|
|
x = -100,
|
|
y = -110
|
|
},
|
|
z_index = -100,
|
|
text = "surface_effect_mask.png"
|
|
})
|
|
|
|
surface_effect.nplayer[name]["id_status_chemical"] = player:hud_add({
|
|
name = "Chemical protection status indicator",
|
|
hud_elem_type = "text",
|
|
position = {x = 0.7, y = 0.1},
|
|
offset = {x = 90, y = -40},
|
|
scale = {
|
|
x = 50,
|
|
y = 10
|
|
},
|
|
z_index = -99,
|
|
size = 2,
|
|
text = S("Chemical protection status: @1%", surface_effect.getHazmatState(player)),
|
|
number = 0x000000
|
|
})
|
|
|
|
surface_effect.nplayer[name]["id_mask"] = id
|
|
|
|
elseif surface_effect.nplayer[name]["id_mask"] ~= false and surface_effect.checkHazmat(player) == false then
|
|
player:hud_remove(surface_effect.nplayer[name]['id_mask'])
|
|
surface_effect.nplayer[name]["id_mask"] = false
|
|
|
|
player:hud_remove(surface_effect.nplayer[name]['id_status_chemical'])
|
|
surface_effect.nplayer[name]["id_status_chemical"] = false
|
|
|
|
return
|
|
end
|
|
|
|
if surface_effect.nplayer[name]["id_status_chemical"] ~= false then
|
|
player:hud_change(surface_effect.nplayer[name]["id_status_chemical"],
|
|
"text", S("Chemical protection status: @1%", surface_effect.getHazmatState(player)))
|
|
end
|
|
|
|
return
|
|
end
|
|
|
|
su.rediationDomage = function (player, pos)
|
|
local name = player:get_player_name()
|
|
|
|
if pos.y > -40 and pos.y < 1500 then
|
|
if surface_effect.technic_forcefield_radiation_protection(pos,player) == true then
|
|
return
|
|
end
|
|
|
|
if surface_effect.detectNuclides(player) == true then
|
|
minetest.sound_play("surface_effect_radiaciya",{
|
|
gain = 1.0,
|
|
to_player = name,
|
|
})
|
|
end
|
|
|
|
persistent_api.add_persistent_effect({
|
|
name = "damage_player", -- identifier
|
|
object = player, -- affected object
|
|
duration = 10, -- this effect will last 10 seconds
|
|
effect = function(player)
|
|
|
|
if surface_effect.nplayer[name]['radiation_damage'] == false then
|
|
local idtext = player:hud_add({
|
|
name = "Attention! Radiation",
|
|
hud_elem_type = "text",
|
|
position = {x = 1, y = 0.5},
|
|
offset = {x = -180, y = 0},
|
|
text = S("Attention! High levels of radiation."),
|
|
alignment = -2,
|
|
scale = { x = 50, y = 10},
|
|
number = 0xFF0000,
|
|
})
|
|
|
|
--[[minetest.after(1.52, function(name, id)
|
|
local player = minetest.get_player_by_name(name)
|
|
if player then
|
|
--player:hud_remove(id)
|
|
else
|
|
-- player has left the game
|
|
end
|
|
end, player:get_player_name(), id)]]
|
|
|
|
surface_effect.nplayer[name]["id_varning_text"] = idtext
|
|
surface_effect.nplayer[name]["radiation_damage"] = true
|
|
end
|
|
|
|
if surface_effect.checkHazmat(player) == false then
|
|
player:set_hp(player:get_hp()-0.1) -- damage the player one half heart
|
|
end
|
|
|
|
end,
|
|
persistence = 2, -- every 0.1 seconds for 10 seconds the previous function will be run.
|
|
})
|
|
|
|
return
|
|
else
|
|
surface_effect.radiaton_off(player)
|
|
end
|
|
end
|
|
|
|
surface_effect.detectNuclides = function (player)
|
|
local inv = player:get_inventory()
|
|
if not inv:contains_item("main", "surface_effect:dosimeter") then
|
|
return false
|
|
end
|
|
|
|
for i=1, inv:get_size("main") do
|
|
local stack = inv:get_stack("main", i)
|
|
if stack:get_name() == "surface_effect:dosimeter" then
|
|
local meta = stack:get_meta()
|
|
local charge = meta:get_int("technic:charge")
|
|
|
|
minetest.log("action", "Detect nuclides, power: " .. charge)
|
|
if charge > 0 then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function battery_dosimeter(stack)
|
|
local meta = stack:get_meta()
|
|
local charge = meta:get_int("technic:charge")
|
|
|
|
minetest.log("action", "Dosimeter power: " .. charge)
|
|
|
|
if charge == -1 then return end
|
|
charge = charge - 1
|
|
|
|
if charge < 0 then
|
|
technic.set_RE_wear(stack, 0, 65535)
|
|
meta:set_int("technic:charge", -1)
|
|
return
|
|
end
|
|
|
|
if charge > 0 then
|
|
technic.set_RE_wear(stack, charge, 65535)
|
|
meta:set_int("technic:charge", charge)
|
|
return
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
surface_effect.update_inventory = function (player)
|
|
local inv = player:get_inventory()
|
|
if not inv:contains_item("main", "surface_effect:dosimeter") then
|
|
return -- Skip checking every stack
|
|
end
|
|
|
|
for i=1, inv:get_size("main") do
|
|
local stack = inv:get_stack("main", i)
|
|
if stack:get_name() == "surface_effect:dosimeter" then
|
|
battery_dosimeter(stack)
|
|
|
|
inv:set_stack("main", i, stack)
|
|
end
|
|
end
|
|
end
|
|
|
|
surface_effect.technicDetectUranium = function(player)
|
|
local pos = player:get_pos()
|
|
local radius = 20
|
|
local protectors = minetest.find_nodes_in_area(
|
|
{x = pos.x - radius , y = pos.y - radius , z = pos.z - radius},
|
|
{x = pos.x + radius , y = pos.y + radius , z = pos.z + radius},
|
|
{"technic:uranium35_block"})
|
|
|
|
if #protectors > 0 then
|
|
local npos = protectors[1]
|
|
local meta = minetest.get_meta(npos)
|
|
local pos1 = vector.subtract(pos, npos)
|
|
|
|
if surface_effect.detectNuclides(player) then
|
|
minetest.log("action", "Radiation detect technic " .. surface_effect.dump(protectors[1]))
|
|
|
|
minetest.sound_play({name = "radiant_damage_geiger",
|
|
--gain = math.min(1, damage/10)
|
|
gain = 1.0
|
|
}, {
|
|
to_player=player:get_player_name()
|
|
})
|
|
end
|
|
end
|
|
end
|