API changes
parent
1e168b9af7
commit
00aa56361d
113
init.lua
113
init.lua
|
@ -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)
|
||||
|
|
|
@ -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 |
Loading…
Reference in New Issue