diff --git a/mods/hudbars/API.md b/mods/hudbars/API.md
new file mode 100644
index 0000000..d18f05b
--- /dev/null
+++ b/mods/hudbars/API.md
@@ -0,0 +1,174 @@
+API documentation for the HUD bars mod 1.2.1
+============================================
+
+## Introduction
+This API allows you to add, change, hide and unhide custom HUD bars for this mod.
+
+## Overview
+To give you a *very* brief overview over this API, here is the basic workflow on how to add your own custom HUD bar:
+
+* Create images for your HUD bar
+* Call `hb.register_hudbar` to make the definition of the HUD bar known to this mod
+* Call `hb.init_hudbar` for each player for which you want to use previously defined HUD bar
+* Use `hb.change_hudbar` whenever you need to change the values of a HUD bar of a certain player
+* If you need it: Use `hb.hide_hudbar` and `hb.unhide_hudbar` to hide or unhide HUD bars of a certain player
+
+## The basic rules
+In order to use this API, you should be aware of a few basic rules in order to understand it:
+
+* A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%.
+* The current value must always be equal to or smaller then the maximum
+* Both current value and maximum must not be smaller than 0
+* Both current value and maximum must be real numbers. So no NaN, infinity, etc.
+* The HUD bar will be hidden if the maximum equals 0. This is intentional.
+* The health and breath HUD bars are hardcoded.
+
+These are soft rules, the HUD bars mod will not enforce all of these.
+But this mod has been programmed under the assumption that these rules are followed, for integrity.
+
+## Adding a HUD bar
+To make a new HUD bar known to this mod, you need …
+
+* … an image of size 2×16 for the bar
+* … an icon of size 16×16 (optional)
+* … to register it with `hb.register_hudbar`
+
+### Bar image
+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
+A 16×16 image shown left of the HUD bar. This is optional.
+
+### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string)`
+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.
+
+
+#### Parameters
+* `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.
+* `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.
+* `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`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section).
+ * `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.
+ * `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.
+* `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
+* `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
+* `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.
+* `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`.
+
+#### Return value
+Always `nil`.
+
+
+## Displaying a HUD bar
+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`.
+
+### `hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)`
+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.
+
+#### Parameters
+* `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to.
+* `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`.
+* `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`.
+* `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`
+* `start_hidden`: Whether the HUD bar is initially hidden. This is optional, `default_start_hidden` of the registration function will be used as default
+
+#### Return value
+Always `nil`.
+
+
+
+## Modifying a HUD bar
+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.
+
+### `hb.change_hudbar(player, identifier, new_value, new_max_value)`
+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.
+
+#### Parameters
+* `player`: `ObjectRef` of the player to which the HUD bar belongs to
+* `identifier`: The identifier of the HUD bar type to change, as specified in `hb.register_hudbar`.
+* `new_value`: The new current value of the HUD bar
+* `new_max_value`: The new maximum value of the HUD bar
+
+#### Return value
+Always `nil`.
+
+
+## Hiding and unhiding a HUD bar
+You can also hide custom HUD bars, meaning they will not be displayed for a certain player. You can still
+use `hb.change_hudbar` on a hidden HUD bar, the new values will be correctly displayed after the HUD bar
+has been unhidden. Both functions will only call `hud_change` if there has been an actual change to avoid
+unneccessary traffic.
+
+Note that the hidden state of a HUD bar will *not* be saved by this mod on server shutdown, so you may need
+to write your own routines for this or by setting the correct value for `start_hidden` when calling
+`hb.init_hudbar`.
+
+### `hb.hide_hudbar(player, identifier)`
+Hides the specified HUD bar from the screen of the specified player.
+
+#### Parameters
+* `player`: `ObjectRef` of the player to which the HUD bar belongs to
+* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`.
+
+#### Return value
+Always `nil`.
+
+
+### `hb.unhide_hudbar(player, identifier)`
+Makes a previously hidden HUD bar visible again to a player.
+
+#### Parameters
+* `player`: `ObjectRef` of the player to which the HUD bar belongs to
+* `identifier`: The identifier of the HUD bar type to unhide, as specified in `hb.register_hudbar`.
+
+#### Return value
+Always `nil`.
+
+
+## Reading HUD bar information
+It is also possible to read information about an active HUD bar.
+
+### `hb.get_hudbar_state(player, identifier)`
+Returns the current state of the active player's HUD bar.
+
+#### Parameters
+* `player`: `ObjectRef` of the player to which the HUD bar belongs to
+* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`.
+
+#### Return value
+A table which holds information on the current state of the HUD bar. Note the table is a deep
+copy of the internal HUD bar state, it is *not* a reference; the information hold by the table is
+only true for the moment you called this function. The fields of this table are:
+
+* `value`: Current value of HUD bar.
+* `max`: Current maximum value of HUD bar.
+* `hidden`: Boolean denoting whether the HUD bar is hidden.
+* `barlength`: The length of the HUD bar in pixels. This field is meaningless if the HUD bar is currently hidden.
+* `text`: The text shown on the HUD bar. This fiels is meaningless if the HUD bar is currently hidden.
diff --git a/mods/hudbars/README.txt b/mods/hudbars/README.txt
new file mode 100644
index 0000000..2fe7127
--- /dev/null
+++ b/mods/hudbars/README.txt
@@ -0,0 +1,109 @@
+Minetest mod: HUD bars
+======================
+Version: 1.2.1
+
+This software uses semantic versioning, as defined by version 2.0.0 of the SemVer
+standard.
+
+
+License of source code: WTFPL
+-----------------------------
+Author: Wuzzy (2015)
+Forked from the “Better HUD” [hud] mod by BlockMen.
+
+
+Using the mod:
+--------------
+This mod changes the HUD of Minetest. It replaces the default health and breath symbols by horizontal colored bars with text showing
+the number.
+
+Furthermore, it enables other mods to add their own custom bars to the HUD, this mod will place them accordingly.
+
+You can create a “hudbars.conf” file to customize the positions of the health and breath bars. Take a look at “hudbars.conf.example”
+to get more infos. The lines starting with “--” are comments, remove the two dashes to activate a setting. Settings which are not
+set will use a default value instead.
+
+
+IMPORTANT:
+Keep in mind if running a server with this mod, that the custom position should be displayed correctly on every screen size!
+
+Settings:
+---------
+This mod can be configured by editing minetest.conf. Currently, the following setting is recognized:
+
+- hudbars_autohide_breath: A boolean setting, it can be either “true” or “false”. If set to “true”,
+ the breath bar will be automatically hidden shortly after the breathbar has been filled up. If set
+ to “false”, the breath bar will always be displayed. The default value is “true”.
+
+- hudbars_sorting: This setting allows you to specify the “slot” positions of the HUD bars manually.
+
+ The setting has to be specified as a comma-seperated list of key=value pairs, where a key refers to the
+ identifier of a HUD bar and the value refers to the slot number of where the HUD bar should be placed.
+ The slot number must be an integer greater of equal to 0. The slot positions start (slot 0) at the
+ bottom (nearest to hotbar in default configuration) left side, the following slot 1 is at the right
+ side, slot `2` is on the right side again, but placed over the first HUD bar (slot 0), and it goes on,
+ in a zig-zag pattern.
+ All HUD bars to which no sorting rule has been applied will fill in all slots which have not been occupied
+ by the HUD bars specified in this setting, the slots will be filled in from the lowest slot number.
+ Note that the order of those remaining HUD bars is *not* fixed, it basically just boils down on which mod
+ “came” first. Don't worry, the mod will still work perfectly fine, this setting is entirely optional.
+
+ Be careful not to use slot indices twice, or else different HUD bars will be drawn over each other!
+
+ If this setting is not set, by default the health and breath bar are displayed at slot positions 0 and 1,
+ respectively (health bar at left bottom-most positoin, breath bar right from it). All other HUD bars are
+ placed automatically.
+
+ Example value:
+ breath=0, health=1
+ This places the breath bar at the left side, and the health bar to the right side.
+
+- hudbars_bar_type: Specifies the style of bars. You can select between the default progress-bar-like bars and the good old statbars
+ like you know from vanilla Minetest. Note that the classic and modern statbars are still a little bit experimental.
+ These values are possible:
+ - progress_bar: A horizontal progress-bar-like bar with a label, showing numerical value (current, maximum), and an icon.
+ These bars usually convey the most information. This is the default and recommended value..
+ - statbar_classic: Classic statbar, like in vanilla Minetest. Made out of up to 20 half-symbols. Those bars represent the vague ratio between
+ the current value and the maximum value. 1 half-symbol stands for approximately 5% of the maximum value.
+ - statbar_modern: Like the classic statbar, but also supports background images, this kind of statbar may be considered to be more user-friendly
+ than the classic statbar. This bar type closely resembles the [hud] mod.
+
+- hudbars_vmargin: The vertical distance between two HUD bars in pixels (default: 24)
+- hudbars_tick: The number of seconds between two updates of the HUD bars. Increase this number if you have a slow server (default: 0.1)
+
+Position settings:
+With these settings you can configure the positions of the HUD bars. All settings must be specified as a number.
+The pos settings are specified as a floating-point number between 0 to 1 each, the start_offset settings are
+specified as whole numbers, they specify a number of pixels.
+The left and right variants are used for the zig-zag mode. In the stack_up and stack_down modes, only the left variant is used for
+the base position
+
+- hudbars_pos_left_x, hudbars_pos_left_y: Screen position (x and y) of the left HUD bar in zigzag mode. 0 is left-most/top, 1 is right-most/bottom.
+ Defaults: 0.5 (x) and 1 (y)
+- hudbars_pos_right_x, hudbars_pos_right_y: Same as above, but for the right one.
+ Defaults: 0.5 and 1.
+- hudbars_start_offset_left_x, hudbars_start_offset_left_y: Offset in pixels from the basic screen position specified in hudbars_pos_left_x/hudbars_pos_left_y.
+ Defaults: -175 and -86
+- hudbars_start_offset_right_x, hudbars_start_offset_right_y: Same as above, but for the right one.
+ Defaults: 15 and -86
+
+API:
+----
+The API is used to add your own custom HUD bars.
+Documentation for the API of this mod can be found in API.md.
+
+
+License of textures:
+--------------------
+hudbars_icon_health.png - celeron55 (CC BY-SA 3.0), modified by BlockMen
+hudbars_bgicon_health.png - celeron55 (CC BY-SA 3.0), modified by BlockMen
+hudbars_icon_breath.png - kaeza (WTFPL), modified by BlockMen
+hudbars_bar_health.png - Wuzzy (WTFPL)
+hudbars_bar_breath.png - Wuzzy (WTFPL)
+hudbars_bar_background.png - Wuzzy(WTFPL)
+
+This program is free software. It comes without any warranty, to
+the extent permitted by applicable law. You can redistribute it
+and/or modify it under the terms of the Do What The Fuck You Want
+To Public License, Version 2, as published by Sam Hocevar. See
+http://sam.zoy.org/wtfpl/COPYING for more details.
diff --git a/mods/hudbars/changelog.txt b/mods/hudbars/changelog.txt
new file mode 100644
index 0000000..3c4f0bc
--- /dev/null
+++ b/mods/hudbars/changelog.txt
@@ -0,0 +1,66 @@
+Note: This software uses semantic versioning,
+as of version 2.0.0 of the standard .
+
+0.1.0
+-----
+- Initial release, forked from mod “Better HUD” [hud].
+
+0.2.0
+-----
+- Add API documentation
+
+0.3.0
+-----
+- Rename main table from “hud” to “hb” (affects function names!)
+- Arguments 3-4 of hb.change_hudbar can be nil for values which should not change
+- Add proper function hb.init_hudbar, replaces odd call to hud.hudtables[identifier].add_all
+- Update API documentation and fix mistakes
+- Use “hudbars.conf” instead of “hud.conf”
+
+0.4.0
+-----
+- New function: hb.get_hudbar_state to get information about the state of an active HUD bar, such as values, whether it is hidden, etc.
+- hb.change_hudbar has been optimized to call hud_change fewer times, which is hopefully good for networking
+- Rename hb.register_hudbar parameter “start_hide” to “start_hidden”
+- start_hidden parameter now finally works
+- Do not affect other HUD flags (crosshair, wielditem, etc.) when starting mod
+- Show error message when trying to call hb.init_hudbar or hb.change_hudbar with bad values
+- Update documentation
+- Lots of refactoring
+- Health and breath bar now use API
+
+1.0.0
+-----
+- Add new parameter start_hidden to hb.init_hudbar, specified whether HUD bar is hidden on start
+- Copy-editing of API.md and README.txt
+- Internal: Fix add_all weirdness
+
+1.0.1
+-----
+- Fix race condition causing crash at start of server
+
+1.0.2
+-----
+- Fix other HUD elements disappearing for rejoining players
+- Remove pointless delays for initializing the HUD for new or rejoining players
+
+1.0.3
+-----
+- Adjust default HUD bars position for Minetest 0.4.12
+
+1.1.0
+-----
+- Add boolean minetest.conf setting support (hudbars_autohide_breathbar) to control whether the breath bar is automatically hidden when full (default: yes)
+
+1.2.0
+-----
+- New setting: hudbars_sorting. You can now manually sort all the HUD bars. Useful if you don't like automatic order
+- New setting: hudbars_bar_type. You now can change the appearance of the HUD bars.
+- New HUD bar types, slightly experimental: Classic statbars and modern [hud]-style statbars
+- New experimental/unfinished setting: hudbars_alignment_pattern: You can now make the HUD bars stack vertically instead of the current zig-zag pattern. Note you probably need to change source code to productively use this feature
+- Various position-related HUD bar settings (see README.txt)
+- Remove hudbars.conf support and hudbars.conf.example (was never officially supported anyways)
+
+1.2.1
+-----
+- Fix crash when enable_damage is changed in mid-game
diff --git a/mods/hudbars/depends.txt b/mods/hudbars/depends.txt
new file mode 100644
index 0000000..e69de29
diff --git a/mods/hudbars/init.lua b/mods/hudbars/init.lua
new file mode 100644
index 0000000..7a30096
--- /dev/null
+++ b/mods/hudbars/init.lua
@@ -0,0 +1,491 @@
+hb = {}
+
+hb.hudtables = {}
+
+-- number of registered HUD bars
+hb.hudbars_count = 0
+
+-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
+hb.registered_slots = {}
+
+hb.settings = {}
+
+function hb.load_setting(sname, stype, defaultval, valid_values)
+ local sval
+ if stype == "string" then
+ sval = minetest.setting_get(sname)
+ elseif stype == "bool" then
+ sval = minetest.setting_getbool(sname)
+ elseif stype == "number" then
+ sval = tonumber(minetest.setting_get(sname))
+ end
+ if sval ~= nil then
+ if valid_values ~= nil then
+ local valid = false
+ for i=1,#valid_values do
+ if sval == valid_values[i] then
+ valid = true
+ end
+ end
+ if not valid then
+ minetest.log("error", "[hudbars] Invalid value for "..sname.."! Using default value ("..tostring(defaultval)..").")
+ return defaultval
+ else
+ return sval
+ end
+ else
+ return sval
+ end
+ else
+ return defaultval
+ end
+end
+
+-- (hardcoded) default settings
+hb.settings.max_bar_length = 160
+hb.settings.statbar_length = 20
+
+-- statbar positions
+hb.settings.pos_left = {}
+hb.settings.pos_right = {}
+hb.settings.start_offset_left = {}
+hb.settings.start_offset_right= {}
+hb.settings.pos_left.x = hb.load_setting("hudbars_pos_left_x", "number", 0.5)
+hb.settings.pos_left.y = hb.load_setting("hudbars_pos_left_y", "number", 1)
+hb.settings.pos_right.x = hb.load_setting("hudbars_pos_right_x", "number", 0.5)
+hb.settings.pos_right.y = hb.load_setting("hudbars_pos_right_y", "number", 1)
+hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_offset_left_x", "number", -175)
+hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_offset_left_y", "number", -86)
+hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15)
+hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86)
+
+hb.settings.vmargin = hb.load_setting("hudbars_tick", "number", 24)
+hb.settings.tick = hb.load_setting("hudbars_tick", "number", 0.1)
+
+-- experimental setting: Changing this setting is not officially supported, do NOT rely on it!
+hb.settings.forceload_default_hudbars = hb.load_setting("hudbars_forceload_default_hudbars", "bool", true)
+
+--[[
+- hudbars_alignment_pattern: This setting changes the way the HUD bars are ordered on the display. You can choose
+ between a zig-zag pattern or a vertically stacked pattern.
+ The following values are allowed:
+ zigzag: Starting from the left bottom, the next is right from the first,
+ the next is above the first, the next is right of the third, etc.
+ This is the default.
+ stack_up: The HUD bars are stacked vertically, going upwards.
+ stack_down: The HUD bars are stacked vertically, going downwards.
+]]
+
+-- Misc. settings
+hb.settings.alignment_pattern = hb.load_setting("hudbars_alignment_pattern", "string", "zigzag", {"zigzag", "stack_up", "stack_down"})
+hb.settings.bar_type = hb.load_setting("hudbars_bar_type", "string", "progress_bar", {"progress_bar", "statbar_classic", "statbar_modern"})
+hb.settings.autohide_breath = hb.load_setting("hudbars_autohide_breath", "bool", true)
+
+local sorting = minetest.setting_get("hudbars_sorting")
+if sorting ~= nil then
+ hb.settings.sorting = {}
+ hb.settings.sorting_reverse = {}
+ for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do
+ hb.settings.sorting[k] = tonumber(v)
+ hb.settings.sorting_reverse[tonumber(v)] = k
+ end
+else
+ hb.settings.sorting = { ["health"] = 0, ["breath"] = 1 }
+ hb.settings.sorting_reverse = { [0] = "health", [1] = "breath" }
+end
+
+-- Table which contains all players with active default HUD bars (only for internal use)
+hb.players = {}
+
+function hb.value_to_barlength(value, max)
+ if max == 0 then
+ return 0
+ else
+ if hb.settings.bar_type == "progress_bar" then
+ local x
+ if value < 0 then x=-0.5 else x = 0.5 end
+ local ret = math.modf((value/max) * hb.settings.max_bar_length + x)
+ return ret
+ else
+ local x
+ if value < 0 then x=-0.5 else x = 0.5 end
+ local ret = math.modf((value/max) * hb.settings.statbar_length + x)
+ return ret
+ end
+ end
+end
+
+function hb.get_hudtable(identifier)
+ return hb.hudtables[identifier]
+end
+
+function hb.get_hudbar_position_index(identifier)
+ if hb.settings.sorting[identifier] ~= nil then
+ return hb.settings.sorting[identifier]
+ else
+ local i = 0
+ while true do
+ if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then
+ return i
+ end
+ i = i + 1
+ end
+ end
+end
+
+function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string)
+ minetest.log("action", "hb.register_hudbar: "..tostring(identifier))
+ local hudtable = {}
+ local pos, offset
+ local index = math.floor(hb.get_hudbar_position_index(identifier))
+ hb.registered_slots[index] = true
+ if hb.settings.alignment_pattern == "stack_up" then
+ pos = hb.settings.pos_left
+ offset = {
+ x = hb.settings.start_offset_left.x,
+ y = hb.settings.start_offset_left.y - hb.settings.vmargin * index
+ }
+ elseif hb.settings.alignment_pattern == "stack_down" then
+ pos = hb.settings.pos_left
+ offset = {
+ x = hb.settings.start_offset_left.x,
+ y = hb.settings.start_offset_left.y + hb.settings.vmargin * index
+ }
+ else
+ if index % 2 == 0 then
+ pos = hb.settings.pos_left
+ offset = {
+ x = hb.settings.start_offset_left.x,
+ y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2)
+ }
+ else
+ pos = hb.settings.pos_right
+ offset = {
+ x = hb.settings.start_offset_right.x,
+ y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2)
+ }
+ end
+ end
+ if format_string == nil then
+ format_string = "%s: %d/%d"
+ end
+
+ hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden)
+ if start_value == nil then start_value = hudtable.default_start_value end
+ if start_max == nil then start_max = hudtable.default_start_max end
+ if start_hidden == nil then start_hidden = hudtable.default_start_hidden end
+ local ids = {}
+ local state = {}
+ local name = player:get_player_name()
+ local bgscale, iconscale, text, barnumber
+ if start_max == 0 or start_hidden then
+ bgscale = { x=0, y=0 }
+ else
+ bgscale = { x=1, y=1 }
+ end
+ if start_hidden then
+ iconscale = { x=0, y=0 }
+ barnumber = 0
+ text = ""
+ else
+ iconscale = { x=1, y=1 }
+ barnumber = hb.value_to_barlength(start_value, start_max)
+ text = string.format(format_string, label, start_value, start_max)
+ end
+ if hb.settings.bar_type == "progress_bar" then
+ ids.bg = player:hud_add({
+ hud_elem_type = "image",
+ position = pos,
+ scale = bgscale,
+ text = "hudbars_bar_background.png",
+ alignment = {x=1,y=1},
+ offset = { x = offset.x - 1, y = offset.y - 1 },
+ })
+ if textures.icon ~= nil then
+ ids.icon = player:hud_add({
+ hud_elem_type = "image",
+ position = pos,
+ scale = iconscale,
+ text = textures.icon,
+ alignment = {x=-1,y=1},
+ offset = { x = offset.x - 3, y = offset.y },
+ })
+ end
+ elseif hb.settings.bar_type == "statbar_modern" then
+ if textures.bgicon ~= nil then
+ ids.bg = player:hud_add({
+ hud_elem_type = "statbar",
+ position = pos,
+ scale = bgscale,
+ text = textures.bgicon,
+ number = hb.settings.statbar_length,
+ alignment = {x=-1,y=-1},
+ offset = { x = offset.x, y = offset.y },
+ })
+ end
+ end
+ local bar_image
+ if hb.settings.bar_type == "progress_bar" then
+ bar_image = textures.bar
+ elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then
+ bar_image = textures.icon
+ end
+ ids.bar = player:hud_add({
+ hud_elem_type = "statbar",
+ position = pos,
+ text = bar_image,
+ number = barnumber,
+ alignment = {x=-1,y=-1},
+ offset = offset,
+ })
+ if hb.settings.bar_type == "progress_bar" then
+ ids.text = player:hud_add({
+ hud_elem_type = "text",
+ position = pos,
+ text = text,
+ alignment = {x=1,y=1},
+ number = text_color,
+ direction = 0,
+ offset = { x = offset.x + 2, y = offset.y },
+ })
+ end
+ -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table
+ state.hidden = start_hidden
+ state.value = start_value
+ state.max = start_max
+ state.text = text
+ state.barlength = hb.value_to_barlength(start_value, start_max)
+
+ local main_error_text =
+ "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."” for player "..name..". "
+
+ if start_max < start_value then
+ minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!")
+ end
+ if start_max < 0 then
+ minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!")
+ end
+ if start_value < 0 then
+ minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!")
+ end
+
+ hb.hudtables[identifier].hudids[name] = ids
+ hb.hudtables[identifier].hudstate[name] = state
+ end
+
+ hudtable.identifier = identifier
+ hudtable.format_string = format_string
+ hudtable.label = label
+ hudtable.hudids = {}
+ hudtable.hudstate = {}
+ hudtable.default_start_hidden = default_start_hidden
+ hudtable.default_start_value = default_start_value
+ hudtable.default_start_max = default_start_max
+
+ hb.hudbars_count= hb.hudbars_count + 1
+
+ hb.hudtables[identifier] = hudtable
+end
+
+function hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)
+ local hudtable = hb.get_hudtable(identifier)
+ hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden)
+end
+
+function hb.change_hudbar(player, identifier, new_value, new_max_value)
+ if new_value == nil and new_max_value == nil then
+ return
+ end
+
+ local name = player:get_player_name()
+ local hudtable = hb.get_hudtable(identifier)
+ local value_changed, max_changed = false, false
+
+ if new_value ~= nil then
+ if new_value ~= hudtable.hudstate[name].value then
+ hudtable.hudstate[name].value = new_value
+ value_changed = true
+ end
+ else
+ new_value = hudtable.hudstate[name].value
+ end
+ if new_max_value ~= nil then
+ if new_max_value ~= hudtable.hudstate[name].max then
+ hudtable.hudstate[name].max = new_max_value
+ max_changed = true
+ end
+ else
+ new_max_value = hudtable.hudstate[name].max
+ end
+
+ local main_error_text =
+ "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. "
+ if new_max_value < new_value then
+ minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!")
+ end
+ if new_max_value < 0 then
+ minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!")
+ end
+ if new_value < 0 then
+ minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!")
+ end
+
+ if hudtable.hudstate[name].hidden == false then
+ if max_changed and hb.settings.bar_type == "progress_bar" then
+ if hudtable.hudstate[name].max == 0 then
+ player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
+ else
+ player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
+ end
+ end
+
+ if value_changed or max_changed then
+ local new_barlength = hb.value_to_barlength(new_value, new_max_value)
+ if new_barlength ~= hudtable.hudstate[name].barlength then
+ player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value))
+ hudtable.hudstate[name].barlength = new_barlength
+ end
+
+ if hb.settings.bar_type == "progress_bar" then
+ local new_text = string.format(hudtable.format_string, hudtable.label, new_value, new_max_value)
+ if new_text ~= hudtable.hudstate[name].text then
+ player:hud_change(hudtable.hudids[name].text, "text", new_text)
+ hudtable.hudstate[name].text = new_text
+ end
+ end
+ end
+ end
+end
+
+function hb.hide_hudbar(player, identifier)
+ local name = player:get_player_name()
+ local hudtable = hb.get_hudtable(identifier)
+ if(hudtable.hudstate[name].hidden == false) then
+ if hb.settings.bar_type == "progress_bar" then
+ if hudtable.hudids[name].icon ~= nil then
+ player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
+ end
+ player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
+ player:hud_change(hudtable.hudids[name].text, "text", "")
+ end
+ player:hud_change(hudtable.hudids[name].bar, "number", 0)
+ hudtable.hudstate[name].hidden = true
+ end
+end
+
+function hb.unhide_hudbar(player, identifier)
+ local name = player:get_player_name()
+ local hudtable = hb.get_hudtable(identifier)
+ if(hudtable.hudstate[name].hidden) then
+ local name = player:get_player_name()
+ local value = hudtable.hudstate[name].value
+ local max = hudtable.hudstate[name].max
+ if hb.settings.bar_type == "progress_bar" then
+ if hudtable.hudids[name].icon ~= nil then
+ player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
+ end
+ if hudtable.hudstate[name].max ~= 0 then
+ player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
+ end
+ player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
+ end
+ player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max))
+ hudtable.hudstate[name].hidden = false
+ end
+end
+
+function hb.get_hudbar_state(player, identifier)
+ local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()]
+ -- Do not forget to update this chunk of code in case the state changes
+ local copy = {
+ hidden = ref.hidden,
+ value = ref.value,
+ max = ref.max,
+ text = ref.text,
+ barlength = ref.barlength,
+ }
+ return copy
+end
+
+--register built-in HUD bars
+if minetest.setting_getbool("enable_damage") or hb.settings.forceload_default_hudbars then
+ hb.register_hudbar("health", 0xFFFFFF, "Health", { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false)
+ hb.register_hudbar("breath", 0xFFFFFF, "Breath", { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png" }, 10, 10, true)
+end
+
+local function hide_builtin(player)
+ local flags = player:hud_get_flags()
+ flags.healthbar = false
+ flags.breathbar = false
+ player:hud_set_flags(flags)
+end
+
+
+local function custom_hud(player)
+ if minetest.setting_getbool("enable_damage") or hb.settings.forceload_default_hudbars then
+ local hide
+ if minetest.setting_getbool("enable_damage") then
+ hide = false
+ else
+ hide = true
+ end
+ hb.init_hudbar(player, "health", player:get_hp(), nil, hide)
+ local breath = player:get_breath()
+ local hide_breath
+ if breath == 11 and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end
+ hb.init_hudbar(player, "breath", math.min(breath, 10), nil, hide_breath or hide)
+ end
+end
+
+
+-- update built-in HUD bars
+local function update_hud(player)
+ if minetest.setting_getbool("enable_damage") then
+ if hb.settings.forceload_default_hudbars then
+ hb.unhide_hudbar(player, "health")
+ end
+ --air
+ local breath = player:get_breath()
+
+ if breath == 11 and hb.settings.autohide_breath == true then
+ hb.hide_hudbar(player, "breath")
+ else
+ hb.unhide_hudbar(player, "breath")
+ hb.change_hudbar(player, "breath", math.min(breath, 10))
+ end
+
+ --health
+ hb.change_hudbar(player, "health", player:get_hp())
+ elseif hb.settings.forceload_default_hudbars then
+ hb.hide_hudbar(player, "health")
+ hb.hide_hudbar(player, "breath")
+ end
+end
+
+minetest.register_on_joinplayer(function(player)
+ hide_builtin(player)
+ custom_hud(player)
+ hb.players[player:get_player_name()] = player
+end)
+
+minetest.register_on_leaveplayer(function(player)
+ hb.players[player:get_player_name()] = nil
+end)
+
+local main_timer = 0
+local timer = 0
+minetest.register_globalstep(function(dtime)
+ main_timer = main_timer + dtime
+ timer = timer + dtime
+ if main_timer > hb.settings.tick or timer > 4 then
+ if main_timer > hb.settings.tick then main_timer = 0 end
+ -- only proceed if damage is enabled
+ if minetest.setting_getbool("enable_damage") or hb.settings.forceload_default_hudbars then
+ for playername, player in pairs(hb.players) do
+ -- update all hud elements
+ update_hud(player)
+ end
+ end
+ end
+ if timer > 4 then timer = 0 end
+end)
diff --git a/mods/hudbars/textures/hudbars_bar_background.png b/mods/hudbars/textures/hudbars_bar_background.png
new file mode 100644
index 0000000..cbc6c3f
Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_background.png differ
diff --git a/mods/hudbars/textures/hudbars_bar_breath.png b/mods/hudbars/textures/hudbars_bar_breath.png
new file mode 100644
index 0000000..7d19a57
Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_breath.png differ
diff --git a/mods/hudbars/textures/hudbars_bar_health.png b/mods/hudbars/textures/hudbars_bar_health.png
new file mode 100644
index 0000000..6530916
Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_health.png differ
diff --git a/mods/hudbars/textures/hudbars_bgicon_health.png b/mods/hudbars/textures/hudbars_bgicon_health.png
new file mode 100644
index 0000000..e2be276
Binary files /dev/null and b/mods/hudbars/textures/hudbars_bgicon_health.png differ
diff --git a/mods/hudbars/textures/hudbars_icon_breath.png b/mods/hudbars/textures/hudbars_icon_breath.png
new file mode 100644
index 0000000..f48aa35
Binary files /dev/null and b/mods/hudbars/textures/hudbars_icon_breath.png differ
diff --git a/mods/hudbars/textures/hudbars_icon_health.png b/mods/hudbars/textures/hudbars_icon_health.png
new file mode 100644
index 0000000..941e973
Binary files /dev/null and b/mods/hudbars/textures/hudbars_icon_health.png differ
diff --git a/mods/sprint/COPYING b/mods/sprint/COPYING
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/mods/sprint/COPYING
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/mods/sprint/README.md b/mods/sprint/README.md
new file mode 100644
index 0000000..71e7d44
--- /dev/null
+++ b/mods/sprint/README.md
@@ -0,0 +1,62 @@
+Sprint Mod For Minetest by GunshipPenguin
+
+Allows the player to sprint by either double tapping w or pressing e.
+By default, sprinting will make the player travel 80% faster and
+allow him/her to jump 10% higher. Also adds a stamina bar that goes
+down when the player sprints and goes up when he/she isn't
+sprinting.
+
+This mod is compatible with the HUD bars [hudbars] mod, but does
+not depend on it. In this care, a green HUD bar will be displayed,
+also showing a number.
+If this mod is not present, a standard statbar with 0-20
+“half-arrows” is shown, which is a bit more coarse than the HUD
+bar version.
+
+
+Licence: CC0 (see COPYING file)
+
+---
+
+This mod can be configured by changing the variables declared in
+the start of init.lua. The following is a brief explanation of each
+one.
+
+SPRINT_METHOD (default 1)
+
+What a player has to do to start sprinting. 0 = double tap w, 1 = press e.
+Note that if you have the fast privlige, and have the fast
+speed turned on, you will run very, very fast. You can toggle this
+by pressing j.
+
+SPRINT_SPEED (default 1.5)
+
+How fast the player will move when sprinting as opposed to normal
+movement speed. 1.0 represents normal speed so 1.5 would mean that a
+sprinting player would travel 50% faster than a walking player and
+2.4 would mean that a sprinting player would travel 140% faster than
+a walking player.
+
+SPRINT_JUMP (default 1.1)
+
+How high the player will jump when sprinting as opposed to normal
+jump height. Same as SPRINT_SPEED, just controls jump height while
+sprinting rather than speed.
+
+SPRINT_STAMINA (default 20)
+
+How long the player can sprint for in seconds. Each player has a
+stamina variable assigned to them, it is initially set to
+SPRINT_STAMINA and can go no higher. When the player is sprinting,
+this variable ticks down once each second, and when it reaches 0,
+the player stops sprinting. It ticks back up when the player isn't
+sprinting and stops at SPRINT_STAMINA. Set this to a huge value if
+you want unlimited sprinting.
+
+SPRINT_TIMEOUT (default 0.5)
+
+Only used if SPRINT_METHOD = 0.
+How much time the player has after releasing w, to press w again and
+start sprinting. Setting this too high will result in unwanted
+sprinting and setting it too low will result in it being
+difficult/impossible to sprint.
diff --git a/mods/sprint/depends.txt b/mods/sprint/depends.txt
new file mode 100644
index 0000000..3e1d5c2
--- /dev/null
+++ b/mods/sprint/depends.txt
@@ -0,0 +1 @@
+hudbars?
diff --git a/mods/sprint/esprint.lua b/mods/sprint/esprint.lua
new file mode 100644
index 0000000..7deeb6a
--- /dev/null
+++ b/mods/sprint/esprint.lua
@@ -0,0 +1,125 @@
+--[[
+Sprint mod for Minetest by GunshipPenguin
+
+To the extent possible under law, the author(s)
+have dedicated all copyright and related and neighboring rights
+to this software to the public domain worldwide. This software is
+distributed without any warranty.
+]]
+
+local players = {}
+local staminaHud = {}
+
+minetest.register_on_joinplayer(function(player)
+ local playerName = player:get_player_name()
+
+ players[playerName] = {
+ sprinting = false,
+ timeOut = 0,
+ stamina = SPRINT_STAMINA,
+ shouldSprint = false,
+ }
+ if SPRINT_HUDBARS_USED then
+ hb.init_hudbar(player, "sprint")
+ else
+ players[playerName].hud = player:hud_add({
+ hud_elem_type = "statbar",
+ position = {x=0.5,y=1},
+ size = {x=24, y=24},
+ text = "sprint_stamina_icon.png",
+ number = 20,
+ alignment = {x=0,y=1},
+ offset = {x=-263, y=-110},
+ }
+ )
+ end
+end)
+minetest.register_on_leaveplayer(function(player)
+ local playerName = player:get_player_name()
+ players[playerName] = nil
+end)
+minetest.register_globalstep(function(dtime)
+ --Get the gametime
+ local gameTime = minetest.get_gametime()
+
+ --Loop through all connected players
+ for playerName,playerInfo in pairs(players) do
+ local player = minetest.get_player_by_name(playerName)
+ if player ~= nil then
+ --Check if the player should be sprinting
+ if player:get_player_control()["aux1"] and player:get_player_control()["up"] then
+ players[playerName]["shouldSprint"] = true
+ else
+ players[playerName]["shouldSprint"] = false
+ end
+
+ --If the player is sprinting, create particles behind him/her
+ if playerInfo["sprinting"] == true and gameTime % 0.1 == 0 then
+ local numParticles = math.random(1, 2)
+ local playerPos = player:getpos()
+ local playerNode = minetest.get_node({x=playerPos["x"], y=playerPos["y"]-1, z=playerPos["z"]})
+ if playerNode["name"] ~= "air" then
+ for i=1, numParticles, 1 do
+ minetest.add_particle({
+ pos = {x=playerPos["x"]+math.random(-1,1)*math.random()/2,y=playerPos["y"]+0.1,z=playerPos["z"]+math.random(-1,1)*math.random()/2},
+ velocity = {x=0, y=5, z=0},
+ acceleration = {x=0, y=-13, z=0},
+ expirationtime = math.random(),
+ size = math.random()+0.5,
+ collisiondetection = true,
+ vertical = false,
+ texture = "sprint_particle.png",
+ })
+ end
+ end
+ end
+
+ --Adjust player states
+ if players[playerName]["shouldSprint"] == true then --Stopped
+ setSprinting(playerName, true)
+ elseif players[playerName]["shouldSprint"] == false then
+ setSprinting(playerName, false)
+ end
+
+ --Lower the player's stamina by dtime if he/she is sprinting and set his/her state to 0 if stamina is zero
+ if playerInfo["sprinting"] == true then
+ playerInfo["stamina"] = playerInfo["stamina"] - dtime
+ if playerInfo["stamina"] <= 0 then
+ playerInfo["stamina"] = 0
+ setSprinting(playerName, false)
+ end
+
+ --Increase player's stamina if he/she is not sprinting and his/her stamina is less than SPRINT_STAMINA
+ elseif playerInfo["sprinting"] == false and playerInfo["stamina"] < SPRINT_STAMINA then
+ playerInfo["stamina"] = playerInfo["stamina"] + dtime
+ end
+ -- Cap stamina at SPRINT_STAMINA
+ if playerInfo["stamina"] > SPRINT_STAMINA then
+ playerInfo["stamina"] = SPRINT_STAMINA
+ end
+
+ --Update the players's hud sprint stamina bar
+
+ if SPRINT_HUDBARS_USED then
+ hb.change_hudbar(player, "sprint", playerInfo["stamina"])
+ else
+ local numBars = (playerInfo["stamina"]/SPRINT_STAMINA)*20
+ player:hud_change(playerInfo["hud"], "number", numBars)
+ end
+ end
+ end
+end)
+
+function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting)
+ local player = minetest.get_player_by_name(playerName)
+ if players[playerName] then
+ players[playerName]["sprinting"] = sprinting
+ if sprinting == true then
+ player:set_physics_override({speed=SPRINT_SPEED,jump=SPRINT_JUMP})
+ elseif sprinting == false then
+ player:set_physics_override({speed=1.0,jump=1.0})
+ end
+ return true
+ end
+ return false
+end
diff --git a/mods/sprint/init.lua b/mods/sprint/init.lua
new file mode 100644
index 0000000..5108bac
--- /dev/null
+++ b/mods/sprint/init.lua
@@ -0,0 +1,34 @@
+--[[
+Sprint mod for Minetest by GunshipPenguin
+
+To the extent possible under law, the author(s)
+have dedicated all copyright and related and neighboring rights
+to this software to the public domain worldwide. This software is
+distributed without any warranty.
+]]
+
+--Configuration variables, these are all explained in README.md
+SPRINT_METHOD = 1
+SPRINT_SPEED = 1.8
+SPRINT_JUMP = 1.1
+SPRINT_STAMINA = 20
+SPRINT_TIMEOUT = 0.5 --Only used if SPRINT_METHOD = 0
+
+if minetest.get_modpath("hudbars") ~= nil then
+ hb.register_hudbar("sprint", 0xFFFFFF, "Stamina",
+ { bar = "sprint_stamina_bar.png", icon = "sprint_stamina_icon.png" },
+ SPRINT_STAMINA, SPRINT_STAMINA,
+ false, "%s: %.1f/%.1f")
+ SPRINT_HUDBARS_USED = true
+else
+ SPRINT_HUDBARS_USED = false
+end
+
+if SPRINT_METHOD == 0 then
+ dofile(minetest.get_modpath("sprint") .. "/wsprint.lua")
+elseif SPRINT_METHOD == 1 then
+ dofile(minetest.get_modpath("sprint") .. "/esprint.lua")
+else
+ minetest.log("error", "Sprint Mod - SPRINT_METHOD is not set properly, using e to sprint")
+ dofile(minetest.get_modpath("sprint") .. "/esprint.lua")
+end
diff --git a/mods/sprint/textures/sprint_particle.png b/mods/sprint/textures/sprint_particle.png
new file mode 100644
index 0000000..451fbba
Binary files /dev/null and b/mods/sprint/textures/sprint_particle.png differ
diff --git a/mods/sprint/textures/sprint_stamina_bar.png b/mods/sprint/textures/sprint_stamina_bar.png
new file mode 100644
index 0000000..1ca7a75
Binary files /dev/null and b/mods/sprint/textures/sprint_stamina_bar.png differ
diff --git a/mods/sprint/textures/sprint_stamina_icon.png b/mods/sprint/textures/sprint_stamina_icon.png
new file mode 100644
index 0000000..eb661eb
Binary files /dev/null and b/mods/sprint/textures/sprint_stamina_icon.png differ
diff --git a/mods/sprint/wsprint.lua b/mods/sprint/wsprint.lua
new file mode 100644
index 0000000..394edbc
--- /dev/null
+++ b/mods/sprint/wsprint.lua
@@ -0,0 +1,135 @@
+--[[
+Sprint mod for Minetest by GunshipPenguin
+
+To the extent possible under law, the author(s)
+have dedicated all copyright and related and neighboring rights
+to this software to the public domain worldwide. This software is
+distributed without any warranty.
+]]
+
+local players = {}
+local staminaHud = {}
+
+minetest.register_on_joinplayer(function(player)
+ local playerName = player:get_player_name()
+ players[playerName] = {
+ state = 0,
+ timeOut = 0,
+ stamina = SPRINT_STAMINA,
+ moving = false,
+ }
+
+ if SPRINT_HUDBARS_USED then
+ hb.init_hudbar(player, "sprint")
+ else
+ players[playerName].hud = player:hud_add({
+ hud_elem_type = "statbar",
+ position = {x=0.5,y=1},
+ size = {x=24, y=24},
+ text = "sprint_stamina_icon.png",
+ number = 20,
+ alignment = {x=0,y=1},
+ offset = {x=-263, y=-110},
+ }
+ )
+ end
+end)
+minetest.register_on_leaveplayer(function(player)
+ local playerName = player:get_player_name()
+ players[playerName] = nil
+end)
+minetest.register_globalstep(function(dtime)
+ --Get the gametime
+ local gameTime = minetest.get_gametime()
+
+ --Loop through all connected players
+ for playerName,playerInfo in pairs(players) do
+ local player = minetest.get_player_by_name(playerName)
+ if player ~= nil then
+ --Check if they are moving or not
+ players[playerName]["moving"] = player:get_player_control()["up"]
+
+ --If the player has tapped w longer than SPRINT_TIMEOUT ago, set his/her state to 0
+ if playerInfo["state"] == 2 then
+ if playerInfo["timeOut"] + SPRINT_TIMEOUT < gameTime then
+ players[playerName]["timeOut"] = nil
+ setState(playerName, 0)
+ end
+
+ --If the player is sprinting, create particles behind him/her
+ elseif playerInfo["state"] == 3 and gameTime % 0.1 == 0 then
+ local numParticles = math.random(1, 2)
+ local playerPos = player:getpos()
+ local playerNode = minetest.get_node({x=playerPos["x"], y=playerPos["y"]-1, z=playerPos["z"]})
+ if playerNode["name"] ~= "air" then
+ for i=1, numParticles, 1 do
+ minetest.add_particle({
+ pos = {x=playerPos["x"]+math.random(-1,1)*math.random()/2,y=playerPos["y"]+0.1,z=playerPos["z"]+math.random(-1,1)*math.random()/2},
+ velocity = {x=0, y=5, z=0},
+ acceleration = {x=0, y=-13, z=0},
+ expirationtime = math.random(),
+ size = math.random()+0.5,
+ collisiondetection = true,
+ vertical = false,
+ texture = "sprint_particle.png",
+ })
+ end
+ end
+ end
+
+ --Adjust player states
+ if players[playerName]["moving"] == false and playerInfo["state"] == 3 then --Stopped
+ setState(playerName, 0)
+ elseif players[playerName]["moving"] == true and playerInfo["state"] == 0 then --Moving
+ setState(playerName, 1)
+ elseif players[playerName]["moving"] == false and playerInfo["state"] == 1 then --Primed
+ setState(playerName, 2)
+ elseif players[playerName]["moving"] == true and playerInfo["state"] == 2 then --Sprinting
+ setState(playerName, 3)
+ end
+
+ --Lower the player's stamina by dtime if he/she is sprinting and set his/her state to 0 if stamina is zero
+ if playerInfo["state"] == 3 then
+ playerInfo["stamina"] = playerInfo["stamina"] - dtime
+ if playerInfo["stamina"] <= 0 then
+ playerInfo["stamina"] = 0
+ setState(playerName, 0)
+ end
+
+ --Increase player's stamina if he/she is not sprinting and his/her stamina is less than SPRINT_STAMINA
+ elseif playerInfo["state"] ~= 3 and playerInfo["stamina"] < SPRINT_STAMINA then
+ playerInfo["stamina"] = playerInfo["stamina"] + dtime
+ end
+ -- Cap stamina at SPRINT_STAMINA
+ if playerInfo["stamina"] > SPRINT_STAMINA then
+ playerInfo["stamina"] = SPRINT_STAMINA
+ end
+
+ --Update the players's hud sprint stamina bar
+
+ if SPRINT_HUDBARS_USED then
+ hb.change_hudbar(player, "sprint", playerInfo["stamina"])
+ else
+ local numBars = (playerInfo["stamina"]/SPRINT_STAMINA)*20
+ player:hud_change(playerInfo["hud"], "number", numBars)
+ end
+ end
+ end
+end)
+
+function setState(playerName, state) --Sets the state of a player (0=stopped, 1=moving, 2=primed, 3=sprinting)
+ local player = minetest.get_player_by_name(playerName)
+ local gameTime = minetest.get_gametime()
+ if players[playerName] then
+ players[playerName]["state"] = state
+ if state == 0 then--Stopped
+ player:set_physics_override({speed=1.0,jump=1.0})
+ elseif state == 2 then --Primed
+ players[playerName]["timeOut"] = gameTime
+ elseif state == 3 then --Sprinting
+ player:set_physics_override({speed=SPRINT_SPEED,jump=SPRINT_JUMP})
+ end
+ return true
+ end
+ return false
+end