2019-02-27 22:35:23 -05:00

120 lines
3.0 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, vector
= math, minetest, nodecore, pairs, vector
local math_random, math_sqrt
= math.random, math.sqrt
-- LUALOCALS > ---------------------------------------------------------
local cache = {}
local function envcheck(player)
local stats = {}
local pos = player:getpos()
pos.y = pos.y + 1.6
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 pname = player:get_player_name()
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
if agg.dirty >= 20 then
agg.dirty = nil
player:set_attribute("healthenv",
minetest.serialize(agg))
nodecore.addphealth(player, 0.01 + (agg.green + 0.02)
* (agg.water + 0.1)
* (agg.space + 5)
* (agg.light + 8) / 240)
end
end
local function setspeed(player, speed)
if speed > 1 then speed = 1 end
if speed < 0 then speed = 0 end
local phys = player:get_physics_override()
if phys.speed == speed then return end
phys.speed = speed
return player:set_physics_override(phys)
end
local function mobility(player)
local health = nodecore.getphealth(player) / 20
if health >= 1 then return setspeed(player, 1) end
local inv = player:get_inventory()
local encumb = 0
local invsize = inv:get_size("main")
for i = 1, invsize do
if not inv:get_stack("main", i):is_empty() then
encumb = encumb + 1
end
end
encumb = encumb / invsize
if encumb <= health then return setspeed(player, 1) end
return setspeed(player, 1 - math_sqrt(encumb - health) * 0.8)
end
local t = 0
minetest.register_globalstep(function(dt)
t = t + dt
while t > 0.1 do
t = t - 0.1
for _, player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 then
envcheck(player)
mobility(player)
end
end
end
end)
minetest.register_on_dieplayer(function(player)
local inv = player:get_inventory()
local pos = player:getpos()
for i = 1, inv:get_size("main") do
nodecore.item_eject(pos, inv:get_stack("main", i), 10)
end
inv:set_list("main", {})
-- flush attributes
player:set_attribute("healthenv", "")
cache[player:get_player_name()] = nil
player:set_attribute("dhp", "0")
end)
minetest.register_on_respawnplayer(function(player)
nodecore.setphealth(player, 0.0001)
mobility(player)
end)