diff --git a/VERSION b/VERSION index 6348c0f..a988815 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.10.6 \ No newline at end of file +0.10.7 \ No newline at end of file diff --git a/init.api.lua b/init.api.lua new file mode 100644 index 0000000..10547f0 --- /dev/null +++ b/init.api.lua @@ -0,0 +1,63 @@ +---------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------- API -- +---------------------------------------------------------------------------------------------------- +minetest_wadsprint.api = { events = EventEmitter:new() } +---------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------- api.stats() -- +---------------------------------------------------------------------------------------------------- +-- Returns player stats. +-- +-- minetest_wadsprint.api.stats(player_name) -- Get player stats. +-- +function minetest_wadsprint.api.stats(player_name) + local player = minetest_wadsprint.stats[player_name] + if player ~= nil then + return -- Return copy of values to be sure that they won't be changed by accident. + { + name = player_name, + stamina = player.stamina, + is_walking = player.is_walking, + 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.stamina() -- +---------------------------------------------------------------------------------------------------- +-- Gets/sets player stamina. +-- +-- minetest_wadsprint.api.stamina(player_name) -- Get player stamina percentage (1 is 100%). +-- minetest_wadsprint.api.stamina(player_name, 0.1) -- SET stamina to 10% of STAMINA_MAX_VALUE. +-- +function minetest_wadsprint.api.stamina(player_name, stamina_percentage) + local player = minetest_wadsprint.stats[player_name] + if player ~= nil then + if stamina_value ~= nil then + minetest_wadsprint.set_stamina( + player, + minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage + ) + else + return player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE + end + end +end +---------------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- api.addstamina() -- +---------------------------------------------------------------------------------------------------- +-- Adds/subtracts stamina to player. +-- +-- 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. +-- +function minetest_wadsprint.api.addstamina(player_name, stamina_percentage) + local player = minetest_wadsprint.stats[player_name] + if player ~= nil then + minetest_wadsprint.set_stamina( + player, + player.stamina + minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage + ) + end +end \ No newline at end of file diff --git a/init.config.lua b/init.config.lua new file mode 100644 index 0000000..8552598 --- /dev/null +++ b/init.config.lua @@ -0,0 +1,62 @@ +-- Loading global config. +dofile(minetest.get_modpath(minetest.get_current_modname()).."/config.lua") + +-- Processing in-game settings. In-game settings are preferrable +-- over global config.lua values. +function minetest_wadsprint.load_minetest_settings_key(key,type) + if type == "int" then + if minetest.settings:get("minetest_wadsprint."..key) ~= nil then + minetest_wadsprint[key] = tonumber(minetest.settings:get("minetest_wadsprint."..key)) + end + elseif type == "bool" then + if minetest.settings:get_bool("minetest_wadsprint."..key) ~= nil then + minetest_wadsprint[key] = minetest.settings:get_bool("minetest_wadsprint."..key) + end + end +end +minetest_wadsprint.load_minetest_settings_key("ENABLE_INGAME_SETTINGS","bool") +if minetest_wadsprint.ENABLE_INGAME_SETTINGS == true then + print("In-game minetest settings are enabled. Loading them.") + minetest_wadsprint.load_minetest_settings_key("HIDE_HUD_BARS","bool") + minetest_wadsprint.load_minetest_settings_key("STAMINA_MAX_VALUE","int") + minetest_wadsprint.load_minetest_settings_key("DYSPNEA_THRESHOLD_VALUE","int") + minetest_wadsprint.load_minetest_settings_key("SAVE_PLAYERS_STATS_TO_FILE","bool") + minetest_wadsprint.load_minetest_settings_key("PLAYERS_STATS_FILE_LIMIT_RECORDS","int") + minetest_wadsprint.load_minetest_settings_key("PLAYER_STATS_UPDATE_PERIOD_SECONDS","int") + minetest_wadsprint.load_minetest_settings_key("PLAYER_CONTROLS_CHECK_PERIOD_SECONDS","int") + minetest_wadsprint.load_minetest_settings_key("SPRINT_RUN_SPEED_BOOST_COEFFICIENT","int") + minetest_wadsprint.load_minetest_settings_key("SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT","int") + minetest_wadsprint.load_minetest_settings_key("SPRINT_STAMINA_DECREASE_PER_SECOND_PERCENTS","int") + minetest_wadsprint.load_minetest_settings_key("SPRINT_STAMINA_INCREASE_PER_SECOND_PERCENTS","int") +else + print("In-game minetest settings are disabled. Ignoring them.") +end + +-- Processing world-specific config. World-specific values are preferrable +-- over both global config and in-game settings. +if file_exists(minetest_wadsprint.worldconfig) then + print("Loading minetest_wadsprint world-specific config: "..minetest_wadsprint.worldconfig) + dofile(minetest_wadsprint.worldconfig) +else + print("Creating minetest_wadsprint world-specific config: "..minetest_wadsprint.worldconfig) + file_put_contents( + minetest_wadsprint.worldconfig, + "-- World-specific config. Copy here values from `mods/minetest_wadsprint/config.lua`:\n" + ) +end + +-- Processing some config values to avoid further unnecessary calculations. +minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_COEFFICIENT = ( + minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_PERCENTS / 100 +) +minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT = ( + minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_PERCENTS / 100 +) +minetest_wadsprint.SPRINT_STAMINA_DECREASE_PER_UPDATE_PERIOD_COEFFICIENT = ( + minetest_wadsprint.PLAYER_STATS_UPDATE_PERIOD_SECONDS * + ( minetest_wadsprint.SPRINT_STAMINA_DECREASE_PER_SECOND_PERCENTS / 100 ) +) +minetest_wadsprint.SPRINT_STAMINA_INCREASE_PER_UPDATE_PERIOD_COEFFICIENT = ( + minetest_wadsprint.PLAYER_STATS_UPDATE_PERIOD_SECONDS * + ( minetest_wadsprint.SPRINT_STAMINA_INCREASE_PER_SECOND_PERCENTS / 100 ) +) \ No newline at end of file diff --git a/init.hudbars.lua b/init.hudbars.lua new file mode 100755 index 0000000..165b583 --- /dev/null +++ b/init.hudbars.lua @@ -0,0 +1,174 @@ +if minetest_wadsprint.HIDE_HUD_BARS == true then + + function minetest_wadsprint.initialize_hudbar(player) end + function minetest_wadsprint.hudbar_update_stamina(player) end + function minetest_wadsprint.hudbar_update_ready_to_sprint(player) end + +elseif minetest.get_modpath("hudbars") ~= nil then + + -- @see http://repo.or.cz/minetest_hudbars.git/blob_plain/HEAD:/API.md + function minetest_wadsprint.register_hudbar() + -- This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden and unhidden on a per-player basis. Note this does not yet display the HUD bar. + -- The HUD bars will be displayed in a “first come, first serve” order. This mod does not allow fow a custom order or a way to set it manually in a reliable way. + hb.register_hudbar( + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: A globally unique internal name for the HUD bar, will be used later to refer to it. Please only rely on alphanumeric characters for now. The identifiers “`health`” and “`breath`” are used internally for the built-in health and breath bar, respectively. Please do not use these names. + minetest_wadsprint.HUDBARS_TEXT_COLOR, -- `text_color`: A 3-octet number defining the color of the text. The octets denote, in this order red, green and blue and range from `0x00` (complete lack of this component) to `0xFF` (full intensity of this component). Example: `0xFFFFFF` for white. + minetest_wadsprint.HUDBARS_TEXT_LABEL, -- `label`: A string which is displayed on the HUD bar itself to describe the HUD bar. Try to keep this string short. + { -- `textures`: A table with the following fields: + bar = minetest_wadsprint.HUDBARS_PROGRESSBAR_NOT_SPRINTING_IMAGE, -- `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section). The image for the bar will be repeated horizontally to denote the “value” of the HUD bar. It **must** be of size 2×16. If neccessary, the image will be split vertically in half, and only the left half of the image is displayed. So the final HUD bar will always be displayed on a per-pixel basis. The default bar images are single-colored, but you can use other styles as well, for instance, a vertical gradient. + icon = minetest_wadsprint.HUDBARS_IS_NOT_SPRINTING_ICON, -- `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used. Icon is a 16×16 image shown left of the HUD bar. This is optional. + bgicon = minetest_wadsprint.HUDBARS_BACKGROUND_ICON, -- `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode. + }, + minetest_wadsprint.STAMINA_MAX_VALUE, -- `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value. + minetest_wadsprint.STAMINA_MAX_VALUE, -- `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value. + false, -- `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it. + minetest_wadsprint.HUDBARS_TEXT_FORMAT -- `format_string`: This is optional; You can specify an alternative format string display the final text on the HUD bar. The default format string is “`%s: %d/%d`” (in this order: Label, current value, maximum value). See also the Lua documentation of `string.format`. + ) + end + function minetest_wadsprint.initialize_hudbar(player) + -- After a HUD bar has been registered, they are not yet displayed yet for any player. HUD bars must be explicitly initialized on a per-player basis. You probably want to do this in the `minetest.register_on_joinplayer`. + -- This function initialzes and activates a previously registered HUD bar and assigns it to a certain client/player. This has only to be done once per player and after that, you can change the values using `hb.change_hudbar`. However, if `start_hidden` was set to `true` for the HUD bar (in `hb.register_hudbar`), the HUD bar will initially be hidden, but the HUD elements are still sent to the client. Otherwise, the HUD bar will be initially be shown to the player. + hb.init_hudbar( + player.obj, -- `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. + math.ceil(player.stamina), -- `start_value`: The initial current value of the HUD bar. This is optional, `default_start_value` of the registration function will be used, if this is `nil`. + nil, -- `start_max`: The initial maximum value of the HUD bar. This is optional, `default_start_max` of the registration function will be used, if this is `nil` + nil -- `start_hidden`: Whether the HUD bar is initially hidden. This is optional, `default_start_hidden` of the registration function will be used as default. + ) + end + function minetest_wadsprint.hudbar_update_ready_to_sprint(player) + if player.is_sprinting then + hb.change_hudbar( + player.obj, -- `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. + nil, -- `new_value`: The new current value of the HUD bar. + nil, -- `new_max_value`: The new maximum value of the HUD bar. + minetest_wadsprint.HUDBARS_IS_SPRINTING_ICON, -- `new_icon`: File name of the new icon. + nil, -- `new_bgicon`: File name of the new background icon for the modern-style statbar. + minetest_wadsprint.HUDBARS_PROGRESSBAR_SPRINTING_IMAGE, -- `new_bar`: File name of the new bar segment image. + nil, -- `new_label`: A new text label of the HUD bar. Note the format string still applies. + nil -- `new_text_color`: A 3-octet number defining the new color of the text. + ) + elseif player.is_ready_to_sprint then + hb.change_hudbar( + player.obj, -- `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. + nil, -- `new_value`: The new current value of the HUD bar. + nil, -- `new_max_value`: The new maximum value of the HUD bar. + minetest_wadsprint.HUDBARS_IS_NOT_SPRINTING_ICON, -- `new_icon`: File name of the new icon. + nil, -- `new_bgicon`: File name of the new background icon for the modern-style statbar. + minetest_wadsprint.HUDBARS_PROGRESSBAR_SPRINTING_IMAGE, -- `new_bar`: File name of the new bar segment image. + nil, -- `new_label`: A new text label of the HUD bar. Note the format string still applies. + nil -- `new_text_color`: A 3-octet number defining the new color of the text. + ) + else + hb.change_hudbar( + player.obj, -- `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. + nil, -- `new_value`: The new current value of the HUD bar. + nil, -- `new_max_value`: The new maximum value of the HUD bar. + minetest_wadsprint.HUDBARS_IS_NOT_SPRINTING_ICON, -- `new_icon`: File name of the new icon. + nil, -- `new_bgicon`: File name of the new background icon for the modern-style statbar. + minetest_wadsprint.HUDBARS_PROGRESSBAR_NOT_SPRINTING_IMAGE, -- `new_bar`: File name of the new bar segment image. + nil, -- `new_label`: A new text label of the HUD bar. Note the format string still applies. + nil -- `new_text_color`: A 3-octet number defining the new color of the text. + ) + end + end + function minetest_wadsprint.hudbar_update_stamina(player) + -- After a HUD bar has been added, you can change the current and maximum value on a per-player basis. You use the function `hb.change_hudbar` for this. It changes the values of an initialized HUD bar for a certain player. `new_value` and `new_max_value` can be `nil`; if one of them is `nil`, that means the value is unchanged. If both values are `nil`, this function is a no-op. This function also tries minimize the amount of calls to `hud_change` of the Minetest Lua API, and therefore, network traffic. `hud_change` is only called if it is actually needed, i.e. when the actual length of the bar or the displayed string changed, so you do not have to worry about it. + hb.change_hudbar( + player.obj, -- `player`: `ObjectRef` of the player to which the HUD bar belongs to + minetest_wadsprint.HUDBARS_IDENTIFIER, -- `identifier`: The identifier of the HUD bar type to change, as specified in `hb.register_hudbar`. + math.ceil(player.stamina), -- `new_value`: The new current value of the HUD bar + minetest_wadsprint.STAMINA_MAX_VALUE -- `new_max_value`: The new maximum value of the HUD bar + ) + end + +elseif minetest.get_modpath("hud") ~= nil then + + -- @see https://github.com/BlockMen/hud_hunger/blob/master/API.txt + function minetest_wadsprint.register_hudbar() + hud.register( + minetest_wadsprint.HUDHUNGER_BAR_NAME, + { + hud_elem_type = "statbar", -- currently only supported type (same as in lua-api.txt) + max = minetest_wadsprint.HUDHUNGER_HALF_ICONS_NUMBER, -- used to prevent "overflow" of statbars + size = minetest_wadsprint.HUDHUNGER_ICON_SIZE, -- statbar texture size (default 24x24), needed to be scaled correctly + text = minetest_wadsprint.HUDBARS_IS_NOT_SPRINTING_ICON, -- texture name (same as in lua-api.txt) + offset = minetest_wadsprint.HUDHUNGER_OFFSET, + number = minetest_wadsprint.HUDHUNGER_HALF_ICONS_NUMBER, -- number/2 = number of full textures(e.g. hearts) + position = minetest_wadsprint.HUDHUNGER_POSITION, -- position of statbar (same as in lua-api.txt) + alignment = minetest_wadsprint.HUDHUNGER_ALIGNMENT, -- alignment on screen (same as in lua-api.txt) + background = nil, -- statbar background texture name + autohide_bg = false, -- hide statbar background textures when number = 0 + events = {}, -- called on events "damage" and "breath_changed" of players + } + ) + end + function minetest_wadsprint.initialize_hudbar(player) + minetest_wadsprint.hudbar_update_stamina(player) + end + function minetest_wadsprint.hudbar_update_ready_to_sprint(player) + if player.is_sprinting or player.is_ready_to_sprint then + hud.change_item( + player.obj, + minetest_wadsprint.HUDHUNGER_BAR_NAME, + { + text = minetest_wadsprint.HUDHUNGER_IS_SPRINTING_ICON, + } + ) + else + hud.change_item( + player.obj, + minetest_wadsprint.HUDHUNGER_BAR_NAME, + { + text = minetest_wadsprint.HUDBARS_IS_NOT_SPRINTING_ICON, + } + ) + end + end + function minetest_wadsprint.hudbar_update_stamina(player) + hud.change_item( + player.obj, + minetest_wadsprint.HUDHUNGER_BAR_NAME, + { + number = 0, -- Workaround for some obscure bug. + } + ) + hud.change_item( + player.obj, + minetest_wadsprint.HUDHUNGER_BAR_NAME, + { + number = math.ceil((player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE) * minetest_wadsprint.HUDHUNGER_HALF_ICONS_NUMBER), + } + ) + end + +else + + -- @see http://dev.minetest.net/HUD + function minetest_wadsprint.initialize_hudbar(player) + player.hud = player.obj:hud_add( + { + hud_elem_type = "statbar", -- HUD type. Statbar displays a horizontal bar made up of half-images. + size = minetest_wadsprint.MINETESTHUD_ICON_SIZE, -- `size`: If used will force full-image size to this value (override texture pack image size). + text = minetest_wadsprint.MINETESTHUD_IS_NOT_SPRINTING_ICON, -- `text`: The name of the texture that is used. + number = math.ceil((player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE) * minetest_wadsprint.MINETESTHUD_HALF_ICONS_NUMBER), -- `number`: The number of half-textures that are displayed. If odd, will end with a vertically center-split texture. + offset = minetest_wadsprint.MINETESTHUD_OFFSET, -- `offset`: Specifies a pixel offset from the position. Not scaled to the screen size. Note: offset WILL adapt to screen DPI as well as the user defined scaling factor! + position = minetest_wadsprint.MINETESTHUD_POSITION, -- `position`: Used for all element types. To account for differing resolutions, the position coordinates are the percentage of the screen, ranging in value from 0 to 1. 0 means left/top, 1 means right/bottom. + alignment = minetest_wadsprint.MINETESTHUD_ALIGNMENT, -- `alignment`: Specifies how the item will be aligned. It ranges from -1 to 1, with 0 being the center, -1 is moved to the left/up, and 1 is to the right/down. Fractional values can be used. + }) + end + function minetest_wadsprint.hudbar_update_stamina(player) + player.obj:hud_change(player.hud, "number", math.ceil((player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE) * minetest_wadsprint.MINETESTHUD_HALF_ICONS_NUMBER)) + end + function minetest_wadsprint.hudbar_update_ready_to_sprint(player) + if player.is_sprinting or player.is_ready_to_sprint then + player.obj:hud_change(player.hud, "text", minetest_wadsprint.MINETESTHUD_IS_SPRINTING_ICON) + else + player.obj:hud_change(player.hud, "text", minetest_wadsprint.MINETESTHUD_IS_NOT_SPRINTING_ICON) + end + end + +end \ No newline at end of file diff --git a/init.lua b/init.lua index 339fce5..56ed0e8 100755 --- a/init.lua +++ b/init.lua @@ -1,14 +1,13 @@ -- WAD SPRINTING minetest (https://minetest.net) mod (https://dev.minetest.net/Intro) -- @link https://github.com/aa6/minetest_wadsprint -dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib_round.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") -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") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/lib.round.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") +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") minetest_wadsprint = { - api = { events = EventEmitter:new() }, stats = -- Online players' stats. { -- : @@ -29,66 +28,34 @@ minetest_wadsprint = savepath = minetest.get_worldpath().."/mod_minetest_wadsprint_saved_players_stats.dat", worldconfig = minetest.get_worldpath().."/mod_minetest_wadsprint_config.lua", } -dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_config.lua") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_hudbars.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/init.api.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/init.config.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/init.hudbars.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()).."/init.set_sprinting_physics.lua") ---------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------- api.stats() -- +-------------------------------------------------------------------------- scan_player_controls() -- ---------------------------------------------------------------------------------------------------- --- Returns player stats. --- --- minetest_wadsprint.api.stats(player_name) -- Get player stats. --- -function minetest_wadsprint.api.stats(player_name) - local player = minetest_wadsprint.stats[player_name] - if player ~= nil then - return -- Return copy of values to be sure that they won't be changed by accident. - { - name = player_name, - stamina = player.stamina, - is_walking = player.is_walking, - 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.stamina() -- ----------------------------------------------------------------------------------------------------- --- Gets/sets player stamina. --- --- minetest_wadsprint.api.stamina(player_name) -- Get player stamina percentage (1 is 100%). --- minetest_wadsprint.api.stamina(player_name, 0.1) -- SET stamina to 10% of STAMINA_MAX_VALUE. --- -function minetest_wadsprint.api.stamina(player_name, stamina_percentage) - local player = minetest_wadsprint.stats[player_name] - if player ~= nil then - if stamina_value ~= nil then - minetest_wadsprint.set_stamina( - player, - minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage - ) - else - return player.stamina / minetest_wadsprint.STAMINA_MAX_VALUE +function minetest_wadsprint.scan_player_controls(player) + local controls = player.obj:get_player_control() + if controls["up"] then + if player.is_sprinting then + return + elseif player.is_ready_to_sprint then + minetest_wadsprint.switch_to_sprinting(player) + return end - end -end ----------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------- api.addstamina() -- ----------------------------------------------------------------------------------------------------- --- Adds/subtracts stamina to player. --- --- 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. --- -function minetest_wadsprint.api.addstamina(player_name, stamina_percentage) - local player = minetest_wadsprint.stats[player_name] - if player ~= nil then - minetest_wadsprint.set_stamina( - player, - player.stamina + minetest_wadsprint.STAMINA_MAX_VALUE * stamina_percentage - ) - end + end + if controls["left"] and controls["right"] and not controls["down"] then + if player.stamina > minetest_wadsprint.DYSPNEA_THRESHOLD_VALUE then + if controls["up"] then + minetest_wadsprint.switch_to_sprinting(player) + else + minetest_wadsprint.switch_to_ready_to_sprint(player) + end + end + else + minetest_wadsprint.switch_to_walking(player) + end end ---------------------------------------------------------------------------------------------------- --------------------------------------------------------------------- stamina_update_cycle_tick() -- @@ -161,35 +128,6 @@ function minetest_wadsprint.switch_to_ready_to_sprint(player) end end ---------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------- set_sprinting_physics() -- ----------------------------------------------------------------------------------------------------- -dofile(minetest.get_modpath(minetest.get_current_modname()).."/init_set_sprinting_physics.lua") ----------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------- scan_player_controls() -- ----------------------------------------------------------------------------------------------------- -function minetest_wadsprint.scan_player_controls(player) - local control = player.obj:get_player_control() - 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 - 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) - end - end - else - minetest_wadsprint.switch_to_walking(player) - end -end ----------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- set_stamina() -- ---------------------------------------------------------------------------------------------------- function minetest_wadsprint.set_stamina(player,stamina_value) @@ -254,9 +192,9 @@ function minetest_wadsprint.initialize_player(player_obj) end end ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- reset_player() -- +---------------------------------------------------------------------------- reset_player_stats() -- ---------------------------------------------------------------------------------------------------- -function minetest_wadsprint.reset_player(player_obj) +function minetest_wadsprint.reset_player_stats(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) @@ -311,7 +249,7 @@ end ------------------------------------------------------------------------------ Mod initialization -- ---------------------------------------------------------------------------------------------------- minetest.register_on_joinplayer(minetest_wadsprint.initialize_player) -minetest.register_on_respawnplayer(minetest_wadsprint.reset_player) +minetest.register_on_respawnplayer(minetest_wadsprint.reset_player_stats) minetest.register_on_leaveplayer(minetest_wadsprint.deinitialize_player) -- Register hudbar call for compatibility with some hudbar mods. @@ -349,4 +287,4 @@ minetest.register_globalstep(function(seconds_since_last_global_step) -- Called end end -end) +end) \ No newline at end of file diff --git a/init.set_sprinting_physics.lua b/init.set_sprinting_physics.lua new file mode 100644 index 0000000..f793e47 --- /dev/null +++ b/init.set_sprinting_physics.lua @@ -0,0 +1,68 @@ +if minetest_wadsprint.BAD_PHYSICS_OVERRIDE_MODE == true then + + function minetest_wadsprint.set_sprinting_physics(player,is_on_val) + if player.is_sprinting_physics_on ~= is_on_val then + local physics = player.obj:get_physics_override() + if is_on_val == true then + player.obj:set_physics_override( + { + jump = (round(physics.jump,0.01) - 1 + minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT), + speed = (round(physics.speed,0.01) - 1 + minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_COEFFICIENT), + }) + elseif player.is_sprinting_physics_on ~= nil then + player.obj:set_physics_override( + { + jump = 1, + speed = 1, + }) + end + player.is_sprinting_physics_on = is_on_val + end + end + +elseif minetest.get_modpath("player_monoids") ~= nil then + + function minetest_wadsprint.set_sprinting_physics(player,is_on_val) + if player.is_sprinting_physics_on ~= is_on_val then + if is_on_val == true then + player_monoids.jump:add_change( + player.obj, + minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT, + "minetest_wadsprint:jump" + ) + player_monoids.speed:add_change( + player.obj, + minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_COEFFICIENT, + "minetest_wadsprint:speed" + ) + elseif player.is_sprinting_physics_on ~= nil then + player_monoids.jump:del_change(player.obj, "minetest_wadsprint:jump") + player_monoids.speed:del_change(player.obj, "minetest_wadsprint:speed") + end + player.is_sprinting_physics_on = is_on_val + end + end + +else + + function minetest_wadsprint.set_sprinting_physics(player,is_on_val) + if player.is_sprinting_physics_on ~= is_on_val then + local physics = player.obj:get_physics_override() + if is_on_val == true then + player.obj:set_physics_override( + { + jump = (round(physics.jump,0.01) - 1 + minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT), + speed = (round(physics.speed,0.01) - 1 + minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_COEFFICIENT), + }) + elseif player.is_sprinting_physics_on ~= nil then + player.obj:set_physics_override( + { + jump = (round(physics.jump,0.01) + 1 - minetest_wadsprint.SPRINT_JUMP_HEIGHT_BOOST_COEFFICIENT), + speed = (round(physics.speed,0.01) + 1 - minetest_wadsprint.SPRINT_RUN_SPEED_BOOST_COEFFICIENT), + }) + end + player.is_sprinting_physics_on = is_on_val + end + end + +end \ No newline at end of file diff --git a/lib.eventemitter.lua b/lib.eventemitter.lua new file mode 100644 index 0000000..59bdd19 --- /dev/null +++ b/lib.eventemitter.lua @@ -0,0 +1,185 @@ +------------------------------------------------------------------------------ +-- EventEmitter Class in Node.js Style +-- LICENSE: MIT +-- Simen Li +------------------------------------------------------------------------------ +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 diff --git a/lib.file_exists.lua b/lib.file_exists.lua new file mode 100644 index 0000000..766aa58 --- /dev/null +++ b/lib.file_exists.lua @@ -0,0 +1,4 @@ +function file_exists(name) + local fd = io.open(name,"r") + if fd ~= nil then io.close(fd) return true else return false end +end \ No newline at end of file diff --git a/lib.file_get_contents.lua b/lib.file_get_contents.lua new file mode 100644 index 0000000..82da27c --- /dev/null +++ b/lib.file_get_contents.lua @@ -0,0 +1,6 @@ +function file_get_contents(file) + local fp = io.open(file,"r") + local data = fp:read("*all") + fp:close() + return data +end \ No newline at end of file diff --git a/lib.file_put_contents.lua b/lib.file_put_contents.lua new file mode 100644 index 0000000..acd54f5 --- /dev/null +++ b/lib.file_put_contents.lua @@ -0,0 +1,5 @@ +function file_put_contents(file,data) + local fp = io.open(file,"w") + fp:write(data) + fp:close() +end \ No newline at end of file diff --git a/lib.round.lua b/lib.round.lua new file mode 100644 index 0000000..5c3ec90 --- /dev/null +++ b/lib.round.lua @@ -0,0 +1,4 @@ +function round(exact, quantum) + local quant,frac = math.modf(exact/quantum) + return quantum * (quant + (frac > 0.5 and 1 or 0)) +end \ No newline at end of file diff --git a/lib.savetable.lua b/lib.savetable.lua new file mode 100644 index 0000000..f808f72 --- /dev/null +++ b/lib.savetable.lua @@ -0,0 +1,134 @@ +--[[ + Save Table to File + Load Table from File + v 1.0 + + Lua 5.2 compatible + + Only Saves Tables, Numbers and Strings + Insides Table References are saved + Does not save Userdata, Metatables, Functions and indices of these + ---------------------------------------------------- + table.save( table , filename ) + + on failure: returns an error msg + + ---------------------------------------------------- + table.load( filename or stringtable ) + + Loads a table that has been saved via the table.save function + + on success: returns a previously saved table + on failure: returns as second argument an error msg + ---------------------------------------------------- + + Licensed under the same terms as Lua itself. +]]-- +do + -- declare local variables + --// exportstring( string ) + --// returns a "Lua" portable version of the string + local function exportstring( s ) + return string.format("%q", s) + end + + --// The Save Function + function table.save( tbl,filename ) + local charS,charE = " ","\n" + local file,err = io.open( filename, "wb" ) + if err then return err end + + -- initiate variables for save procedure + local tables,lookup = { tbl },{ [tbl] = 1 } + file:write( "return {"..charE ) + + for idx,t in ipairs( tables ) do + file:write( "-- Table: {"..idx.."}"..charE ) + file:write( "{"..charE ) + local thandled = {} + + for i,v in ipairs( t ) do + thandled[i] = true + local stype = type( v ) + -- only handle value + if stype == "table" then + if not lookup[v] then + table.insert( tables, v ) + lookup[v] = #tables + end + file:write( charS.."{"..lookup[v].."},"..charE ) + elseif stype == "string" then + file:write( charS..exportstring( v )..","..charE ) + elseif stype == "number" then + file:write( charS..tostring( v )..","..charE ) + end + end + + for i,v in pairs( t ) do + -- escape handled values + if (not thandled[i]) then + + local str = "" + local stype = type( i ) + -- handle index + if stype == "table" then + if not lookup[i] then + table.insert( tables,i ) + lookup[i] = #tables + end + str = charS.."[{"..lookup[i].."}]=" + elseif stype == "string" then + str = charS.."["..exportstring( i ).."]=" + elseif stype == "number" then + str = charS.."["..tostring( i ).."]=" + end + + if str ~= "" then + stype = type( v ) + -- handle value + if stype == "table" then + if not lookup[v] then + table.insert( tables,v ) + lookup[v] = #tables + end + file:write( str.."{"..lookup[v].."},"..charE ) + elseif stype == "string" then + file:write( str..exportstring( v )..","..charE ) + elseif stype == "number" then + file:write( str..tostring( v )..","..charE ) + end + end + end + end + file:write( "},"..charE ) + end + file:write( "}" ) + file:close() + end + + --// The Load Function + function table.load( sfile ) + local ftables,err = loadfile( sfile ) + if err then return _,err end + local tables = ftables() + for idx = 1,#tables do + local tolinki = {} + for i,v in pairs( tables[idx] ) do + if type( v ) == "table" then + tables[idx][i] = tables[v[1]] + end + if type( i ) == "table" and tables[i[1]] then + table.insert( tolinki,{ i,tables[i[1]] } ) + end + end + -- link indices + for _,v in ipairs( tolinki ) do + tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil + end + end + return tables[1] + end +-- close do +end + +-- ChillCode \ No newline at end of file diff --git a/util/version.png b/util/version.png index b742486..c7e77f2 100644 Binary files a/util/version.png and b/util/version.png differ