API changes

master
aa6 2016-06-08 21:23:17 +03:00
parent 1e168b9af7
commit 00aa56361d
4 changed files with 271 additions and 29 deletions

View File

@ -1 +1 @@
0.3.9
0.3.10

113
init.lua
View File

@ -12,42 +12,78 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/config.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_hudbars.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_savetable.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_file_exists.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_eventemitter.lua")
minetest_wadsprint.api.events = EventEmitter:new()
-- API function to safely get player's stamina value.
function minetest_wadsprint.api.get_stamina_rate(player_name)
if minetest_wadsprint.players[player_name] ~= nil then
return minetest_wadsprint.players[player_name].stamina / minetest_wadsprint.STAMINA_MAX_VALUE
end
function minetest_wadsprint.api.stats(player_name)
local player = minetest_wadsprint.players[player_name]
if player ~= nil then
return
{
name = player_name,
stamina = player.stamina,
is_sprinting = player.is_sprinting,
is_ready_to_sprint = player.is_ready_to_sprint,
is_sprinting_physics_on = player.is_sprinting_physics_on,
}
end
end
-- API function to safely change player's stamina.
function minetest_wadsprint.api.change_stamina_by_coefficient(player_name,stamina_change_coefficient)
if minetest_wadsprint.players[player_name] ~= nil then
local player = minetest_wadsprint.players[player_name]
player.stamina = player.stamina + (stamina_change_coefficient * minetest_wadsprint.STAMINA_MAX_VALUE)
if player.stamina < 0 then
player.stamina = 0
elseif player.stamina > minetest_wadsprint.STAMINA_MAX_VALUE then
player.stamina = minetest_wadsprint.STAMINA_MAX_VALUE
function minetest_wadsprint.api.stamina(player_name,stamina_rate)
local player = minetest_wadsprint.players[player_name]
if player ~= nil then
if stamina_value ~= nil then
minetest_wadsprint.set_stamina(player, minetest_wadsprint.STAMINA_MAX_VALUE * stamina_value)
else
return player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE
end
minetest_wadsprint.hudbar_update_stamina(player)
end
return minetest_wadsprint.api
end
end
function minetest_wadsprint.api.addstamina(player_name,stamina_rate_change)
local player = minetest_wadsprint.players[player_name]
if player ~= nil then
minetest_wadsprint.set_stamina(player, player.stamina + minetest_wadsprint.STAMINA_MAX_VALUE * stamina_value)
end
end
function minetest_wadsprint.stamina_update_cycle(player)
if player.is_sprinting then
player.stamina = player.stamina - (minetest_wadsprint.STAMINA_MAX_VALUE * minetest_wadsprint.SPRINT_STAMINA_DECREASE_PER_UPDATE_PERIOD_COEFFICIENT)
if player.stamina < 0 then
minetest_wadsprint.set_sprinting(player,false)
minetest_wadsprint.set_ready_to_sprint(player,false)
player.stamina = 0
end
minetest_wadsprint.set_stamina(player, player.stamina - (minetest_wadsprint.STAMINA_MAX_VALUE * minetest_wadsprint.SPRINT_STAMINA_DECREASE_PER_UPDATE_PERIOD_COEFFICIENT))
elseif player.stamina < minetest_wadsprint.STAMINA_MAX_VALUE then
player.stamina = player.stamina + (minetest_wadsprint.STAMINA_MAX_VALUE * minetest_wadsprint.SPRINT_STAMINA_INCREASE_PER_UPDATE_PERIOD_COEFFICIENT)
if player.stamina > minetest_wadsprint.STAMINA_MAX_VALUE then
player.stamina = minetest_wadsprint.STAMINA_MAX_VALUE
end
minetest_wadsprint.set_stamina(player, player.stamina + (minetest_wadsprint.STAMINA_MAX_VALUE * minetest_wadsprint.SPRINT_STAMINA_INCREASE_PER_UPDATE_PERIOD_COEFFICIENT))
end
end
function minetest_wadsprint.set_stamina(player,stamina_value)
local old_stamina_value = player.stamina
if stamina_value < 0 then
minetest_wadsprint.set_sprinting(player,false)
minetest_wadsprint.set_ready_to_sprint(player,false)
player.stamina = 0
elseif stamina_value > minetest_wadsprint.STAMINA_MAX_VALUE then
player.stamina = minetest_wadsprint.STAMINA_MAX_VALUE
else
player.stamina = stamina_value
end
if old_stamina_value >= minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE and player.stamina < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
minetest_wadsprint.api.events:emit(
"dyspnea",
{
player = player,
value = true,
name = "dyspnea",
}
)
elseif old_stamina_value < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE and player.stamina >= minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
minetest_wadsprint.api.events:emit(
"dyspnea",
{
player = player,
value = false,
name = "dyspnea",
}
)
end
minetest_wadsprint.hudbar_update_stamina(player)
end
@ -74,6 +110,9 @@ function minetest_wadsprint.set_sprinting_physics(player,is_on)
end
end
-- If player.is_sprinting that means he is actually moving forward. If player is not moving then he
-- isn't sprinting. `player.is_sprinting` could be nil if the value is not initialized. Nil is not
-- equal nor to true neither to false.
function minetest_wadsprint.set_sprinting(player,is_sprinting)
if player.is_sprinting ~= is_sprinting then
if player.is_sprinting ~= nil then
@ -91,6 +130,13 @@ function minetest_wadsprint.set_sprinting(player,is_sprinting)
end
end
-- Main use of this function is to put player in a state when pressing "W" would trigger the
-- set_sprinting function thus you won't need to hold "A"+"D" to keep sprinting. Also it alters player
-- physics to workaround lag between pressing "W" and actual set_sprinting call. So if player is ready
-- to sprint it is sure that his physics is already in sprinting state and he can not afraid to fall
-- while jumping from a tree to tree just because the lag between pressing "W" and set_sprinting call
-- would be too big. At the same time being only ready to sprint and not actually sprinting does not
-- decreases the stamina because decreasing stamina for nothing is unfair.
function minetest_wadsprint.set_ready_to_sprint(player,is_ready_to_sprint)
if player.is_ready_to_sprint ~= is_ready_to_sprint then
if is_ready_to_sprint then
@ -124,7 +170,7 @@ end
function minetest_wadsprint.reset_stamina(player,stamina_value)
if stamina_value == nil then stamina_value = minetest_wadsprint.STAMINA_MAX_VALUE end
player.stamina = stamina_value
minetest_wadsprint.set_stamina(player,stamina_value)
minetest_wadsprint.set_sprinting(player,false)
minetest_wadsprint.set_ready_to_sprint(player,false)
return player
@ -168,9 +214,20 @@ minetest.register_on_joinplayer(function(player_obj)
player = { stamina = minetest_wadsprint.STAMINA_MAX_VALUE }
end
player.obj = player_obj
player.name = playername
minetest_wadsprint.players[playername] = player
minetest_wadsprint.initialize_hudbar(player)
minetest_wadsprint.reset_stamina(player,player.stamina)
if player.stamina < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
minetest_wadsprint.api.events:emit(
"dyspnea",
{
player = player,
value = true,
name = "dyspnea",
}
)
end
end)
minetest.register_on_respawnplayer(function(player_obj)

185
lib_eventemitter.lua Normal file
View File

@ -0,0 +1,185 @@
------------------------------------------------------------------------------
-- EventEmitter Class in Node.js Style
-- LICENSE: MIT
-- Simen Li <simenkid@gmail.com>
------------------------------------------------------------------------------
EventEmitter = { defaultMaxListeners = 10 }
local PFX = '__lsn_'
local PFX_LEN = #PFX
setmetatable(EventEmitter, {
__call = function (_, ...) return EventEmitter:new(...) end
})
local function rmEntry(tbl, pred)
local x, len = 0, #tbl
for i = 1, len do
local trusy, idx = false, (i - x)
if (type(pred) == 'function') then trusy = pred(tbl[idx])
else trusy = tbl[idx] == pred
end
if (tbl[idx] ~= nil and trusy) then
tbl[idx] = nil
table.remove(tbl, idx)
x = x + 1
end
end
return tbl
end
function EventEmitter:new(obj)
obj = obj or {}
self.__index = self
setmetatable(obj, self)
obj._on = {}
return obj
end
function EventEmitter:evTable(ev)
if (type(self._on[ev]) ~= 'table') then self._on[ev] = {} end
return self._on[ev]
end
function EventEmitter:getEvTable(ev)
return self._on[ev]
end
-- ************************************************************************ --
-- ** Public APIs * --
-- ************************************************************************ --
function EventEmitter:addListener(ev, listener)
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:evTable(pfx_ev)
local maxLsnNum = self.currentMaxListeners or self.defaultMaxListeners
local lsnNum = self:listenerCount(ev)
table.insert(evtbl, listener)
if (lsnNum > maxLsnNum) then print('WARN: Number of ' .. string.sub(pfx_ev, PFX_LEN + 1) .. " event listeners: " .. tostring(lsnNum)) end
return self
end
function EventEmitter:emit(ev, ...)
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:getEvTable(pfx_ev)
if (evtbl ~= nil) then
for _, lsn in ipairs(evtbl) do
local status, err = pcall(lsn, ...)
if not (status) then print(string.sub(_, PFX_LEN + 1) .. " emit error: " .. tostring(err)) end
end
end
-- one-time listener
pfx_ev = pfx_ev .. ':once'
evtbl = self:getEvTable(pfx_ev)
if (evtbl ~= nil) then
for _, lsn in ipairs(evtbl) do
local status, err = pcall(lsn, ...)
if not (status) then print(string.sub(_, PFX_LEN + 1) .. " emit error: " .. tostring(err)) end
end
rmEntry(evtbl, function (v) return v ~= nil end)
self._on[pfx_ev] = nil
end
return self
end
function EventEmitter:getMaxListeners()
return self.currentMaxListeners or self.defaultMaxListeners
end
function EventEmitter:listenerCount(ev)
local totalNum = 0
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:getEvTable(pfx_ev)
if (evtbl ~= nil) then totalNum = totalNum + #evtbl end
pfx_ev = pfx_ev .. ':once'
evtbl = self:getEvTable(pfx_ev)
if (evtbl ~= nil) then totalNum = totalNum + #evtbl end
return totalNum
end
function EventEmitter:listeners(ev)
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:getEvTable(pfx_ev)
local clone = {}
if (evtbl ~= nil) then
for i, lsn in ipairs(evtbl) do table.insert(clone, lsn) end
end
pfx_ev = pfx_ev .. ':once'
evtbl = self:getEvTable(pfx_ev)
if (evtbl ~= nil) then
for i, lsn in ipairs(evtbl) do table.insert(clone, lsn) end
end
return clone
end
EventEmitter.on = EventEmitter.addListener
function EventEmitter:once(ev, listener)
local pfx_ev = PFX .. tostring(ev) .. ':once'
local evtbl = self:evTable(pfx_ev)
local maxLsnNum = self.currentMaxListeners or self.defaultMaxListeners
local lsnNum = self:listenerCount(ev)
if (lsnNum > maxLsnNum) then print('WARN: Number of ' .. ev .. " event listeners: " .. tostring(lsnNum)) end
table.insert(evtbl, listener)
return self
end
function EventEmitter:removeAllListeners(ev)
if ev ~= nil then
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:evTable(pfx_ev)
rmEntry(evtbl, function (v) return v ~= nil end)
pfx_ev = pfx_ev .. ':once'
evtbl = self:evTable(pfx_ev)
rmEntry(evtbl, function (v) return v ~= nil end)
self._on[pfx_ev] = nil
else
for _pfx_ev, _t in pairs(self._on) do self:removeAllListeners(string.sub(_pfx_ev, PFX_LEN + 1)) end
end
for _pfx_ev, _t in pairs(self._on) do
if (#_t == 0) then self._on[_pfx_ev] = nil end
end
return self
end
function EventEmitter:removeListener(ev, listener)
local pfx_ev = PFX .. tostring(ev)
local evtbl = self:evTable(pfx_ev)
local lsnCount = 0
assert(listener ~= nil, "listener is nil")
-- normal listener
rmEntry(evtbl, listener)
if (#evtbl == 0) then self._on[pfx_ev] = nil end
-- emit-once listener
pfx_ev = pfx_ev .. ':once'
evtbl = self:evTable(pfx_ev)
rmEntry(evtbl, listener)
if (#evtbl == 0) then self._on[pfx_ev] = nil end
return self
end
function EventEmitter:setMaxListeners(n)
self.currentMaxListeners = n
return self
end
return EventEmitter

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB