minetest_wadsprint/init.lua

353 lines
17 KiB
Lua
Raw Normal View History

2016-03-26 11:41:29 -07:00
-- WAD SPRINTING minetest (https://minetest.net) mod (https://dev.minetest.net/Intro)
2016-03-26 12:04:32 -07:00
-- @link https://github.com/aa6/minetest_wadsprint
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_round.lua")
2016-10-20 13:51:18 -07:00
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")
2019-05-25 00:02:04 -07:00
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_file_get_contents.lua")
dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_file_put_contents.lua")
2016-03-26 11:41:29 -07:00
minetest_wadsprint =
{
2016-10-20 13:51:18 -07:00
api = { events = EventEmitter:new() },
2017-01-12 07:25:36 -08:00
stats = -- Online players' stats.
2016-10-20 13:51:18 -07:00
{
-- <playername string>:
-- obj: <player object>
-- name: <playername string>
-- stamina: <float>
-- is_walking: <boolean>
-- is_sprinting: <boolean>
-- is_ready_to_sprint: <boolean>
-- is_sprinting_physics_on: <boolean>
2016-10-20 13:51:18 -07:00
},
2017-01-13 02:20:53 -08:00
offline_stats = -- Offline stats aren't processed in the main cycle.
{
-- <playername string>:
-- stamina: <float>
2017-01-13 02:20:53 -08:00
},
2019-05-25 00:02:04 -07:00
version = file_get_contents(minetest.get_modpath(minetest.get_current_modname()).."/VERSION"),
savepath = minetest.get_worldpath().."/mod_minetest_wadsprint_saved_players_stats.dat",
worldconfig = minetest.get_worldpath().."/mod_minetest_wadsprint_config.lua",
2016-03-26 11:41:29 -07:00
}
2019-05-25 00:02:04 -07:00
dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_config.lua")
2016-03-26 11:41:29 -07:00
dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_hudbars.lua")
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 04:19:42 -08:00
------------------------------------------------------------------------------------- api.stats() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-17 13:31:48 -08:00
-- Returns player stats.
--
2017-04-24 08:25:20 -07:00
-- minetest_wadsprint.api.stats(player_name) -- Get player stats.
2017-01-17 13:31:48 -08:00
--
2016-06-08 11:23:17 -07:00
function minetest_wadsprint.api.stats(player_name)
2017-01-12 07:25:36 -08:00
local player = minetest_wadsprint.stats[player_name]
2016-06-08 11:23:17 -07:00
if player ~= nil then
return -- Return copy of values to be sure that they won't be changed by accident.
2016-06-08 11:23:17 -07:00
{
name = player_name,
stamina = player.stamina,
2017-01-13 12:39:28 -08:00
is_walking = player.is_walking,
2016-06-08 11:23:17 -07:00
is_sprinting = player.is_sprinting,
is_ready_to_sprint = player.is_ready_to_sprint,
is_sprinting_physics_on = player.is_sprinting_physics_on,
}
2016-10-20 13:51:18 -07:00
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 04:19:42 -08:00
----------------------------------------------------------------------------------- api.stamina() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
-- Gets/sets player stamina.
2017-01-17 13:31:48 -08:00
--
2017-04-24 08:46:23 -07:00
-- minetest_wadsprint.api.stamina(player_name) -- Get player stamina percentage (1 is 100%).
2017-04-24 08:25:20 -07:00
-- minetest_wadsprint.api.stamina(player_name, 0.1) -- SET stamina to 10% of STAMINA_MAX_VALUE.
2017-01-17 13:31:48 -08:00
--
2017-04-24 08:25:20 -07:00
function minetest_wadsprint.api.stamina(player_name, stamina_percentage)
2017-01-12 07:25:36 -08:00
local player = minetest_wadsprint.stats[player_name]
2016-06-08 11:23:17 -07:00
if player ~= nil then
if stamina_value ~= nil then
2017-10-28 23:59:20 -07:00
minetest_wadsprint.set_stamina(
player,
minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage
)
2016-06-08 11:23:17 -07:00
else
return player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE
end
2016-06-08 11:23:17 -07:00
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 04:19:42 -08:00
-------------------------------------------------------------------------------- api.addstamina() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-17 13:31:48 -08:00
-- Adds/subtracts stamina to player.
--
2017-04-24 08:25:20 -07:00
-- minetest_wadsprint.api.addstamina(player_name, 0.1) -- Add 10% of STAMINA_MAX_VALUE.
-- minetest_wadsprint.api.addstamina(player_name, -0.1) -- Subtract 10% of STAMINA_MAX_VALUE.
2017-01-17 13:31:48 -08:00
--
2017-04-24 08:25:20 -07:00
function minetest_wadsprint.api.addstamina(player_name, stamina_percentage)
2017-01-12 07:25:36 -08:00
local player = minetest_wadsprint.stats[player_name]
2016-06-08 11:23:17 -07:00
if player ~= nil then
2017-10-28 23:59:20 -07:00
minetest_wadsprint.set_stamina(
player,
player.stamina + minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage
)
2016-06-08 11:23:17 -07:00
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2019-08-24 04:53:55 -07:00
--------------------------------------------------------------------- stamina_update_cycle_tick() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2019-08-24 04:53:55 -07:00
function minetest_wadsprint.stamina_update_cycle_tick(player)
2016-03-26 11:41:29 -07:00
if player.is_sprinting then
2019-08-24 04:53:55 -07:00
minetest_wadsprint.set_stamina(player, player.stamina -
2017-01-13 12:47:52 -08:00
(
minetest_wadsprint.STAMINA_MAX_VALUE *
minetest_wadsprint.SPRINT_STAMINA_DECREASE_PER_UPDATE_PERIOD_COEFFICIENT
)
)
2017-01-18 06:33:31 -08:00
else
if player.stamina < minetest_wadsprint.STAMINA_MAX_VALUE then
2019-08-24 04:53:55 -07:00
minetest_wadsprint.set_stamina(player, player.stamina +
2017-01-18 06:33:31 -08:00
(
minetest_wadsprint.STAMINA_MAX_VALUE *
minetest_wadsprint.SPRINT_STAMINA_INCREASE_PER_UPDATE_PERIOD_COEFFICIENT
)
2017-01-13 12:47:52 -08:00
)
2017-01-18 06:33:31 -08:00
end
2016-06-08 11:23:17 -07:00
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
----------------------------------------------------------------------------- switch_to_walking() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
function minetest_wadsprint.switch_to_walking(player)
if player.is_walking == false then
player.is_walking = true
player.is_sprinting = false
player.is_ready_to_sprint = false
2019-08-24 04:53:55 -07:00
minetest_wadsprint.set_sprinting_physics(player,false)
2017-01-13 12:39:28 -08:00
minetest_wadsprint.hudbar_update_ready_to_sprint(player)
minetest_wadsprint.hudbar_update_stamina(player)
end
2017-01-13 12:39:28 -08:00
end
----------------------------------------------------------------------------------------------------
2019-08-24 05:08:46 -07:00
--------------------------------------------------------------------------- switch_to_sprinting() --
----------------------------------------------------------------------------------------------------
-- Sprinting means that player has altered physics and is moving forward. If player isn't moving
-- then he isn't sprinting.
function minetest_wadsprint.switch_to_sprinting(player)
if player.is_sprinting == false then
player.is_walking = false
player.is_sprinting = true
player.is_ready_to_sprint = false
minetest_wadsprint.set_sprinting_physics(player,true)
minetest_wadsprint.hudbar_update_ready_to_sprint(player)
minetest_wadsprint.hudbar_update_stamina(player)
end
end
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
--------------------------------------------------------------------- switch_to_ready_to_sprint() --
----------------------------------------------------------------------------------------------------
-- Main use of this function is to put player in a state when pressing "W" would trigger the
-- sprinting state 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 sprinting. So if player is ready to
2017-01-18 06:33:31 -08:00
-- sprint he 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 switching to
-- sprinting state would be too big. At the same time being only ready to sprint but not actually
-- sprinting does not decreases the stamina because decreasing stamina for not sprinting is unfair.
2017-01-13 12:39:28 -08:00
function minetest_wadsprint.switch_to_ready_to_sprint(player)
if player.is_ready_to_sprint == false then
player.is_walking = false
player.is_sprinting = false
player.is_ready_to_sprint = true
2019-08-24 04:53:55 -07:00
minetest_wadsprint.set_sprinting_physics(player,true)
minetest_wadsprint.hudbar_update_ready_to_sprint(player)
minetest_wadsprint.hudbar_update_stamina(player)
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
------------------------------------------------------------------------- set_sprinting_physics() --
----------------------------------------------------------------------------------------------------
dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_set_sprinting_physics.lua")
2017-01-13 12:39:28 -08:00
----------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------- scan_player_controls() --
----------------------------------------------------------------------------------------------------
function minetest_wadsprint.scan_player_controls(player)
local control = player.obj:get_player_control()
2017-03-10 22:09:23 -08:00
if control["up"] then
if player.is_sprinting then
return
elseif player.is_ready_to_sprint then
minetest_wadsprint.switch_to_sprinting(player)
return
end
2017-01-13 12:42:44 -08:00
end
if control["left"] and control["right"] and not control["down"] then
if player.stamina > minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
if control["up"] then
minetest_wadsprint.switch_to_sprinting(player)
else
minetest_wadsprint.switch_to_ready_to_sprint(player)
2017-01-13 12:39:28 -08:00
end
end
2017-01-13 12:42:44 -08:00
else
minetest_wadsprint.switch_to_walking(player)
2017-01-13 12:39:28 -08:00
end
end
----------------------------------------------------------------------------------------------------
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------- set_stamina() --
----------------------------------------------------------------------------------------------------
2016-06-08 11:23:17 -07:00
function minetest_wadsprint.set_stamina(player,stamina_value)
local old_stamina_value = player.stamina
if stamina_value < 0 then
2017-01-13 12:39:28 -08:00
minetest_wadsprint.switch_to_walking(player)
2016-06-08 11:23:17 -07:00
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
2017-01-13 12:39:28 -08:00
if old_stamina_value >= minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE
and player.stamina < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
2016-06-08 11:23:17 -07:00
minetest_wadsprint.api.events:emit(
"dyspnea-on",
2016-06-08 11:23:17 -07:00
{
name = "dyspnea-on",
2016-10-20 13:51:18 -07:00
player = player,
2016-06-08 11:23:17 -07:00
}
)
2017-01-13 12:39:28 -08:00
elseif old_stamina_value < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE
and player.stamina >= minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
2016-06-08 11:23:17 -07:00
minetest_wadsprint.api.events:emit(
"dyspnea-off",
2016-06-08 11:23:17 -07:00
{
name = "dyspnea-off",
2016-10-20 13:51:18 -07:00
player = player,
2016-06-08 11:23:17 -07:00
}
)
2016-03-26 11:41:29 -07:00
end
minetest_wadsprint.hudbar_update_stamina(player)
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
----------------------------------------------------------------------------- initialize_player() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
function minetest_wadsprint.initialize_player(player_obj)
local player =
{
obj = player_obj,
name = player_obj:get_player_name(),
is_walking = true,
is_sprinting = false,
is_ready_to_sprint = false,
is_sprinting_physics_on = false,
}
if minetest_wadsprint.offline_stats[player.name] ~= nil then
player.stamina = minetest_wadsprint.offline_stats[player.name].stamina
else
player.stamina = minetest_wadsprint.STAMINA_MAX_VALUE
end
minetest_wadsprint.stats[player.name] = player
minetest_wadsprint.initialize_hudbar(player)
if player.stamina < minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then
minetest_wadsprint.api.events:emit(
"dyspnea-on",
{
name = "dyspnea-on",
2017-01-13 12:39:28 -08:00
player = player,
}
)
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
---------------------------------------------------------------------------------- reset_player() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
function minetest_wadsprint.reset_player(player_obj)
local player = minetest_wadsprint.stats[player_obj:get_player_name()]
minetest_wadsprint.set_stamina(player,minetest_wadsprint.STAMINA_MAX_VALUE)
minetest_wadsprint.switch_to_walking(player)
2016-03-26 11:41:29 -07:00
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
--------------------------------------------------------------------------- deinitialize_player() --
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
function minetest_wadsprint.deinitialize_player(player_obj)
local player = minetest_wadsprint.stats[player_obj:get_player_name()]
minetest_wadsprint.offline_stats[player.name] = { stamina = player.stamina, was_online = true }
minetest_wadsprint.stats[player.name] = nil
2016-04-24 11:01:21 -07:00
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------- save_players_stats() --
----------------------------------------------------------------------------------------------------
function minetest_wadsprint.save_players_stats()
local stats = {}
local counter = 1
2017-01-12 07:25:36 -08:00
for key,val in pairs(minetest_wadsprint.stats) do
stats[counter] = { name = key, stamina = val.stamina }
counter = counter + 1
end
2017-01-13 02:20:53 -08:00
for key,val in ipairs(minetest_wadsprint.offline_stats) do
2017-01-13 12:39:28 -08:00
if counter == minetest_wadsprint.PLAYERS_STATS_FILE_LIMIT_RECORDS then break end
if minetest_wadsprint.stats[val.name] == nil and val.was_online ~= nil then
stats[counter] = { name = val.name, stamina = val.stamina }
counter = counter + 1
end
2017-01-13 12:39:28 -08:00
end
for key,val in ipairs(minetest_wadsprint.offline_stats) do
if counter == minetest_wadsprint.PLAYERS_STATS_FILE_LIMIT_RECORDS then break end
if minetest_wadsprint.stats[val.name] == nil and val.was_online == nil then
stats[counter] = { name = val.name, stamina = val.stamina }
counter = counter + 1
end
end
2017-01-12 07:25:36 -08:00
table.save(stats,minetest_wadsprint.savepath)
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------- load_players_stats() --
----------------------------------------------------------------------------------------------------
function minetest_wadsprint.load_players_stats()
2017-01-12 07:25:36 -08:00
if file_exists(minetest_wadsprint.savepath) then
2017-01-13 02:20:53 -08:00
local raw_saved_stats = table.load(minetest_wadsprint.savepath)
minetest_wadsprint.offline_stats = {}
for key,val in ipairs(raw_saved_stats) do
minetest_wadsprint.offline_stats[val.name] = { stamina = val.stamina }
end
end
end
2017-01-13 04:08:04 -08:00
----------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------ Mod initialization --
----------------------------------------------------------------------------------------------------
2017-01-13 12:39:28 -08:00
minetest.register_on_joinplayer(minetest_wadsprint.initialize_player)
minetest.register_on_respawnplayer(minetest_wadsprint.reset_player)
minetest.register_on_leaveplayer(minetest_wadsprint.deinitialize_player)
2016-03-26 11:41:29 -07:00
-- Register hudbar call for compatibility with some hudbar mods.
if minetest_wadsprint.register_hudbar ~= nil then
minetest_wadsprint.register_hudbar()
end
-- Save player stats to file on server shutdown.
if minetest_wadsprint.SAVE_PLAYERS_STATS_TO_FILE then
minetest_wadsprint.load_players_stats()
minetest.register_on_shutdown(minetest_wadsprint.save_players_stats)
end
2016-03-26 11:41:29 -07:00
-- Main cycle.
2017-05-02 11:54:45 -07:00
local timer_of_stats_update = 0
local timer_of_controls_check = 0
2019-08-24 06:22:10 -07:00
minetest.register_globalstep(function(seconds_since_last_global_step) -- Called every server step, usually interval of 0.05s.
2017-05-02 11:54:45 -07:00
2019-08-24 06:22:10 -07:00
timer_of_stats_update = timer_of_stats_update + seconds_since_last_global_step
timer_of_controls_check = timer_of_controls_check + seconds_since_last_global_step
2017-05-02 11:54:45 -07:00
-- Run stamina update cycle for every player.
if timer_of_stats_update > minetest_wadsprint.PLAYER_STATS_UPDATE_PERIOD_SECONDS then
timer_of_stats_update = 0
2017-01-12 07:25:36 -08:00
for player_name,player in pairs(minetest_wadsprint.stats) do
2019-08-24 04:53:55 -07:00
minetest_wadsprint.stamina_update_cycle_tick(player)
2016-03-26 11:41:29 -07:00
end
end
2017-05-02 11:54:45 -07:00
-- Scan players controls.
if timer_of_controls_check > minetest_wadsprint.PLAYER_CONTROLS_CHECK_PERIOD_SECONDS then
timer_of_controls_check = 0
2017-01-12 07:25:36 -08:00
for player_name,player in pairs(minetest_wadsprint.stats) do
minetest_wadsprint.scan_player_controls(player)
2016-03-26 11:41:29 -07:00
end
end
2017-05-02 11:54:45 -07:00
2016-03-26 12:04:32 -07:00
end)