2019-02-23 13:14:09 -05:00
|
|
|
-- LUALOCALS < ---------------------------------------------------------
|
|
|
|
local math, minetest, nodecore, pairs, vector
|
|
|
|
= math, minetest, nodecore, pairs, vector
|
2019-03-10 15:47:22 -04:00
|
|
|
local math_exp, math_random, math_sqrt
|
|
|
|
= math.exp, math.random, math.sqrt
|
2019-02-23 13:14:09 -05:00
|
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
|
2019-03-11 23:12:04 -04:00
|
|
|
local ppos = {}
|
2019-02-23 13:14:09 -05:00
|
|
|
local cache = {}
|
|
|
|
|
|
|
|
local function envcheck(player)
|
2019-03-11 23:12:04 -04:00
|
|
|
local pname = player:get_player_name()
|
|
|
|
|
|
|
|
if player:get_breath() < 11 then return end
|
2019-02-23 13:14:09 -05:00
|
|
|
|
|
|
|
local pos = player:getpos()
|
|
|
|
pos.y = pos.y + 1.6
|
|
|
|
|
2019-03-11 23:12:04 -04:00
|
|
|
local old = ppos[pname] or pos
|
|
|
|
ppos[pname] = pos
|
|
|
|
local moving = not vector.equals(pos, old)
|
|
|
|
|
|
|
|
local stats = {}
|
|
|
|
|
2019-02-23 13:14:09 -05:00
|
|
|
stats.light = minetest.get_node_light(pos)
|
|
|
|
|
|
|
|
local target = vector.add(pos, {
|
|
|
|
x = math_random() * 128 - 64,
|
|
|
|
y = math_random() * 128 - 64,
|
|
|
|
z = math_random() * 128 - 64
|
|
|
|
})
|
|
|
|
local _, hit = minetest.line_of_sight(pos, target)
|
|
|
|
hit = hit or target
|
|
|
|
|
|
|
|
stats.space = vector.distance(pos, hit)
|
|
|
|
|
|
|
|
local node = minetest.get_node(hit)
|
|
|
|
local def = minetest.registered_items[node.name]
|
|
|
|
local groups = def.groups or {}
|
|
|
|
|
|
|
|
stats.green = groups.green or 0
|
|
|
|
stats.water = groups.water or 0 + stats.green / 5
|
|
|
|
|
|
|
|
local agg = cache[pname]
|
|
|
|
if not agg then
|
|
|
|
agg = {}
|
|
|
|
local raw = player:get_attribute("healthenv")
|
|
|
|
if raw and raw ~= "" then
|
|
|
|
agg = minetest.deserialize(raw)
|
|
|
|
end
|
|
|
|
cache[pname] = agg
|
|
|
|
end
|
|
|
|
for k, v in pairs(stats) do
|
|
|
|
agg[k] = ((agg[k] or 0) * 99 + v) / 100
|
|
|
|
end
|
|
|
|
agg.dirty = (agg.dirty or 0) + 1
|
2019-03-01 00:15:29 -05:00
|
|
|
if agg.dirty >= 5 then
|
2019-02-23 13:14:09 -05:00
|
|
|
agg.dirty = nil
|
|
|
|
player:set_attribute("healthenv",
|
|
|
|
minetest.serialize(agg))
|
2019-03-10 15:47:22 -04:00
|
|
|
for k, v in pairs(agg) do
|
|
|
|
agg[k] = 1 - math_exp(-v)
|
|
|
|
end
|
|
|
|
local heal = 0.1
|
|
|
|
+ (agg.green * agg.green) * 4
|
|
|
|
+ (agg.water * agg.water) * 2
|
|
|
|
+ (agg.space * agg.space)
|
|
|
|
+ (agg.light * agg.light)
|
|
|
|
heal = math_sqrt(heal)
|
2019-03-11 23:12:04 -04:00
|
|
|
if moving then heal = heal / 2 end
|
2019-03-10 15:47:22 -04:00
|
|
|
nodecore.addphealth(player, heal)
|
2019-02-23 13:14:09 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2019-02-23 18:47:11 -05:00
|
|
|
minetest.register_on_dieplayer(function(player)
|
|
|
|
player:set_attribute("healthenv", "")
|
|
|
|
cache[player:get_player_name()] = nil
|
2019-02-23 17:52:23 -05:00
|
|
|
end)
|
|
|
|
|
2019-03-02 20:32:50 -05:00
|
|
|
local function timer()
|
|
|
|
minetest.after(0.5, timer)
|
|
|
|
for _, p in pairs(minetest.get_connected_players()) do
|
|
|
|
if p:get_hp() > 0 then envcheck(p) end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
timer()
|