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