137 lines
4.0 KiB
Lua
137 lines
4.0 KiB
Lua
local MOD_NAME = minetest.get_current_modname() or "exertion";
|
|
local MOD_PATH = minetest.get_modpath(MOD_NAME);
|
|
|
|
local exertion = { MOD_NAME = MOD_NAME, MOD_PATH = MOD_PATH };
|
|
_G[MOD_NAME] = exertion;
|
|
|
|
|
|
local function callFile(fileName, ...)
|
|
local chunk, err = loadfile(MOD_PATH .. "/" .. fileName);
|
|
if not chunk then error(err); end;
|
|
return chunk(...);
|
|
end;
|
|
|
|
|
|
local settings = callFile("loadSettings.lua", exertion);
|
|
exertion.settings = settings;
|
|
|
|
local PlayerState = callFile("PlayerState.lua", exertion);
|
|
exertion.PlayerState = PlayerState;
|
|
|
|
|
|
PlayerState.load();
|
|
local playerStates = {};
|
|
|
|
--- Retrieves the PlayerState object for a given player. Returns nil if player
|
|
-- is not logged in.
|
|
--
|
|
-- @param player
|
|
-- A player object or player name.
|
|
--
|
|
function exertion.getPlayerState(player)
|
|
if type(player) == 'string' then
|
|
player = minetest.get_player_by_name(player);
|
|
end;
|
|
return playerStates[player];
|
|
end;
|
|
|
|
minetest.register_on_joinplayer(
|
|
function(player)
|
|
minetest.after(
|
|
0, function() playerStates[player] = PlayerState(player); end);
|
|
end);
|
|
|
|
minetest.register_on_leaveplayer(
|
|
function(player)
|
|
playerStates[player] = nil;
|
|
end);
|
|
|
|
minetest.register_on_dieplayer(
|
|
function(player)
|
|
local ps = playerStates[player];
|
|
if not ps then return; end;
|
|
ps:setFed(0, true);
|
|
ps:setHydrated(0, true);
|
|
ps:setPoisoned(0, true);
|
|
ps:clearExertionStats();
|
|
ps:updateHud();
|
|
end);
|
|
|
|
minetest.register_on_shutdown(PlayerState.save);
|
|
|
|
minetest.register_on_dignode(
|
|
function(pos, oldNode, digger)
|
|
local ps = playerStates[digger];
|
|
if ps then ps:markBuildAction(oldNode); end;
|
|
end);
|
|
|
|
minetest.register_on_placenode(
|
|
function(pos, newNode, placer, oldNode, itemStack, pointedThing)
|
|
local ps = playerStates[placer];
|
|
if ps then ps:markBuildAction(newNode); end;
|
|
end);
|
|
|
|
local controlPeriod = settings.controlTestPeriod_seconds;
|
|
local updatePeriod = settings.accountingPeriod_seconds;
|
|
local savePeriod = settings.savePeriod_seconds;
|
|
local controlTime = 0.0;
|
|
local updateTime = 0.0;
|
|
local saveTime = 0.0;
|
|
minetest.register_globalstep(
|
|
function(dt)
|
|
controlTime = controlTime + dt;
|
|
if controlTime >= controlPeriod then
|
|
for _, ps in pairs(playerStates) do
|
|
ps:pollForActivity();
|
|
end;
|
|
controlTime = 0;
|
|
end;
|
|
|
|
updateTime = updateTime + dt;
|
|
if updateTime >= updatePeriod then
|
|
controlPeriod = settings.controlTestPeriod_seconds;
|
|
updatePeriod = settings.accountingPeriod_seconds;
|
|
local tw = os.time();
|
|
for _, ps in pairs(playerStates) do
|
|
ps:update(tw, updateTime);
|
|
end;
|
|
updateTime = 0;
|
|
end;
|
|
|
|
saveTime = saveTime + dt;
|
|
if saveTime >= savePeriod then
|
|
savePeriod = settings.savePeriod_seconds;
|
|
PlayerState.save();
|
|
saveTime = 0;
|
|
end;
|
|
end);
|
|
|
|
minetest.register_on_item_eat(
|
|
function(hpChange, replacementItem, itemStack, player, pointedThing)
|
|
if itemStack:take_item() ~= nil then
|
|
local ps = playerStates[player];
|
|
if ps then
|
|
if hpChange > 0 then
|
|
local pp = math.max(0, settings.foodPoisoningProb);
|
|
|
|
if math.random() <= 1.0 - pp then
|
|
local update = false;
|
|
update = ps:addFood(hpChange, true) or update;
|
|
update = ps:addWater(hpChange / 2, true) or update;
|
|
if update then ps:updateHud(); end;
|
|
else
|
|
minetest.chat_send_player(player:get_player_name(),
|
|
settings.foodPoisoningMessage);
|
|
ps:addPoison(hpChange);
|
|
end;
|
|
elseif hpChange < 0 then
|
|
minetest.chat_send_player(player:get_player_name(),
|
|
settings.foodPoisoningMessage);
|
|
ps:addPoison(-hpChange);
|
|
end;
|
|
end;
|
|
itemStack:add_item(replacementItem);
|
|
end;
|
|
return itemStack;
|
|
end);
|