This commit is contained in:
Rainer 2025-08-22 02:04:48 +02:00
commit 2d26db1c5b
38 changed files with 2837 additions and 0 deletions

21
LICENSE.txt Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) “Linuxdirk”
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

41
README.md Normal file
View file

@ -0,0 +1,41 @@
***Hunger NG*** *is a mod for Luanti adding a very customizable and easy to extend hunger system.*
The mod adds a hunger bar at the position of the breath bar and hides the bar if the breath bar becomes visible so the most important bar is shown without cluttering the UI too much.
![Hiding/Showing the hunger bar](hunger_bar_hiding.gif)
*Hunger NG* works in singleplayer mode as well as on a multiplayer server. It automatically disables itself when damage is disabled and adapts to the used texture pack. The mod is self-contained and has no dependencies.
## Main difference to most (if not all) hunger mods
All of the hunger-related information is stored as custom player attributes or custom item attributes. There are no global tables polluting the mod namespace or held in the mods local chunk. Its all nice and clean stored in players and items.
Hunger points get subtracted directly from the hunger value instead of being calculated to some sort of exhaustion value thats being used to reduce the hunger. This gives more detailed control over how many hunger a specific action will cause.
## 3rd-party mod support
Hunger NG support was added by the following mods.
* [hbSprint](https://forum.luanti.org/viewtopic.php?t=18069)
* [DG SPRINT: HUNGER](https://content.luanti.org/packages/digitalnoob/dg_sprint_hunger_ng/)
Built-in support for the following mods was added.
* [Berry Bushes](https://forum.luanti.org/viewtopic.php?t=14068)
* [Ethereal NG](https://forum.luanti.org/viewtopic.php?t=14638)
* [Farming Redo](https://forum.luanti.org/viewtopic.php?t=9019)
* [Ferns](https://forum.luanti.org/viewtopic.php?id=6921)
* [HUD bars](https://forum.luanti.org/viewtopic.php?t=11153)
* [Mobs Redo](https://forum.luanti.org/viewtopic.php?t=9917)
* [More Trees](https://forum.luanti.org/viewtopic.php?t=4394)
Built-in support for the following games was added.
* [Minetest Game](https://forum.luanti.org/viewtopic.php?t=9724)
## Translations
Missing your language? Feel free to add it!
[![Translation status](https://translate.codeberg.org/widget/linuxdirks-luanti-mods/hunger_ng/287x66-grey.png)](https://translate.codeberg.org/projects/linuxdirks-luanti-mods/hunger_ng)

217
doc/README.API.md Normal file
View file

@ -0,0 +1,217 @@
# API Usage
Hunger NG provides an API so other mods can have interoperability functionality. The API is represented by the global table `hunger_ng`. To reliably use the API, modders need to depend or opt-depend their mod to Hunger NG (`hunger_ng`).
## Adding hunger data
Modders can easily add satiation and health information to their custom food by running the function `add_hunger_data` from the global `hunger_ng` table after they registered their food.
```Lua
hunger_ng.add_hunger_data('modname:itemname', {
satiates = 2.5,
heals = 0,
returns = 'mymod:myitem',
timeout = 4
})
```
Floats are allowed for `satiates` only. Health points and the timeout are always integers. Using food to satiate only is preferred. The item defined in `returns` will be returned when the food is eaten. If there is no space in the inventory the food cant be eaten.
Values not to be set can be omitted in the table.
### On the timeout attribute …
Foods can have a timeout set. When set it prevents the food (and all other foods that have a similar or higher timeout or a timeout thats within the current timeout time) to be eaten again while the timeout is active. The timeout also takes place when trying to eat the food after another food.
Foods without timeout can be eaten at any time if no default timeout is set. See the configuration readme for more details on setting a default timeout. To make sure the food can be eaten regardless of the default timeout set `timeout = 0` in the definition. Otherwise the default timeout is applied.
All foods reset the timeout period. Example: When eating food with timeout `10` right after eating something (food item and set timeout for that item do not matter) you need to wait 10 seconds. When eating an item with timeout `0` after 9 seconds it works but now you need to wait 10 more seconds to eat the other item with timeout `10`.
## Changing hunger
It is possible for modders to change hunger in their mods without having to care about the correct attributes. In the global table there is a function for that.
hunger_ng.alter_hunger('Foobar', -5, 'optional reason')
This removes 5 hunger points from Foobars hunger value with the reason “optional reason”. Since the reason is optional it can be omitted. If given it should be as short as possible. If it is longer than 3 words reconsider it.
The function can be used in a globalstep that loops over all players, too.
```Lua
local timer = 0
core.register_globalstep(function(dtime)
timer = timer + dtime
if timer >= 1 then
timer = 0
for _,player in ipairs(core.get_connected_players()) do
if player ~= nil then
hunger_ng.alter_hunger(player:get_player_name(), 1, 'because I can')
end
end
end
end)
```
This globalstep iterates over all players and gives them 1 hunger point every second with the reason “because I can”. The reason is shown in the log files if Hunger NGs debug mode is enabled (you should not do that, it spams your logs with A LOT of lines).
Be careful with globalsteps because they can cause server lag.
### Enable/Disable hunger
An API function for enabling or disabling hunger on a per-player basis is available. The function can be used by other mods to disable and re-enable the hunger functionality.
hunger_ng.configure_hunger('Foobar', 'disable')
The example disables all hunger functionality for the player “Foobar”. When passing `enable` to the function the hunger gets enabled.
While disabled the normal eating functionality is restored (eating directly heals the player) and the default hunger bar is removed.
#### Automatic server-wide disabling
On server start it is checked if damage is enabled. If this is the case then the mod loading is stopped right at the beginning. No hunger functionality is enabled and the mod is not loaded.
If there are no food items registered using `hunger_ng.add_hunger_data()` then the mod is loaded but none of the hunger-related functions are running and the hunger bar is not shown. Mods registering their food without using the API function can change the “registered food items” amount manually.
```Lua
-- Scheme
hunger_ng.food_itmes = {
satiating = 0,
starving = 0,
healing = 0,
injuring = 0,
}
-- Manually add one satiating food item to the check
hunger_ng.food_items.satiating = hunger_ng.food_items.satiating + 1
```
This is of course not recommended. Always use `hunger_ng.add_hunger_data()` in order to register hunger information to edible food. This automatically handles all the necessary checks.
## Getting hunger information
If modders want to get a players hunger information they can use `hunger_ng.get_hunger_information()` This returns a table with all relevant hunger-related information for the given player name.
```Lua
local info = hunger_ng.get_hunger_information('Foobar')
```
The information of the returned table can be used for further processing. Be aware that the value should not be stored for too long because the actual value will change over time and actions basing on the hunger value might not be exact anymore.
```Lua
{
player_name = 'Foobar',
hunger = {
floored = 18,
ceiled = 19
exact = 18.928,
disabled = false,
enabled = true
},
maximum = {
hunger = 20,
health = 20,
breath = 11
},
effects = {
starving = { enabled = true, status = false },
healing = { enabled = true, status = true },
current_breath = 11
},
timestamps = {
last_eaten = 1549670580,
request = 1549671198
}
}
```
The `hunger` sub-table contains five values. `floored` is the next lower full number while `ceiled` is the next higher full number (this value is used to create the hunger bar from). The `exact` value represents the hunger value at the moment when the request was made and can be a floating point number.
The `disabled` value indicates if hunger is generally disabled for the player either because the player has no interact permission or the player has the corresponding meta information set. This can be used by other mods to control hunger management as a whole.
The `enabled` value indicates if the hunger effect (i.e. losing hunger points when moving, when placing nodes, etc.) is enabled. This can be used by mods to control the effects that causing the loss of hunger points without disabling hunger as a whole.
The `maximum` sub-table is a convenient way to get the maximum values of the settings for this user.
In `effects` the current player effects are given. The `starving` and `healing` tables indicate if the player is below the starving limit or above the healing limit (the respective `status` values are `true` then) and if the effect is enabled (`enabled` is `true` then). If the status of both values is `false` then the user is within the frame between those two limits. `current_breath` gives the current breath of the player.
The sub-table `timestamps` contains timestamps according to the server time. `last_eaten` is the value of when the player ate something for the last time or is `0` if the player never ate anything before. `request` is the value of when the request was made. It can be used to determine the age of the information.
If the given player name is not a name of a currently available player the returned table contains two entries.
```Lua
{
invalid = true,
player_name = 'Foobar'
}
```
The `player_name` is the name of the player that cant be found and `invalid` can be used as check if the request was successful.
```Lua
local info = hunger_ng.get_hunger_information('Foobar')
if info.invalid then
print(info.player_name..' cant be found.')
else
print('Hunger of '..info.player_name..' is at '..info.hunger.exact..'.')
end
```
This example prints either `Foobar cant be found.` or `Hunger of Foobar is at 18.928.` depending on if the user is available or not.
## Mod compatibility
The hunger bar is in the same position as the breath bar (the bubbles that appear when a player is awash) and disappears if the breath bar becomes visible. Any mod changing the position of the breath bar needs to change the position of the hunger bar as well.
Mods that alter or replace food with own versions ignoring custom item attributes will render them unusable for *Hunger NG* resulting in not being processed by *Hunger NG* but handled regularly.
Mods using the `/hunger` or `/myhunger` chat commands will either break or be broken when used in combination with *Hunger NG*.
Mods deleting or overwriting the global table `hunger_ng` break any mods that use the functions that are stored in the table.
### Change hunger bar image
By default a simple fallback bread image is used by *Hunger NG*. This image can easily be changed by setting `hunger_ng.hunger_bar_image` to a valid texture file name. This can be done from other mods as well as from within interoperability files.
```Lua
hunger_ng.hunger_bar_image = 'mymod_texturename.png'
```
The change does not need a restart and is applied automatically for all players as soon as the value is changed.
### Change hunger effects
Mods can control the effects that the hunger value has on a polayer as well as the change of the hunger value when actions are performed that cost hunger points.
```Lua
hunger_ng.set_effect('Playername', 'effect', 'setting')
```
The `'setting'` can be either `'enabled'` or `'disabled'`. The follwoing values for `'effect'` are valid:
* `heal` - If disabled the player wont heal even if all conditions for healing are met.
* `hunger` - If disabled actions that normally cost hunger points do not cost hunger points, basal metabolism is also disabled.
* `starve` - If disabled the player wont starve even if all conditions for starving are met.
The changes to the hunger effects are not persistent by design. This circumvents issues when effects were changed by a mod that then is unloaded or does not alter the effects after disbaling them.
Mods that need the effects to be persistent between logins need to track the changes on their own and need to disable the effects again **after** the player joined. Hunger NG resets the effect values in a `core.register_on_joinplayer` definition. Mods doing the same might cause race conditions.
### Interoperability
Hunger NG provides an interoperability system. This system allows adding support for mods (for example adding hunger information to the items of that mod).
If you want to change this for your own server (you need to track changes on mod updates by yourself, though) simply add a file named after the mod you want to support in the `interoperability` directory.
The interoperability system is seen as a temporary solution or a fallback solution. The preferred way is to contact the original mods author and ask them to add Hunger NG support and point them to this API documentation. If theyre not interested in supporting Hunger NG feel free to file an issue or create a merge request.
#### Additional interoperability functions
The API table provides additional function for interoperability reasons in the sub table `hunger_ng.interoperability`.
`attributes` provides the attribute names for the various meta data that is stored in the player objects.
`get_data` and `set_data` allow getting and setting a players meta data via the Hunger NG system. The functions both take the player name, the field to get/set and an optional `true` for getting the result as string instead of a number. It is advised not to use this functions in interoperability files to set or get hunger data. This is what `hunger_ng.alter_hunger` is for.
`settings` is a table containing the Hunger NG configuration. For example: You can check via `hunger_ng.interoperability.settings.hunger_bar.use` if the hunger bar is to be used. There are also timer information and hunger information (maximum hunger, timeout, etc.) available. Changing values here does not change the configuration. The table is solely informational.
`translator` is a preconfigured Luanti translation functionality instance. It can be used like the normal translation function but automatically uses the correct textdomain. Strings that can be translated are seen in the mods `locale` directory.

View file

@ -0,0 +1,77 @@
# Configuration
The mod allows a lot of configuration. All of the following attributes are editable on global level either via the advanced configuration within the client or by manually adding the options to the configuration file that is used for the server.
In addition to the settings in the server-specific configuration file, the values can also be stored in a world-specific configuration file located at `./worlds/worldname/_hunger_ng/hunger_ng_settings.conf`. Settings in this file overwrite the global settings and/or default values.
## Healing and starving
By default players heal to the maximum of 20 health points (10 hearts) when their hunger level is above 16 (8 breads). When the hunger is lower than 1 (no breads) players start starving. Their health will be reduced to 1 (0.5 hearts). If set players can starve to death. This is not active by default.
hunger_ng_heal_above
hunger_ng_heal_amount
hunger_ng_starve_below
hunger_ng_starve_amount
hunger_ng_starve_die
Set this values somewhere between 1 and 20 (floats are allowed for hunger values only, health values have to be integers due to technical limitations). Make sure not to use paradox values. This would result in unforeseen consequences.
## Hunger persistence and values
By default the hunger value is persistent. That means if a player leaves the game and comes back later the hunger value will not be reset but will be the same as when the player left.
The hunger value is configured to have a maximum of 20 (10 breads in default configuration, the image used for the bar can be changed, too). If a new player joins (or players that have to respawn because they died) they start with this value. Both of them are configurable.
hunger_ng_hunger_persistent
hunger_ng_hunger_maximum
hunger_ng_hunger_start_with
hunger_ng_hunger_bar_image
hunger_ng_hunger_timeout
If the value to start with is larger than the maximum value the maximum value is used.
The timeout is added to all foods that do not have a timeout set and defines how long after eating the last food the next food can be eaten. See section “Adding hunger data” for information about the per-food configuration.
## Debugging and mod configuration
Those values should be left untouched if not instructed otherwise or if you know what you are doing.
hunger_ng_debug_mode
hunger_ng_use_hunger_bar
Listen to the mod author or check `settingtypes.txt` for any further details.
## Hunger manipulation
### Costs for activities
This mod adds a basal metabolism. Players lose hunger points regardless of what they do. Digging and placing nodes also costs some hunger points. When moving around very little hunger points are subtracted regularly, too.
hunger_ng_cost_base
hunger_ng_cost_dig
hunger_ng_cost_place
hunger_ng_cost_movement
When setting any of the values to `0` the functionality will be disabled.
### Timers
There are also timers that can be set to allow even more detailed configuration of hunger manipulation
hunger_ng_timer_heal
hunger_ng_timer_starve
hunger_ng_timer_basal_metabolism
hunger_ng_timer_movement
All timers take floats as seconds value. The minimum value is 0.1 for all of the values because 0.1 seconds roughly is the time one server step takes.
### Conclusion of default values
After some balancing tests the following rules apply.
* By default players can walk for a whole accumulated ingame day before their hunger is at 0. Direction (or multiple directions at the same time) does not matter.
* Placing nodes costs 1 hunger point for 100 nodes and digging nodes costs 1 hunger point for 200 nodes.
* The basal metabolism takes roughly 10 ingame days to use up the maximum hunger value. (Which is actually pretty common in reality to survive 10 days without eating something when not doing anything else except drinking enough water.)
* Starvation (below 1 hunger point) results in 1 health point removed every 20 seconds ending up with 1 health point (starving to death is disabled by default) and when healing (above 16 hunger points, or 8 breads) 1 health point is restored every 5 seconds
One bread consists of 2 hunger points. That means that removing 1 hunger point results in 0.5 breads removed.

33
doc/README.Management.md Normal file
View file

@ -0,0 +1,33 @@
# Management
Currently there are two chat commands that allow changing ones hunger value manually or viewing the own hunger value.
## Management chat command
A custom chat command `/hunger` is added. The chat command can be used by anyone having the `manage_hunger` privilege. It provides some hunger-related features for players that are currently online.
/hunger set Foobar 10
/hunger set 7.5
/hunger change -10
/hunger change Foobar 15
/hunger get
/hunger get Foobar
The first example sets the hunger value of player “Foobar” to 10 (5 breads). The second example sets the own hunger value to 7.5 (ceiled 8, so this looks like 4 breads). The third example reduces the own hunger value by 10, the fourth example raises Foobars hunger value by 15.
The two last examples either return a list of all currently online players hunger values or the hunger value of the given player.
You can also toggle the hunger status for yourself or for a given player.
/hunger toggle
/hunger toggle Foobar
The first example toggles the own hunger status. The second example toggles the hunger status of the player “Foobar”.
## Personal information chat command
Players that have the `interact` permission can query their own hunger value as numeric information using the `/myhunger` chat command
/myhunger
This commands displays the player name and the hunger value to the player who invoked the command.

19
doc/README.md Normal file
View file

@ -0,0 +1,19 @@
The documentation is grouped into three sections. Each of the three sections contain the documentation on one of the three specific topics.
## API Documentation
Hunger NG provides an API so other mods can have interoperability functionality. The API is represented by the global table `hunger_ng`. To reliably use the API, modders need to depend or opt-depend their mod to Hunger NG (`hunger_ng`).
Read more about how to use the API in the [API documentation file](README.API.md).
## Configuration
The mod allows a lot of configuration. All of the following attributes are editable either via the advanced configuration within the client or by manually adding the options to the configuration file that is used for the server.
Check out the [configuration README](README.Configuration.md) for more details.
## Management functionality
Currently a single chat command is added that allows changing ones hunger value manually. The chat command can be used by anyone having the `server` privilege.
Read about the command and any future functionality in the [management information document](README.Management.md).

BIN
hunger_bar_hiding.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

170
init.lua Normal file
View file

@ -0,0 +1,170 @@
-- Exit if damage is not enabled and create dummy functions so mods using the
-- API do not crash the server.
if not core.is_yes(core.settings:get('enable_damage')) then
local info = 'Hunger NG is disabled because damage is disabled.'
local call = function (function_name)
core.log('warning', ('+m tried to use +f but +i'):gsub('%+%a+', {
['+m'] = core.get_current_modname(),
['+f'] = 'hunger_ng.'..function_name..'()',
['+i'] = info
}))
end
hunger_ng = {
add_hunger_data = function () call('add_hunger_data') end,
alter_hunger = function () call('alter_hunger') end,
configure_hunger = function () call('configure_hunger') end,
get_hunger_information = function () call('get_hunger_information') end,
hunger_bar_image = '',
interoperability = {
settings = {},
attributes = {},
translator = function () call('interoperability.translator') end,
get_data = function () call('interoperability.get_data') end,
set_data = function () call('interoperability.set_data') end,
}
}
core.log('info', '[hunger_ng] '..info)
return
end
-- Paths for later use
local modpath = core.get_modpath('hunger_ng')..DIR_DELIM
local worldpath = core.get_worldpath()..DIR_DELIM
local configpath = worldpath..'_hunger_ng'..DIR_DELIM..'hunger_ng_settings.conf'
-- World-specific configuration interface for use in the get function
local worldconfig = Settings(configpath)
-- Wrapper for getting configuration options
--
-- The function automatically prefixes the given setting with `hunger_ng_` and
-- returns the requested setting from one of the three sources.
--
-- 1. world-specific `./worlds/worldname/_hunger_ng/hunger_ng.conf` file
-- 2. server-specific configuration file
-- 3. the given default value
--
-- If 1. is found then it will be returned from there. If 2. is found then it
-- will be returned from there and after that it will be returned using 3.
--
-- @param setting The unprefixed setting name
-- @param default The default value if the setting is not found
-- @return string The value for the requested setting
local get = function (setting, default)
local parameter = 'hunger_ng_'..setting
local global_setting = core.settings:get(parameter)
local world_specific_setting = worldconfig:get(parameter)
return world_specific_setting or global_setting or default
end
-- Global hunger_ng table that will be used to pass around variables and use
-- them later in the game. The table is not to be used by mods. Mods should
-- only use the interoperability functionality. This table is for internal
-- use only.
hunger_ng = {
functions = {},
food_items = {
satiating = 0,
starving = 0,
healing = 0,
injuring = 0,
},
attributes = {
hunger_bar_id = 'hunger_ng:hunger_bar_id',
hunger_value = 'hunger_ng:hunger_value',
eating_timestamp = 'hunger_ng:eating_timestamp',
hunger_disabled = 'hunger_ng:hunger_disabled',
effect_heal = 'hunger_ng:effect_heal',
effect_hunger = 'hunger_ng:effect_hunger',
effect_starve = 'hunger_ng:effect_starve'
},
configuration = {
debug_mode = core.is_yes(get('debug_mode', false)),
log_prefix = '[hunger_ng] ',
translator = core.get_translator('hunger_ng')
},
settings = {
hunger_bar = {
image = get('hunger_bar_image', 'hunger_ng_builtin_bread_icon.png'),
use = core.is_yes(get('use_hunger_bar', true)),
force_builtin_image = get('force_builtin_image', false),
},
timers = {
heal = tonumber(get('timer_heal', 5)),
starve = tonumber(get('timer_starve', 10)),
basal_metabolism = tonumber(get('timer_basal_metabolism', 60)),
movement = tonumber(get('timer_movement', 0.5))
},
hunger = {
timeout = tonumber(get('hunger_timeout', 0)),
persistent = core.is_yes(get('hunger_persistent', true)),
start_with = tonumber(get('hunger_start_with', 20)),
maximum = tonumber(get('hunger_maximum', 20))
}
},
effects = {
heal = {
above = tonumber(get('heal_above', 16)),
amount = tonumber(get('heal_amount', 1)),
},
starve = {
below = tonumber(get('starve_below', 1)),
amount = tonumber(get('starve_amount', 1)),
die = core.is_yes(get('starve_die', false))
},
disabled_attribute = 'hunger_ng:hunger_disabled'
},
costs = {
base = tonumber(get('cost_base', 0.1)),
dig = tonumber(get('cost_dig', 0.005)),
place = tonumber(get('cost_place', 0.01)),
movement = tonumber(get('cost_movement', 0.008))
}
}
-- Load mod parts
dofile(modpath..'system'..DIR_DELIM..'hunger_functions.lua')
dofile(modpath..'system'..DIR_DELIM..'chat_commands.lua')
dofile(modpath..'system'..DIR_DELIM..'timers.lua')
dofile(modpath..'system'..DIR_DELIM..'register_on.lua')
dofile(modpath..'system'..DIR_DELIM..'add_hunger_data.lua')
dofile(modpath..'system'..DIR_DELIM..'interoperability.lua')
-- Log debug mode warning
if hunger_ng.configuration.debug_mode then
local log_prefix = hunger_ng.configuration.log_prefix
core.log('warning', log_prefix..'Mod loaded with debug mode enabled!')
end
-- Replace the global table used for easy variable access within the mod with
-- an API-like global table for other mods to utilize.
local api_functions = {
add_hunger_data = hunger_ng.functions.add_hunger_data,
alter_hunger = hunger_ng.functions.alter_hunger,
configure_hunger = hunger_ng.functions.configure_hunger,
set_effect = hunger_ng.set_effect,
get_hunger_information = hunger_ng.functions.get_hunger_information,
hunger_bar_image = hunger_ng.settings.hunger_bar.image,
food_items = hunger_ng.food_items,
interoperability = {
settings = hunger_ng.settings,
attributes = hunger_ng.attributes,
translator = hunger_ng.configuration.translator,
get_data = hunger_ng.functions.get_data,
set_data = hunger_ng.functions.set_data
}
}
-- Replace the internal global table with the api functions
hunger_ng = api_functions

View file

@ -0,0 +1,19 @@
# Interoperability
The interoperability files (short *i14n* files) are supposed to be used as fallback created within Hunger NG when a mod author can not or will not add support for Hunger NG in their mod for whatever reason.
Hunger NG is meant to be used as library/API by other mods. The i14n files should not be seen as the first solution if in is desirable that another mod in some way interacts with Hunger NG (hunger definition in food items, for example).
Before an i14y file will be added the following things have to be checked/done.
1. Maybe informally contact the original mod author in the mods forum thread and point them to [the Hunger NG API definition][api] and ask them to look at this and if they want to add support.
2. Formally file an issue/ticket in the mods VCS or issue-tracker or proactively create a pull request at the mods VCS adding support for Hunger NG there.
3. If you are a server owner the easiest would be creating an interoperability mod depending on both the original mod and `hunger_ng` and incorporate the Hunger NG API on your own. Its actually quite simple. The i14y files to exactly the same. See [the i14y section of the API][i14y]) for more details on API things dedicated to the i14y functionality in addition to the regular API calls.
4. Create a pull request on *Hunger NG* adding the desired support. _**Important note:** The i14y code has to be self-contained within the corresponding i14y file. No code, files, or configuration outside the i14y file will be added. Hunger NG is a library/API providing hunger functionality. Interoperability with other mods is just an additional fallback solution if original mod authors wont add support to their mods._
5. [Start a discussion in the CDB][cdb] requesting interoperability with a specific mods giving as much information as possible (name, author, link to forum and VCS, optimally the item ID to add support for) and not just the mods name and “please add” 😊
Go through the list from 1 to 5. Advance by 1 step if the previous step did not result in anything\ or is not desirable.
[api]: https://git.0x7be.net/dirk/hunger_ng/src/branch/main/doc/README.md
[i14y]: https://git.0x7be.net/dirk/hunger_ng/src/branch/main/doc/README.API.md#additional-interoperability-functions
[cdb]: https://content.luanti.org/threads/new/?pid=133

View file

@ -0,0 +1,24 @@
-- Berry Bushes
--
-- Author jordan4ibanez
-- Forums https://forum.luanti.org/viewtopic.php?t=14068
-- VCS No VCS provided
local add = hunger_ng.add_hunger_data
local berries = {
'raspberry',
'blackberry',
'gooseberry',
'strawberry',
'mixed_berry',
'blueberry'
}
for _,berry in pairs(berries) do
add('bushes:'..berry..'_pie_raw', { satiates = 2, heals = -2 })
add('bushes:'..berry..'_pie_cooked', { satiates = 5 })
add('bushes:'..berry..'_pie_slice', { satiates = 0.8 })
add('bushes:'..berry, { satiates = 0.5 })
end

View file

@ -0,0 +1,12 @@
-- default (comes with Minetest Game)
--
-- Author Various Minetest Game developers and contributors
-- Forums https://forum.luanti.org/viewtopic.php?t=9724
-- VCS https://github.com/minetest/minetest_game
local add = hunger_ng.add_hunger_data
add('default:apple', { satiates = 4, heals = 0 })
add('default:blueberries', { satiates = 0.5 })

View file

@ -0,0 +1,49 @@
-- Ethereal
--
-- Author TenPlus1
-- Forums https://forum.luanti.org/viewtopic.php?t=14638
-- VCS https://notabug.org/TenPlus1/ethereal
local add = hunger_ng.add_hunger_data
-- fishing.lua
add('ethereal:fish_raw', { satiates = 1 })
add('ethereal:fish_cooked', { satiates = 2.5 })
add('ethereal:sashimi', { satiates = 2 })
-- food.lua
add('ethereal:banana', { satiates = 1.5 })
add('ethereal:banana_bunch', { satiates = 4.5 })
add('ethereal:orange', { satiates = 2 })
add('ethereal:pine_nuts', { satiates = 0.5 })
add('ethereal:banana_bread', { satiates = 6 })
add('ethereal:coconut_slice', { satiates = 0.5 })
add('ethereal:golden_apple', { satiates = 10, heals = 10 })
add('ethereal:hearty_stew', { satiates = 7, returns = 'ethereal:bowl' })
add('ethereal:bucket_cactus', { satiates = 1, returns = 'bucket:bucket_empty' })
add('ethereal:firethorn_jelly', { satiates = 1, returns = 'vessels:glass_bottle' })
add('ethereal:lemon', { satiates = 3 })
add('ethereal:candied_lemon', { satiates = 5 })
add('ethereal:olive', { satiates = 1 })
-- leaves.lua
add('ethereal:yellowleaves', { satiates = 0.5 })
-- mushroom.lua
add('ethereal:mushroom_soup', { satiates = 2.5, returns = 'ethereal:bowl' })
-- onion.lua
add('ethereal:wild_onion_plant', { satiates = 1.5, heals = -1 })
-- plantlife.lua
add('ethereal:fern_tubers', { satiates = 0.5 })
-- sapling.lua
add('ethereal:bamboo_sprout', { satiates = 1 })
-- sealife.lua
add('ethereal:seaweed', { satiates = 0.5 })
-- strawberry.lua
add('ethereal:strawberry', { satiates = 0.5 })

View file

@ -0,0 +1,84 @@
-- Farming Redo
--
-- Author TenPlus1
-- Forums https://forum.luanti.org/viewtopic.php?t=9019
-- VCS https://notabug.org/TenPlus1/Farming
local add = hunger_ng.add_hunger_data
-- `farming:bread` is also a part of the default `farming` mod. Its texture
-- is used for the hunger bar if not specified to not doing so.
local ubi = hunger_ng.interoperability.settings.hunger_bar.force_builtin_image
if ubi == false then hunger_ng.hunger_bar_image = 'farming_bread.png' end
-- Farming bread
add('farming:bread', { satiates = 5 })
-- Edible stuff from farming Redo
add('farming:apple_pie', { satiates = 6 })
add('farming:baked_potato', { satiates = 6 })
add('farming:beans', { satiates = 1 })
add('farming:beetroot', { satiates = 0.6 })
add('farming:beetroot_soup', { satiates = 4, returns = 'farming:bowl' })
add('farming:bibimbap', { satiates = 8 })
add('farming:blueberries', { satiates = 0.5 })
add('farming:blueberry_pie', { satiates = 5 })
add('farming:bread_multigrain', { satiates = 6 })
add('farming:bread_slice', { satiates = 1 })
add('farming:burger', { satiates = 13 })
add('farming:cabbage', { satiates = 1 })
add('farming:carrot', { satiates = 2.5 })
add('farming:carrot_gold', { satiates = 8, heals = 8 })
add('farming:chili_bowl', { satiates = 7, returns = 'farming:bowl' })
add('farming:chili_pepper', { satiates = 1, heals= -1 })
add('farming:chocolate_dark', { satiates = 2 })
add('farming:cookie', { satiates = 1 })
add('farming:corn', { satiates = 2 })
add('farming:corn_cob', { satiates = 4 })
add('farming:cucumber', { satiates = 2 })
add('farming:donut', { satiates = 2 })
add('farming:donut_apple', { satiates = 3 })
add('farming:donut_chocolate', { satiates = 2 })
add('farming:garlic', { satiates = 1 })
add('farming:garlic_bread', { satiates = 2 })
add('farming:grapes', { satiates = 2 })
add('farming:jaffa_cake', { satiates = 1.5 })
add('farming:lettuce', { satiates = 2 })
add('farming:melon_slice', { satiates = 1 })
add('farming:muffin_blueberry', { satiates = 4 })
add('farming:onion', { satiates = 3, heals = -1 })
add('farming:onion_soup', { satiates = 6, returns = 'farming:bowl' })
add('farming:pea_pod', { satiates = 0.6 })
add('farming:pea_soup', { satiates = 7, returns = 'farming:bowl' })
add('farming:peas', { satiates = 0.5 })
add('farming:pepper', { satiates = 2 })
add('farming:pepper_yellow', { satiates = 3 })
add('farming:pepper_red', { satiates = 4 })
add('farming:pineapple', { satiates = 3 })
add('farming:pineapple_ring', { satiates = 0.6 })
add('farming:porridge', { satiates = 7 })
add('farming:potato', { satiates = 0.5 })
add('farming:potato_salad', { satiates = 3 })
add('farming:pumpkin_bread', { satiates = 6 })
add('farming:pumpkin_slice', { satiates = 1 })
add('farming:raspberries', { satiates = 0.5 })
add('farming:rhubarb', { satiates = 1 })
add('farming:rhubarb_pie', { satiates = 5 })
add('farming:rice_bread', { satiates = 2 })
add('farming:salad', { satiates = 8 })
add('farming:soy_beans', { satiates = 1 })
add('farming:spaghetti', { satiates = 8 })
add('farming:toast', { satiates = 1 })
add('farming:toast_sandwich', { satiates = 2.5 })
add('farming:tomato', { satiates = 3 })
add('farming:turkish_delight', { satiates = 1 })
add('farming:vanilla', { satiates = 1 })
add('farming:mint_tea', { satiates = 0.25, heals = 1, returns = 'vessels:drinking_glass' })
add('farming:coffee_cup', { satiates = 0.5, returns = 'vessels:drinking_glass' })
add('farming:smoothie_berry', { satiates = 6, returns = 'vessels:drinking_glass' })
add('farming:smoothie_raspberry', { satiates = 2.5, returns = 'vessels:drinking_glass' })
add('farming:popcorn', { satiates = 2 })

View file

@ -0,0 +1,12 @@
-- Ferns
--
-- Author Mossmanikin
-- Forums https://forum.luanti.org/viewtopic.php?id=6921
-- VCS https://github.com/Mossmanikin/ferns
local add = hunger_ng.add_hunger_data
add('ferns:fiddlehead', { satiates = 0.5, heals = -1.5 })
add('ferns:fiddlehead_roasted', { satiates = 1.2 })
add('ferns:ferntuber_roasted', { satiates = 2.5 })

View file

@ -0,0 +1,11 @@
-- flowers (comes with Minetest Game)
--
-- Author Various Minetest Game developers and contributors
-- Forums https://forum.luanti.org/viewtopic.php?t=9724
-- VCS https://github.com/minetest/minetest_game
local add = hunger_ng.add_hunger_data
add('flowers:mushroom_brown', { satiates = 1 })
add('flowers:mushroom_red', { satiates = 1, heals = -2 })

View file

@ -0,0 +1,85 @@
-- HUD bars
--
-- Author Wuzzy
-- Forums https://forum.luanti.org/viewtopic.php?t=11153
-- VCS https://repo.or.cz/w/minetest_hudbars.git
-- Localize and Prepare
local a = hunger_ng.interoperability.attributes
local s = hunger_ng.interoperability.settings
local S = hunger_ng.interoperability.translator
local get_data = hunger_ng.interoperability.get_data
local set_data = hunger_ng.interoperability.set_data
local bar_id = 'hungernghudbar'
local hudbar_image_filters = '^[noalpha^[colorize:#c17d11ff^[resize:2x16'
local hudbar_image = s.hunger_bar.image..hudbar_image_filters
-- register the hud bar
hb.register_hudbar(
bar_id,
'0xFFFFFF',
S('Satiation'),
{
bar = hudbar_image,
icon = s.hunger_bar.image
},
s.hunger.maximum,
s.hunger.maximum,
false
)
-- Remove normal hunger bar and add hudbar version of it
core.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local hud_id = tonumber(get_data(player_name, a.hunger_bar_id))
local current_hunger = get_data(player_name, a.hunger_value)
local hunger_ceiled = math.ceil(current_hunger)
if s.hunger_bar.use then
-- Since we dont have register_after_joinplayer() we need to delay
-- the removal of the default hunger bar because without delay this
-- results in a race condition with Hunger NGs register_on_joinplayer
-- callback that defines and sets the default hunger bar.
--
-- If for some reason the hud bar is not hidden try raising the delay
-- before the bar is hidden by adding hunger_ng_i14y_hudbars_delay to
-- your configuration and setting it to a value of your liking (the
-- value is giving in seconds and decimals are allowed).
local parameter_name = 'hunger_ng_i14y_hudbars_delay'
local delay = core.settings:get(parameter_name) or 0.5
if core.settings:get('hunger_ng_debug_mode') and delay ~= 0.5 then
local message = 'Using delay of +d to hide the hunger bar for +p.'
core.log('action', '[hungerng] '..message:gsub('%+%a+', {
['+d'] = delay..'s',
['+p'] = player_name
}))
end
core.after(delay, function () player:hud_remove(hud_id) end)
end
hb.init_hudbar(player, bar_id, hunger_ceiled, s.hunger.maximum, false)
end)
-- Globalstep for updating the hundbar version of the hunger bar without
-- any additional code outside the interoperability system.
local hudbars_timer = 0
core.register_globalstep(function(dtime)
hudbars_timer = hudbars_timer + dtime
if hudbars_timer >= 1 then
hudbars_timer = 0
for _,player in ipairs(core.get_connected_players()) do
if player ~= nil then
local playername = player:get_player_name()
local hunger = get_data(playername, a.hunger_value)
local ceiled = math.ceil(hunger)
hb.change_hudbar(player, bar_id, ceiled, s.hunger.maximum)
end
end
end
end)

View file

@ -0,0 +1,34 @@
-- Ice Cream
-- Hunger NG data for the Ice Cream mod by Dog_sl
-- https://forum.minetest.net/viewtopic.php?t=10321
local add = hunger_ng.add_hunger_data
-- Cones and Ingredients (Original item_eat: 1, 1, 4)
add('icecream:dough', { satiates = 0.25 })
add('icecream:notcone', { satiates = 0.25 }) -- Cone-shaped dough
add('icecream:cone', { satiates = 1.0 })
-- Fruit & Vegetable Ice Creams
add('icecream:apple', { satiates = 2.0 }) -- Original: 8
add('icecream:pineapple', { satiates = 1.0 }) -- Original: 4
add('icecream:banana', { satiates = 2.0 }) -- Original: 8
add('icecream:carrot', { satiates = 1.5 }) -- Original: 6
add('icecream:orange', { satiates = 2.0 }) -- Original: 8
add('icecream:watermelon', { satiates = 1.5 }) -- Original: 6
add('icecream:pumpkin', { satiates = 1.5 }) -- Original: 6
add('icecream:blueberries', { satiates = 1.5 }) -- Original: 6
add('icecream:strawberry', { satiates = 2.5 }) -- Original: 10
add('icecream:grapes', { satiates = 2.0 }) -- Original: 8
add('icecream:raspberry', { satiates = 2.0 }) -- Original: 8
add('icecream:garlic', { satiates = 1.0 }) -- Original: 4
-- Sweet & Special Ice Creams
add('icecream:chocolate', { satiates = 2.0 }) -- Original: 8
add('icecream:vanilla', { satiates = 2.5 }) -- Original: 10
add('icecream:chocolate_with_cookies', { satiates = 3.0 }) -- Original: 12
add('icecream:vanilla_with_cookies', { satiates = 3.0 }) -- Original: 12
add('icecream:mint', { satiates = 3.0 }) -- Original: 12

27
interoperability/mobs.lua Normal file
View file

@ -0,0 +1,27 @@
-- Mobs Redo Animals
--
-- Author TenPlus1
-- Forums https://forum.luanti.org/viewtopic.php?t=9917
-- VCS https://notabug.org/TenPlus1/mobs_animal
--
-- The mob mods register their stuff with the `mobs` prefix in the `mobs` mod.
local add = hunger_ng.add_hunger_data
add('mobs:cheese', { satiates = 2.5 })
add('mobs:chicken_cooked', { satiates = 5 })
add('mobs:chicken_egg_fried', { satiates = 2 })
add('mobs:chicken_raw', { satiates = 2, heals = -2 })
add('mobs:honey', { satiates = 2 })
add('mobs:meat', { satiates = 5.5 })
add('mobs:meat_raw', { satiates = 2.5, heals = -1 })
add('mobs:meatblock', { satiates = 5.5 * 9 })
add('mobs:meatblock_raw', { satiates = 2.5 * 9, heals = -1 * 9 })
add('mobs:mutton_cooked', { satiates = 6, heals = 1 })
add('mobs:mutton_raw', { satiates = 2, heals = -1 })
add('mobs:pork_cooked', { satiates = 4 })
add('mobs:pork_raw', { satiates = 1 })
add('mobs:rabbit_cooked', { satiates = 4.5 })
add('mobs:rabbit_raw', { satiates = 2, heals = -1 })
add('mobs:rat_cooked', { satiates = 1.5 })

View file

@ -0,0 +1,26 @@
-- More Trees!
--
-- Author VanessaE
-- Forums https://forum.luanti.org/viewtopic.php?t=4394
-- VCS https://gitlab.com/VanessaE/moretrees
local add = hunger_ng.add_hunger_data
-- Base items
add('moretrees:acorn', { satiates = 1, heals = -1 })
add('moretrees:cedar_nuts', { satiates = 1 })
add('moretrees:raw_coconut', { satiates = 1 })
add('moretrees:date', { satiates = 1 })
add('moretrees:fir_nuts', { satiates = 1 })
add('moretrees:spruce_nuts', { satiates = 1 })
-- Mixed base items
add('moretrees:acorn_muffin_batter', { satiates = 2, heals = -3 })
add('moretrees:date_nut_batter', { satiates = 2, heals = -3 })
-- Processed food
add('moretrees:acorn_muffin', { satiates = 2 })
add('moretrees:date_nut_bar', { satiates = 5, heals = 2 })
add('moretrees:date_nut_cake', { satiates = 5 })
add('moretrees:date_nut_snack', { satiates = 3, heals = 1 })

View file

@ -0,0 +1,12 @@
-- Waffles
-- Hunger NG data for the Waffles mod by apercy
-- https://content.minetest.net/packages/apercy/waffles/
local add = hunger_ng.add_hunger_data
-- Quarter of Waffle (Base value as requested)
add('waffles:waffle_quarter', { satiates = 0.5 })
-- Whole Waffle (Calculated as 4x the quarter)
add('waffles:waffle', { satiates = 2.0 })

146
locale/hunger_ng.de.po Normal file
View file

@ -0,0 +1,146 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-12-02 22:17+0100\n"
"PO-Revision-Date: \n"
"Last-Translator: Dirk <spam@0x7be.de>\n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-KeywordsList: ;S;NS:1,2;core.translate:1c,2;core."
"translate_n:1c,2,3\n"
"X-Poedit-Basepath: ..\n"
"X-Generator: Poedit 3.4.2\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: .\n"
#: interoperability/hudbars.lua:23
msgid "Satiation"
msgstr "Sättigung"
#: system/add_hunger_data.lua:47
msgid "Satiates: @1"
msgstr "Sättigt: @1"
#: system/add_hunger_data.lua:50
msgid "Deprives: @1"
msgstr "Entzieht: @1"
#: system/add_hunger_data.lua:55
msgid "Heals: @1"
msgstr "Heilt: @1"
#: system/add_hunger_data.lua:58
msgid "Injures: @1"
msgstr "Verletzt: @1"
#: system/add_hunger_data.lua:64
msgid "Returns: @1"
msgstr "Rückgabe: @1"
#: system/add_hunger_data.lua:72
msgid "Eating timeout: @1 seconds"
msgstr "Verzehrpause: @1 Sekunden"
#: system/chat_commands.lua:31 system/chat_commands.lua:73
#: system/chat_commands.lua:113
msgid "The player @1 is not online"
msgstr "Der Spieler @1 ist nicht online"
#: system/chat_commands.lua:36 system/chat_commands.lua:78
msgid "Hunger for @1 is disabled"
msgstr "Hunger ist für @1 deaktiviert"
#: system/chat_commands.lua:47
msgid "Hunger for @1 set to @2"
msgstr "Hunger für @1 auf @2 gesetzt"
#: system/chat_commands.lua:48
msgid "@1 set your hunger to @2"
msgstr "Hungerwert wurde von @1 auf @2 gesetzt"
#: system/chat_commands.lua:51
msgid "Hunger set to @1"
msgstr "Hungerwert auf @1 gesetzt"
#: system/chat_commands.lua:88
msgid "Hunger for @1 changed by @2"
msgstr "Hunger für @1 auf @2 gesetzt"
#: system/chat_commands.lua:89
msgid "@1 changed your hunger by @2"
msgstr "Hungerwert wurde von @1 um @2 verändert"
#: system/chat_commands.lua:92
msgid "Hunger changed by @1"
msgstr "Hungerwert um @1 verändert"
#: system/chat_commands.lua:126
msgid "Hunger for @1 was toggled"
msgstr "Hunger für @1 wurde umgeschaltet"
#: system/chat_commands.lua:127
msgid "@1 toggled your hunger"
msgstr "@1 hat deinen Hunger umgeschaltet"
#: system/chat_commands.lua:130
msgid "Own hunger was toggled"
msgstr "Eigener Hunger wurde umgeschaltet"
#: system/chat_commands.lua:162
msgid "Hunger is disabled"
msgstr "Hunger ist deaktiviert"
#: system/chat_commands.lua:176
msgid "No player matches your criteria"
msgstr "Keinen passenden Spieler gefunden"
#: system/chat_commands.lua:188
msgid "run `/help hunger` to show help"
msgstr "Für Hilfe `/help hunger` ausführen"
#: system/chat_commands.lua:194
msgid "Player can view and alter own and others hunger values."
msgstr ""
"Spieler kann eigene und andere Hungerwerte anzeigen und "
"verändern."
#: system/chat_commands.lua:201
msgid "Modify or get hunger values"
msgstr "Hungerwerte verändern oder anzeigen"
#: system/chat_commands.lua:240
msgid "Show own hunger value"
msgstr "Eigenen Hungerwert anzeigen"
#: system/chat_commands.lua:246
msgid "Your hunger is disabled"
msgstr "Eigener Hunger ist deaktiviert"
#: system/chat_commands.lua:248
msgid "Your hunger value is @1"
msgstr "Eigener Hungerwert ist @1"
#: system/register_on.lua:76
msgid "Hunger is disabled for you! Eating normally."
msgstr ""
"Eigene Hungerfunktionen sind deaktiviert. Essen funktioniert "
"normal."
#: system/register_on.lua:88
msgid "Youre fully satiated already!"
msgstr "Bereits vollständig gesättigt!"
#: system/register_on.lua:95
msgid "You have no inventory space to keep the leftovers."
msgstr "Kein Inventarplatz frei, um die Reste abzulegen."
#: system/register_on.lua:107
msgid "Youre eating too fast!"
msgstr "Zu schnell gegessen!"
#: system/register_on.lua:108
msgid "Wait for eating timeout to end: @1s"
msgstr "Ende des Timeouts abwarten: @1s"

146
locale/hunger_ng.es.po Normal file
View file

@ -0,0 +1,146 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-12-02 22:17+0100\n"
"PO-Revision-Date: 2024-12-02 21:55+0000\n"
"Last-Translator: Dirk <Dirk@users.noreply.translate.codeberg.org>\n"
"Language-Team: Spanish <https://translate.codeberg.org/projects/"
"linuxdirks-luanti-mods/hunger_ng/es/>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Poedit-KeywordsList: ;S;NS:1,2;core.translate:1c,2;core.translate_n:1c,2,"
"3\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: .\n"
#: interoperability/hudbars.lua:23
msgid "Satiation"
msgstr "Saciedad"
#: system/add_hunger_data.lua:47
msgid "Satiates: @1"
msgstr "Sacia: @1"
#: system/add_hunger_data.lua:50
msgid "Deprives: @1"
msgstr "Priva: @1"
#: system/add_hunger_data.lua:55
msgid "Heals: @1"
msgstr "Cura: @1"
#: system/add_hunger_data.lua:58
msgid "Injures: @1"
msgstr "Daña: @1"
#: system/add_hunger_data.lua:64
msgid "Returns: @1"
msgstr "Sobras: @1"
#: system/add_hunger_data.lua:72
msgid "Eating timeout: @1 seconds"
msgstr "Pausa para comer: @1 segundo/s"
#: system/chat_commands.lua:31 system/chat_commands.lua:73
#: system/chat_commands.lua:113
msgid "The player @1 is not online"
msgstr "El jugador @1 no está en línea"
#: system/chat_commands.lua:36 system/chat_commands.lua:78
msgid "Hunger for @1 is disabled"
msgstr "El hambre está desabilitada para @1"
#: system/chat_commands.lua:47
msgid "Hunger for @1 set to @2"
msgstr "Hambre de @1 ajustado a @2"
#: system/chat_commands.lua:48
msgid "@1 set your hunger to @2"
msgstr "@1 ha puesto tu hambre a @2"
#: system/chat_commands.lua:51
msgid "Hunger set to @1"
msgstr "Hambre ajustada a @1"
#: system/chat_commands.lua:88
msgid "Hunger for @1 changed by @2"
msgstr "Hambre de @1 cambiada a @2"
#: system/chat_commands.lua:89
msgid "@1 changed your hunger by @2"
msgstr "@1 ha cambiado tu hambre por @2"
#: system/chat_commands.lua:92
msgid "Hunger changed by @1"
msgstr "Hambre cambiada por @1"
#: system/chat_commands.lua:126
msgid "Hunger for @1 was toggled"
msgstr ""
#: system/chat_commands.lua:127
msgid "@1 toggled your hunger"
msgstr ""
#: system/chat_commands.lua:130
msgid "Own hunger was toggled"
msgstr ""
#: system/chat_commands.lua:162
msgid "Hunger is disabled"
msgstr ""
#: system/chat_commands.lua:176
msgid "No player matches your criteria"
msgstr "No hay ningún jugador que coincida con tus criterios"
#: system/chat_commands.lua:188
msgid "run `/help hunger` to show help"
msgstr "ejecuta `/help hunger` para mostrar la ayuda"
#: system/chat_commands.lua:194
msgid "Player can view and alter own and others hunger values."
msgstr ""
"El jugador puede ver y cambiar sus propios valores sobre el hambre y los de "
"los demás."
#: system/chat_commands.lua:201
msgid "Modify or get hunger values"
msgstr "Modifica u obtiene los valores de hambre"
#: system/chat_commands.lua:240
msgid "Show own hunger value"
msgstr "Muestra el valor de tu hambre"
#: system/chat_commands.lua:246
msgid "Your hunger is disabled"
msgstr "Tu hambre está desabilitada"
#: system/chat_commands.lua:248
msgid "Your hunger value is @1"
msgstr ""
#: system/register_on.lua:76
msgid "Hunger is disabled for you! Eating normally."
msgstr "¡El hambre está desabilitada para ti! Come normalmente."
#: system/register_on.lua:88
msgid "Youre fully satiated already!"
msgstr "¡Ya estás saciado!"
#: system/register_on.lua:95
msgid "You have no inventory space to keep the leftovers."
msgstr "No tienes espacio en tu inventario para llevarte las sobras."
#: system/register_on.lua:107
msgid "Youre eating too fast!"
msgstr "¡Estás comiendo demasiado rápido!"
#: system/register_on.lua:108
msgid "Wait for eating timeout to end: @1s"
msgstr "Espera a que termine el descanso: @1s"

146
locale/hunger_ng.fr.po Normal file
View file

@ -0,0 +1,146 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-12-02 22:17+0100\n"
"PO-Revision-Date: 2025-05-25 22:58+0000\n"
"Last-Translator: Hēphaïstos <hephaistos@noreply.codeberg.org>\n"
"Language-Team: French <https://translate.codeberg.org/projects/"
"linuxdirks-luanti-mods/hunger_ng/fr/>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Poedit-KeywordsList: ;S;NS:1,2;core.translate:1c,2;core.translate_n:1c,2,"
"3\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: .\n"
#: interoperability/hudbars.lua:23
msgid "Satiation"
msgstr "Satiété"
#: system/add_hunger_data.lua:47
msgid "Satiates: @1"
msgstr "Rassasie : @1"
#: system/add_hunger_data.lua:50
msgid "Deprives: @1"
msgstr "Affame : @1"
#: system/add_hunger_data.lua:55
msgid "Heals: @1"
msgstr "Guéri : @1"
#: system/add_hunger_data.lua:58
msgid "Injures: @1"
msgstr "Blesse : @1"
#: system/add_hunger_data.lua:64
msgid "Returns: @1"
msgstr "Reste : @1"
#: system/add_hunger_data.lua:72
msgid "Eating timeout: @1 seconds"
msgstr "Temps mort pour manger : @1 seconde(s)"
#: system/chat_commands.lua:31 system/chat_commands.lua:73
#: system/chat_commands.lua:113
msgid "The player @1 is not online"
msgstr "Le joueur @1 nest pas en ligne"
#: system/chat_commands.lua:36 system/chat_commands.lua:78
msgid "Hunger for @1 is disabled"
msgstr "La faim est désactivée pour @1"
#: system/chat_commands.lua:47
msgid "Hunger for @1 set to @2"
msgstr "La faim pour @1 a été fixée à @2"
#: system/chat_commands.lua:48
msgid "@1 set your hunger to @2"
msgstr "@1 a fixé votre faim à @2"
#: system/chat_commands.lua:51
msgid "Hunger set to @1"
msgstr "Faim fixée à @1"
#: system/chat_commands.lua:88
msgid "Hunger for @1 changed by @2"
msgstr "Faim de @1 modifiée par @2"
#: system/chat_commands.lua:89
msgid "@1 changed your hunger by @2"
msgstr "@1 a modifié votre faim de @2"
#: system/chat_commands.lua:92
msgid "Hunger changed by @1"
msgstr "Faim modifiée de @1"
#: system/chat_commands.lua:126
msgid "Hunger for @1 was toggled"
msgstr "L'état de faim pour @1 a changé"
#: system/chat_commands.lua:127
msgid "@1 toggled your hunger"
msgstr "@1 a changé votre état de faim"
#: system/chat_commands.lua:130
msgid "Own hunger was toggled"
msgstr "L'état de votre propre faim a changé"
#: system/chat_commands.lua:162
msgid "Hunger is disabled"
msgstr "La faim est désactivé"
#: system/chat_commands.lua:176
msgid "No player matches your criteria"
msgstr "Aucun joueur ne correspond à vos critères"
#: system/chat_commands.lua:188
msgid "run `/help hunger` to show help"
msgstr "Exécuter `/help hunger` pour afficher laide"
#: system/chat_commands.lua:194
msgid "Player can view and alter own and others hunger values."
msgstr ""
"Le joueur peut voir ou changer ses propres valeurs de faim ou celles des "
"autres."
#: system/chat_commands.lua:201
msgid "Modify or get hunger values"
msgstr "Modifier ou lire les valeurs de faim"
#: system/chat_commands.lua:240
msgid "Show own hunger value"
msgstr "Afficher l'ampleur de votre propre faim"
#: system/chat_commands.lua:246
msgid "Your hunger is disabled"
msgstr "Votre faim est désactivée"
#: system/chat_commands.lua:248
msgid "Your hunger value is @1"
msgstr "La valeur de votre faim est de @1"
#: system/register_on.lua:76
msgid "Hunger is disabled for you! Eating normally."
msgstr "La faim est désactivée pour toi! Manger normalement."
#: system/register_on.lua:88
msgid "Youre fully satiated already!"
msgstr "Tu es déjà repu!"
#: system/register_on.lua:95
msgid "You have no inventory space to keep the leftovers."
msgstr "Tu nas pas assez de place dans ton inventaire pour garder les restes."
#: system/register_on.lua:107
msgid "Youre eating too fast!"
msgstr "Tu manges trop vite!"
#: system/register_on.lua:108
msgid "Wait for eating timeout to end: @1s"
msgstr "Pour manger, attends la fin du compte à rebours : @1s"

145
locale/hunger_ng.it.po Normal file
View file

@ -0,0 +1,145 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-12-02 22:17+0100\n"
"PO-Revision-Date: 2024-12-02 21:55+0000\n"
"Last-Translator: Dirk <Dirk@users.noreply.translate.codeberg.org>\n"
"Language-Team: Italian <https://translate.codeberg.org/projects/"
"linuxdirks-luanti-mods/hunger_ng/it/>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Poedit-KeywordsList: ;S;NS:1,2;core.translate:1c,2;core.translate_n:1c,2,"
"3\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: .\n"
#: interoperability/hudbars.lua:23
msgid "Satiation"
msgstr "Sazietà"
#: system/add_hunger_data.lua:47
msgid "Satiates: @1"
msgstr "Sazia: @1"
#: system/add_hunger_data.lua:50
msgid "Deprives: @1"
msgstr "Priva: @1"
#: system/add_hunger_data.lua:55
msgid "Heals: @1"
msgstr "Guarisce: @1"
#: system/add_hunger_data.lua:58
msgid "Injures: @1"
msgstr "Ferisce: @1"
#: system/add_hunger_data.lua:64
msgid "Returns: @1"
msgstr "Restituisce: @1"
#: system/add_hunger_data.lua:72
#, fuzzy
msgid "Eating timeout: @1 seconds"
msgstr "Pausa pasto: @1"
#: system/chat_commands.lua:31 system/chat_commands.lua:73
#: system/chat_commands.lua:113
msgid "The player @1 is not online"
msgstr "Il giocatore @1 non è in linea"
#: system/chat_commands.lua:36 system/chat_commands.lua:78
msgid "Hunger for @1 is disabled"
msgstr "La fame è disabilitata per @1"
#: system/chat_commands.lua:47
msgid "Hunger for @1 set to @2"
msgstr "Fame per @1 impostata a @2"
#: system/chat_commands.lua:48
msgid "@1 set your hunger to @2"
msgstr "@1 ha impostato la tua fame a @2"
#: system/chat_commands.lua:51
msgid "Hunger set to @1"
msgstr "Fame impostata a @1"
#: system/chat_commands.lua:88
msgid "Hunger for @1 changed by @2"
msgstr "Fame di @1 cambiata di @2"
#: system/chat_commands.lua:89
msgid "@1 changed your hunger by @2"
msgstr "@1 ha cambiato la tua fame di @2"
#: system/chat_commands.lua:92
msgid "Hunger changed by @1"
msgstr "Fame cambiata di @1"
#: system/chat_commands.lua:126
msgid "Hunger for @1 was toggled"
msgstr ""
#: system/chat_commands.lua:127
msgid "@1 toggled your hunger"
msgstr ""
#: system/chat_commands.lua:130
msgid "Own hunger was toggled"
msgstr ""
#: system/chat_commands.lua:162
msgid "Hunger is disabled"
msgstr "La tua fame è disabilitata"
#: system/chat_commands.lua:176
msgid "No player matches your criteria"
msgstr "Nessun giocatore corrispondente ai tuoi criteri"
#: system/chat_commands.lua:188
msgid "run `/help hunger` to show help"
msgstr "esegui `/help hunger` per mostrare l'aiuto"
#: system/chat_commands.lua:194
msgid "Player can view and alter own and others hunger values."
msgstr "Il giocatore può vedere e cambiare i valori della fame propri e altrui."
#: system/chat_commands.lua:201
msgid "Modify or get hunger values"
msgstr "Modifica o ottieni i valori di fame"
#: system/chat_commands.lua:240
msgid "Show own hunger value"
msgstr "Mostra il proprio valore di fame"
#: system/chat_commands.lua:246
msgid "Your hunger is disabled"
msgstr "La tua fame è disabilitata"
#: system/chat_commands.lua:248
msgid "Your hunger value is @1"
msgstr ""
#: system/register_on.lua:76
msgid "Hunger is disabled for you! Eating normally."
msgstr "Per te la fame è disabilitata! Mangi normalmente."
#: system/register_on.lua:88
msgid "Youre fully satiated already!"
msgstr "Sei già completamente sazio!"
#: system/register_on.lua:95
msgid "You have no inventory space to keep the leftovers."
msgstr "Non hai spazio nell'inventario per ternere gli avanzi."
#: system/register_on.lua:107
msgid "Youre eating too fast!"
msgstr "Stai mangiando troppo velocemente!"
#: system/register_on.lua:108
msgid "Wait for eating timeout to end: @1s"
msgstr "Aspetta che finisca la pausa: @1s"

145
locale/hunger_ng.uk.po Normal file
View file

@ -0,0 +1,145 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2024-12-02 22:17+0100\n"
"PO-Revision-Date: 2025-07-17 20:08+0000\n"
"Last-Translator: FromKaniv <fromkaniv@noreply.codeberg.org>\n"
"Language-Team: Ukrainian <https://translate.codeberg.org/projects/"
"linuxdirks-luanti-mods/hunger_ng/uk/>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.12.2\n"
"X-Poedit-KeywordsList: ;S;NS:1,2;core.translate:1c,2;core.translate_n:1c,2,"
"3\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: .\n"
#: interoperability/hudbars.lua:23
msgid "Satiation"
msgstr "Насичення"
#: system/add_hunger_data.lua:47
msgid "Satiates: @1"
msgstr "Насичує: @1"
#: system/add_hunger_data.lua:50
msgid "Deprives: @1"
msgstr "Позбавляє: @1"
#: system/add_hunger_data.lua:55
msgid "Heals: @1"
msgstr "Зцілює: @1"
#: system/add_hunger_data.lua:58
msgid "Injures: @1"
msgstr "Шкодить: @1"
#: system/add_hunger_data.lua:64
msgid "Returns: @1"
msgstr "Повертає: @1"
#: system/add_hunger_data.lua:72
msgid "Eating timeout: @1 seconds"
msgstr "Тайм-аут їди: @1 сек"
#: system/chat_commands.lua:31 system/chat_commands.lua:73
#: system/chat_commands.lua:113
msgid "The player @1 is not online"
msgstr "Гравець @1 не в грі"
#: system/chat_commands.lua:36 system/chat_commands.lua:78
msgid "Hunger for @1 is disabled"
msgstr "Голод для @1 вимкнений"
#: system/chat_commands.lua:47
msgid "Hunger for @1 set to @2"
msgstr "Голод для @1 встановлено на @2"
#: system/chat_commands.lua:48
msgid "@1 set your hunger to @2"
msgstr "@1 встановив твій голод на @2"
#: system/chat_commands.lua:51
msgid "Hunger set to @1"
msgstr "Голод встановлено на @1"
#: system/chat_commands.lua:88
msgid "Hunger for @1 changed by @2"
msgstr "Голод для @1 змінено на @2"
#: system/chat_commands.lua:89
msgid "@1 changed your hunger by @2"
msgstr "@1 змінив твій голод на @2"
#: system/chat_commands.lua:92
msgid "Hunger changed by @1"
msgstr "Голод змінено на @1"
#: system/chat_commands.lua:126
msgid "Hunger for @1 was toggled"
msgstr "Голод для @1 було перемкнено"
#: system/chat_commands.lua:127
msgid "@1 toggled your hunger"
msgstr "@1 перемикнув твій голод"
#: system/chat_commands.lua:130
msgid "Own hunger was toggled"
msgstr "Власний голод було переключено"
#: system/chat_commands.lua:162
msgid "Hunger is disabled"
msgstr "Голод вимкнено"
#: system/chat_commands.lua:176
msgid "No player matches your criteria"
msgstr "Жоден гравець не відповідає твоїм критеріям"
#: system/chat_commands.lua:188
msgid "run `/help hunger` to show help"
msgstr "запусти `/help hunger` для допомоги"
#: system/chat_commands.lua:194
msgid "Player can view and alter own and others hunger values."
msgstr "Гравець може переглядати і змінювати значення голоду власного та інших."
#: system/chat_commands.lua:201
msgid "Modify or get hunger values"
msgstr "Модифікувати або отримати значення голоду"
#: system/chat_commands.lua:240
msgid "Show own hunger value"
msgstr "Показати своє значення голоду"
#: system/chat_commands.lua:246
msgid "Your hunger is disabled"
msgstr "Твій голод вимкнено"
#: system/chat_commands.lua:248
msgid "Your hunger value is @1"
msgstr "Твій голод — @1"
#: system/register_on.lua:76
msgid "Hunger is disabled for you! Eating normally."
msgstr "Голод вимкнено для тебе! Їж нормально."
#: system/register_on.lua:88
msgid "Youre fully satiated already!"
msgstr "Ти уже повністю насичений!"
#: system/register_on.lua:95
msgid "You have no inventory space to keep the leftovers."
msgstr "Ти не маєш місця в інвентарі для збереження залишків."
#: system/register_on.lua:107
msgid "Youre eating too fast!"
msgstr "Ти їж надто швидко!"
#: system/register_on.lua:108
msgid "Wait for eating timeout to end: @1s"
msgstr "Зачекай, поки тайм-аут їди закінчиться: @1 сек"

6
mod.conf Normal file
View file

@ -0,0 +1,6 @@
name = hunger_ng
title = Hunger NG
description = The mods adds a hunger bar at the position of the breath bar and hides the bar if the breath bar becomes visible so the most important bar is shown without cluttering the UI too much.
release = 32055
author = Linuxdirk

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

163
settingtypes.txt Normal file
View file

@ -0,0 +1,163 @@
[Settings]
# By default the mod uses the bread from the farming mod
# as hunger indicator. This value allows to change it to
# any valid texture.
hunger_ng_hunger_bar_image (Hunger bar image) string farming_bread.png
# Interoperability files might want to set the hunger bar
# icon to something else. With this option the image is
# left untouched from any built-in interoperability files.
hunger_ng_force_builtin_image (Force built-in hunger bar image) bool false
# Enable debugging mode. This causes A LOT of date logged
# and some date printed to the chat for every health or
# hunger change. Do not use unless you want to debug
# something within the mod and need to see all changes.
hunger_ng_debug_mode (Debug mode) bool false
# By default the hunger bar is shown and hidden based on
# some circumstances. Some mods might have issues when
# the hunger bar is shown.
#
# When set to `false` the default hunger bar wont be
# registered and all functions altering the hunger bar
# are disabled.
#
# Hunger itself and mod interoperability functionality
# work like before.
hunger_ng_use_hunger_bar (Use the hunger bar) bool true
[Effects]
[* Heal]
# When the hunger lvel is above this value health will
# slowly be restored to maximum health. When the value
# is set to higher than maximum hunger the functionality
# is deisabled.
hunger_ng_heal_above (Heal when hunger his above this value) float 16
# When healing the player because the hunger level is
# over the healing limit health will be restored using
# this value for every restore cycle.
hunger_ng_heal_amount (Heal this amount of health points) int 1
[* Starve]
# When the hunger is below this value the player starves
# and loses health points. Set this value to -1 if you
# want to disable this functionality.
hunger_ng_starve_below (Starve when hunger is below this value) float 1
# When starving the player because the hunger level is
# below the starvation limit health will be reduced using
# this value for every starving cycle.
hunger_ng_starve_amount (Starve by this amount of health points) int 1
# If the player starves the player will starve to death
# if this value is true. Otherwise starvation will end
# at 1 health point (0.5 hearts).
hunger_ng_starve_die (Starve to death when hunger is below limit) bool false
[Hunger]
# This defines tha maximum hunger value. Higher values
# result in more breads to be shown. By default it uses
# 20, which is the same value as for health.
hunger_ng_hunger_maximum (Maximum hunger value) float 20
# When enabled the hunger value wont be reset on new
# logins but stay as it was when logging out.
hunger_ng_hunger_persistent (Hunger stays the same between logins) bool true
# When players log in for the first time or if players
# die and respawn this value will be set for the hunger
# value. This does not need to match maximum health but
# cannot be above maximum health.
hunger_ng_hunger_start_with (Start with this hunger value) float 20
# Foods may have an eating timeout where the same food
# cant be eaten within a defined timeout in seconds.
# When there is no timeout configured the default
# timeout will be used.
hunger_ng_hunger_timeout (Default eating timeout) int 0
[Costs]
# The “basal metabolism” is exactly that. Players lose
# this amount of hunger on every basal metabolism cycle
# regardless if they do anything or being idle.
#
# When this value and the basal metabolism timer are
# left at their default values, players roughly loose
# 2 hunger points during 1 ingame day. This allows
# surviving around 10 days without food when no other
# hunger costs are substracted.
hunger_ng_cost_base (Basal metabolism) float 0.1
# Digging a node (regardless of manual or with tools)
# costs this amount of hunger to perform.
#
# If this value is left at its default, digging costs
# 1 hunger point for 200 digged nodes.
hunger_ng_cost_dig (Digging a node) float 0.005
# Placing a node costs this amount of hunger to perform.
#
# If this value is left at its default, players lose
# 1 hunger point for 100 placed nodes
hunger_ng_cost_place (Placing a node) float 0.01
# When moving around players lose this amount hof hunger
# regardless if the do anything else. When not pressing
# any movement buttons for the movement this does not
# apply and nothing will be remnoved.
#
# When this value and the movement timer are left at
# their default values, players can roughtly move for
# one ingame day until the hunger value is at 0 when
# nbot doing anything else than walking.
hunger_ng_cost_movement (Moving around) float 0.008
[Timers]
# Heal a player that can heal (above healing limit and
# not awash) every N seconds. Fractions are allowed.
# 0.1 seconds is the minimum value.
hunger_ng_timer_heal (Automatic healing) float 2
# Make a player starve when the hunger value is below
#the starvation limit every N seconds. Fractions are
# allowed and 0.1 seconds is the minimum value
hunger_ng_timer_starve (Starvation) float 2
# Set the basal metabolism to be active every N
# seconds. Fractions are allowed and 0.1 seconds is
# the minimum value for this.
#
# When this value and the basal metabolism cost are
# left at their default values, players roughly lose
# 2 hunger points during 1 ingame day. This allows
# surviving around 10 days without food when no other
# hunger costs are substracted.
hunger_ng_timer_base (Basal metabolism) float 60
# Apoply movement-based hunger every N seconds.
# Fractions are allowed and 0.1 seconds is the
# minimum value for this. The higher the value is
# the longer can players move without hunger being
# applied.
#
# When set too high players can circumvent
# movement-based hunger by not pressing a movement
# key for too long.
#
# When this value and the movement cost are left at
# their default values, players can roughtly move for
# one ingame day until the hunger value is at 0 when
# nbot doing anything else than walking.
hunger_ng_timer_movement (Movement) float 0.5

13
sounds/README.md Normal file
View file

@ -0,0 +1,13 @@
# Sounds are licensed differently
## hunger_ng_eat.1.ogg
* Source: https://freesound.org/people/Thedust82/sounds/215639/
* License: Creative Commons 0
* Autor: Thedust82
* Title: Eating a Cracker in the Kitchen
## hunger_ng_eat.2.ogg
* Source: https://freesound.org/people/rkeato/sounds/118050/
* License: Creative Commons By
* Autor: rkeato
* Title: Chomping/Chewing/Crunching on some cheerios, closed AND open mouthed

BIN
sounds/hunger_ng_eat.1.ogg Normal file

Binary file not shown.

BIN
sounds/hunger_ng_eat.2.ogg Normal file

Binary file not shown.

View file

@ -0,0 +1,79 @@
-- Localize Hunger NG
local a = hunger_ng.attributes
local c = hunger_ng.configuration
local e = hunger_ng.effects
local f = hunger_ng.functions
local s = hunger_ng.settings
local S = hunger_ng.configuration.translator
-- Localize Luanti
local registered_items = core.registered_items
local override_item = core.override_item
-- Add custom _hunger_ng attribute to items
--
-- Checks if the item already has the attribute. If not, then the provided
-- values are set.
--
-- The data table has to be the following.
--
-- {
-- heals = n,
-- satiates = n,
-- returns = 'id'
-- }
--
-- Where n is a number (can be negative to damage the player or make the
-- player hungry) or a fraction of a number. If `returns` is set to an ID of
-- a registered item this item will be returned when the food is eaten.
--
-- @param id The ID of the item to be modified.
-- @param data The data table as described
hunger_ng.functions.add_hunger_data = function (id, data)
if registered_items[id] == nil then return end
if registered_items[id]._hunger_ng ~= nil then return end
if registered_items[id].on_use == nil then return end
local item_data = registered_items[id]
local info = ''
local satiates = data.satiates or 0
local heals = data.heals or 0
local returns = data.returns or false
local timeout = data.timeout or s.hunger.timeout
if satiates > 0 then
info = info..'\n'..S('Satiates: @1', satiates)
hunger_ng.food_items.satiating = hunger_ng.food_items.satiating + 1
elseif satiates < 0 then
info = info..'\n'..S('Deprives: @1', math.abs(satiates))
hunger_ng.food_items.starving = hunger_ng.food_items.starving + 1
end
if heals > 0 then
info = info..'\n'..S('Heals: @1', data.heals)
hunger_ng.food_items.healing = hunger_ng.food_items.healing + 1
elseif heals < 0 then
info = info..'\n'..S('Injures: @1', math.abs(heals))
hunger_ng.food_items.injuring = hunger_ng.food_items.injuring + 1
end
if returns and registered_items[returns] then
local return_name = registered_items[returns].description
info = info..'\n'..S('Returns: @1', return_name)
end
if data.returns and not registered_items[returns] then
data.returns = nil
end
if timeout > 0 then
info = info..'\n'..S('Eating timeout: @1 seconds', timeout)
end
override_item(id, {
description = item_data.description..info,
_hunger_ng = data
})
end

252
system/chat_commands.lua Normal file
View file

@ -0,0 +1,252 @@
-- Localize Hunger NG
local a = hunger_ng.attributes
local c = hunger_ng.configuration
local e = hunger_ng.effects
local f = hunger_ng.functions
local s = hunger_ng.settings
local S = hunger_ng.configuration.translator
-- Localize Luanto
local chat_send = core.chat_send_player
local log = core.log
local player_exists = core.player_exists
local get_player_by_name = core.get_player_by_name
local get_connected_players = core.get_connected_players
-- Set hunger to given value
--
-- Sets the hunger of the given player to the given value. If the player name
-- is omitted own hunger is set.
--
-- @param name The name of the target player
-- @param value The hunger value to set to
-- @param caller The player who invoked the command
-- @return mixed `void` if player exists, otherwise `nil`
local set_hunger = function (name, value, caller)
local message = ''
if not get_player_by_name(name) then
chat_send(caller, S('The player @1 is not online', name))
return
end
if f.hunger_disabled(name) then
chat_send(caller, S('Hunger for @1 is disabled', name))
return
end
if value > s.hunger.maximum then value = s.hunger.maximum end
if value < 0 then value = 0 end
f.alter_hunger(name, -s.hunger.maximum, 'chat set 0')
f.alter_hunger(name, value, 'chat set target')
if name ~= caller then
chat_send(caller, S('Hunger for @1 set to @2', name, value))
chat_send(name, S('@1 set your hunger to @2', caller, value))
message = caller..' sets hunger for '..name..' to '..value
else
chat_send(caller, S('Hunger set to @1', value))
message = caller..' sets own hunger to '..value
end
log('action', '[hunger_ng] '..message)
end
-- Change the hunger value
--
-- Changes the hunger value of the given player by the given value. Use
-- negative values to substract hunger. If the player name is omitted the own
-- hunger gets changed.
--
-- @param name The name of the target player
-- @param value The hunger value to change by
-- @param caller The player who invoked the command
-- @return mixed `void` if player exists, otherwise `nil`
local change_hunger = function (name, value, caller)
local message = ''
if not get_player_by_name(name) then
chat_send(caller, S('The player @1 is not online', name))
return
end
if f.hunger_disabled(name) then
chat_send(caller, S('Hunger for @1 is disabled', name))
return
end
if value > s.hunger.maximum then value = s.hunger.maximum end
if value < -s.hunger.maximum then value = -s.hunger.maximum end
f.alter_hunger(name, value, 'chat change')
if name ~= caller then
chat_send(caller, S('Hunger for @1 changed by @2', name, value))
chat_send(name, S('@1 changed your hunger by @2', caller, value))
message = caller..'changes hunger for '..name..' by '..value
else
chat_send(caller, S('Hunger changed by @1', value))
message = caller..' changes own hunger by '..value
end
log('action', '[hunger_ng] '..message)
end
-- Toggle hunger being enabled
--
-- Toggles the hunger for the given player from enabled to disabled.
--
-- @param name The name of the target player
-- @param caller The player who invoked the command
-- @return mixed `void` if player exists, otherwise `nil`
local toggle_hunger = function (name, value, caller)
local message = ''
local action = ''
local name = name == '' and caller or name
if not get_player_by_name(name) then
chat_send(caller, S('The player @1 is not online', name))
return
end
if f.hunger_disabled(name) then
hunger_ng.configure_hunger(name, 'enable')
action = 'enabled'
else
hunger_ng.configure_hunger(name, 'disable')
action = 'disabled'
end
if name ~= caller then
chat_send(caller, S('Hunger for @1 was toggled', name))
chat_send(name, S('@1 toggled your hunger', caller))
message = caller..' '..action..' hunger for '..name
else
chat_send(caller, S('Own hunger was toggled'))
message = caller..' '..action..' own hunger'
end
log('action', '[hunger_ng] '..message)
end
-- Get the hunger value
--
-- When called without name parameter it gets the hunger values from all
-- currently connected players. If a name is given the hunger value for that
-- player is returned if the player is online
--
-- @param name The name of the target player
-- @param caller The player who invoked the command
-- @return void
local get_hunger = function(name, caller)
local message = ''
if name == '' then name = get_connected_players()
else name = { get_player_by_name(name) } end
for _,player in pairs(name) do
if player:is_player() then
local player_name = player:get_player_name()
local player_hunger = f.get_data(player_name, a.hunger_value)
local hunger_disabled = f.hunger_disabled(player_name)
if not hunger_disabled then
chat_send(caller, player_name..': '..player_hunger)
else
chat_send(caller, player_name..': '..S('Hunger is disabled'))
end
if player_name == caller then
message = caller..' gets own hunger value'
else
message = caller..' gets hunger value for '..player_name
end
log('action', '[hunger_ng] '..message)
end
end
if #name == 0 then
chat_send(caller, S('No player matches your criteria'))
end
end
-- Show the help message
--
-- Shows the help message to the caller
--
-- @param caller The player who invoked the command
-- @return void
local show_help = function (caller)
chat_send(caller, S('run `/help hunger` to show help'))
end
-- Register privilege for hunger control
core.register_privilege('manage_hunger', {
description = S('Player can view and alter own and others hunger values.')
})
-- Administrative chat command definition
core.register_chatcommand('hunger', {
params = '<set/change/get/toggle> <name> <value>',
description = S('Modify or get hunger values'),
privs = { manage_hunger = true },
func = function (caller, parameters)
local pt= {}
for p in parameters:gmatch("%S+") do table.insert(pt, p) end
local action = pt[1] or ''
local name = pt[2] or ''
local value = pt[3] or ''
-- Name parameter missing
if not player_exists(name) and tonumber(name) and value == '' then
value = name
name = caller
end
-- Convert value to number or print error message when trying to set
-- a value but no proper value was given
if tonumber(value) then
value = tonumber(value)
else
if action ~= 'get' and action ~= 'toggle' then
show_help(caller)
return
end
end
-- Execute the corresponding function for the defined action
if action == 'set' then set_hunger(name, value, caller)
elseif action == 'change' then change_hunger(name, value, caller)
elseif action == 'get' then get_hunger(name, caller)
elseif action == 'toggle' then toggle_hunger(name, value, caller)
else show_help(caller) end
end
})
-- Personal information chat command
core.register_chatcommand('myhunger', {
params = 'name',
description = S('Show own hunger value'),
privs = { interact = true },
func = function (caller)
local player_hunger = f.get_data(caller, a.hunger_value)
local hunger_disabled = f.hunger_disabled(caller)
if hunger_disabled then
chat_send(caller, S('Your hunger is disabled'))
else
chat_send(caller, S('Your hunger value is @1', player_hunger))
end
end
})

283
system/hunger_functions.lua Normal file
View file

@ -0,0 +1,283 @@
-- Localize Hunger NG
local a = hunger_ng.attributes
local c = hunger_ng.configuration
local e = hunger_ng.effects
local f = hunger_ng.functions
local s = hunger_ng.settings
local S = hunger_ng.configuration.translator
-- Localize Luanti
local core_log = core.log
local get_player_by_name = core.get_player_by_name
local get_current_modname = core.get_current_modname
-- Gets and returns the given player-related data
--
-- To gain more flexibility this function is used wherever something from the
-- player has to be loaded either as custom player attribute or as planned
-- player meta data.
--
-- @param playername The name of the player to get the information from
-- @param field The field that has to be get.
-- @param as_string Optionally return the value of the field as string
-- @return bool|string|number
local get_data = function (playername, field, as_string)
local player = get_player_by_name(playername)
if not player then return false end
local player_meta = player:get_meta()
if as_string then
return tostring(player_meta:get(field) or 'invalid')
else
return tonumber(player_meta:get(field) or nil)
end
end
-- Sets a player-related attribute
--
-- To gain more flexibility on the player-related functions this function can
-- be used wherever a player-related attribute has to be set.
--
-- @param playername The name of the player to set the attribute to
-- @param field The field to set
-- @param value The value to set the field to
-- @return void
local set_data = function (playername, field, value)
local player = get_player_by_name(playername)
if not player then return false end
local player_meta = player:get_meta()
player_meta:set_string(field, value)
end
-- Print health and hunger changes
--
-- This function prints all health and hunger changes that are triggered by
-- this mod. The following information will be shown for every change.
--
-- t: Ingame time when the change was applied
-- p: player name affected by the change
-- w: Information on what was changes (hunger/health)
-- n: The new value as defined by the definition
-- d: definition (calculation) of the change (old + change = new)
--
-- @param playername Name of the player (p)
-- @param what Description on what was changed (w, hunger/health)
-- @param old The old value
-- @param new The new value
-- @param change The change amount
-- @param reason The given reason for the change
-- @return void
local debug_log = function (playername, what, old, new, change, reason)
if not c.debug_mode then return end
local timestamp = 24 * 60 * core.get_timeofday()
local h = tostring((math.floor(timestamp/60) % 60))
local m = tostring((math.floor(timestamp) % 60))
local text = ('t: +t, p: +p, w: +w, n: +n, d: +o + +c, r: +r'):gsub('+.', {
['+t'] = string.rep('0', 2-#h)..h..':'..string.rep('0', 2-#m)..m,
['+p'] = playername,
['+w'] = what,
['+o'] = old,
['+n'] = new,
['+c'] = change,
['+r'] = reason or 'n/a'
})
core_log('action', c.log_prefix..text)
end
-- Returns if hunger is disabled for the given player
--
-- When the player is no `interact` permission or has the `hunger_disabled`
-- parameter set then this function returns boolean true. Otherwise boolean
-- false will be returned.
--
-- @param playername The name of the player to check
-- @return bool
local hunger_disabled = function (playername)
local interact = core.check_player_privs(playername, { interact=true })
local disabled = get_data(playername, a.hunger_disabled)
if core.is_yes(disabled) or not interact then return true end
return false
end
-- Configures hunger effects for the player
--
-- The function can enable or disable hunger for a player. It is meant to be
-- used by other mods to disable or enable hunger effects for a specific
-- player. For example a magic item that prevents players from getting hungry.
--
-- The parameter `action` can be either `disable`, `enable`. The actions are
-- very self-explainatory.
--
-- @param playername The name of the player whose hunger is to be configured
-- @param action The action that will be taken as described
local configure_hunger = function (playername, action)
if not action then return end
if action == 'enable' then
set_data(playername, a.hunger_disabled, 0)
elseif action == 'disable' then
set_data(playername, a.hunger_disabled, 1)
end
end
-- Get the current hunger information
--
-- Gets (Returns) the current hunger information for the given player. See API
-- documentation for a detailled overview of the returned table.
--
-- @param playername The name of the player whose hunger value is to be get
-- @return table The table as described
hunger_ng.functions.get_hunger_information = function (playername)
local player = get_player_by_name(playername)
if not player then return { invalid = true, player_name = playername } end
local last_eaten = get_data(playername, a.eating_timestamp) or 0
local current_hunger = get_data(playername, a.hunger_value)
local player_properties = player:get_properties()
local e_heal = get_data(playername, a.effect_heal, true) == 'enabled'
local e_hunger = get_data(playername, a.effect_hunger, true) == 'enabled'
local e_starve = get_data(playername, a.effect_starve, true) == 'enabled'
return {
player_name = playername,
hunger = {
floored = math.floor(current_hunger),
ceiled = math.ceil(current_hunger),
disabled = hunger_disabled(playername),
exact = current_hunger,
enabled = e_heal
},
maximum = {
hunger = s.hunger.maximum,
health = player_properties.hp_max,
breath = player_properties.breath_max
},
effects = {
starving = {
enabled = e_starve,
status = current_hunger < e.starve.below
},
healing = {
enabled = e_heal,
status = current_hunger > e.heal.above
},
current_breath = player:get_breath(),
},
timestamps = {
last_eaten = tonumber(last_eaten),
request = tonumber(os.time())
}
}
end
-- Alter health by given value
--
-- @param playername The name of a player whose health value should be altered
-- @param change The health change (can be negative to damage the player)
hunger_ng.functions.alter_health = function (playername, change, reason)
local player = get_player_by_name(playername)
local hp_max = player:get_properties().hp_max
if player == nil then return end
if hunger_disabled(playername) then return end
local current_health = player:get_hp()
local new_health = current_health + change
if new_health > hp_max then new_health = hp_max end
if new_health < 0 then new_health = 0 end
player:set_hp(new_health, { hunger = reason })
debug_log(playername, 'health', current_health, new_health, change, reason)
end
-- Alter hunger by the given value
--
-- @param playername The name of a player whose hunger value should be altered
-- @param change The hunger change (can be negative to make player hungry)
hunger_ng.functions.alter_hunger = function (playername, change, reason)
local player = get_player_by_name(playername)
if player == nil then return end
if hunger_disabled(playername) then return end
local current_hunger = get_data(playername, a.hunger_value)
local new_hunger = current_hunger + change
local bar_id = get_data(playername, a.hunger_bar_id)
if new_hunger > s.hunger.maximum then new_hunger = s.hunger.maximum end
if new_hunger < 0 then new_hunger = 0 end
set_data(playername, a.hunger_value, new_hunger)
if s.hunger_bar.use then
player:hud_change(bar_id, 'number', math.ceil(new_hunger))
end
debug_log(playername, 'hunger', current_hunger, new_hunger, change, reason)
end
-- Set hunger effect metadata
--
-- The hunger effect meta data can be set by mods to temporary disable hunger
-- effects for the given player. Everything works normal but hunger effects
-- like hunger itself, starving and healing are not performed even if the
-- player is in a state where this would happen.
--
-- The effect is not persistent. When a player rejoins the setting is actively
-- removed during join time of that player. Mods need to actively track the
-- status if they want the setting persist between joins.
--
-- @see hunger_ng.alter_hunger
-- @see system/timers.lua
--
-- @param playername Name of the player to set the effect for
-- @param effect The effect name as described
-- @param setting Either `enabled` or `disabled`
-- @return void
hunger_ng.set_effect = function (playername, effect, setting)
local attribute = a['effect_'..effect] or false
local allowed_values = { enabled = true, disabled = true }
-- Warn in server log when a mod tries to configure an unknown effect
if attribute == false then
core_log('warning', ('+t +m tried to set +v for +p'):gsub('+.', {
['+t'] = '[hunger_ng]',
['+m'] = get_current_modname(),
['+v'] = 'unknown effect '..effect,
['+p'] = playername
}))
return
end
-- Set the attribute according to what the mod wants and log that setting
if allowed_values[setting] == true then
set_data(playername, attribute, setting)
core_log('verbose', ('+t +m sets +a to +v for +p'):gsub('+.', {
['+t'] = '[hunger_ng]',
['+m'] = get_current_modname(),
['+a'] = attribute,
['+v'] = setting,
['+p'] = playername
}))
end
end
-- Globalize the set and get function for player data for use in other files
hunger_ng.functions.get_data = get_data
hunger_ng.functions.set_data = set_data
hunger_ng.functions.hunger_disabled = hunger_disabled
hunger_ng.functions.configure_hunger = configure_hunger

View file

@ -0,0 +1,37 @@
-- Localize Hunger NG
local a = hunger_ng.attributes
local c = hunger_ng.configuration
local e = hunger_ng.effects
local f = hunger_ng.functions
local s = hunger_ng.settings
local S = hunger_ng.configuration.translator
-- Localize Luanti
local get_modpath = core.get_modpath
local get_dir_list = core.get_dir_list
local log = core.log
-- Load needed data
local mod_path = core.get_modpath('hunger_ng')
local i14y_path = mod_path..DIR_DELIM..'interoperability'..DIR_DELIM
-- Load interoperability file when the corresponding mod was loaded
core.register_on_mods_loaded(function()
for _,i14y_file in pairs(get_dir_list(i14y_path)) do
local modname = i14y_file:gsub('%..*', '')
if get_modpath(modname) and i14y_file ~= 'README.md' then
dofile(i14y_path..i14y_file)
log('info', c.log_prefix..'Loaded built-in '..modname..' support')
end
end
if hunger_ng.food_items.satiating == 0 then
local message = {
'There are NO satiating food items registered!',
'Hunger is disabled!',
'Enable at least one of the supported mods.'
}
log('warning', '[hunger_ng] '..table.concat(message, ' '))
end
end)

173
system/register_on.lua Normal file
View file

@ -0,0 +1,173 @@
-- vim: set sw=2:
-- Set Vims shiftwidth to 2 instead of 4 because the functions in this file
-- are deeply nested and there are some long lines. 2 instead of 4 gives a tiny
-- bit more space for each indentation level.
-- Localize Hunger NG
local a = hunger_ng.attributes
local c = hunger_ng.configuration
local e = hunger_ng.effects
local f = hunger_ng.functions
local s = hunger_ng.settings
local S = hunger_ng.configuration.translator
local costs = hunger_ng.costs
-- Localize Luanti
local chat_send = core.chat_send_player
local core_log = core.log
-- When a player digs or places a node the corresponding hunger alteration
-- will be applied
core.register_on_dignode(function(p, on, digger)
if digger then
f.alter_hunger(digger:get_player_name(), -costs.dig, 'digging')
end
end)
core.register_on_placenode(function(p, nn, placer, on, is, pt)
if placer then
f.alter_hunger(placer:get_player_name(), -costs.place, 'placing')
end
end)
-- If a player dies and respawns the hunger value will be properly deleted and
-- after respawn it will be set again. This avoids the player healing even if
-- the player died.
core.register_on_dieplayer(function(player)
f.alter_hunger(player:get_player_name(), -s.hunger.maximum, 'death')
return true
end)
core.register_on_respawnplayer(function(player)
f.alter_hunger(player:get_player_name(), s.hunger.start_with, 'respawn')
end)
-- Custom eating function
--
-- When the player eats an item it is checked if the item has the custom
-- _hunger_ng attribute set. If no, the eating wont be intercepted by the
-- function and the item will be eat regularly.
--
-- If the item has the attribute set then it will be processed and the heal
-- and hunger values will be applied according to the items settings.
--
-- If the item has a timeout and the timeout is still active the user gets an
-- information about this mentioning the timeout and how long the user has to
-- wait before being able to eat again.
core.register_on_item_eat(function(hpc, rwi, itemstack, user, pt)
local definition = itemstack:get_definition()
local hunger_def = definition._hunger_ng
-- Make sure to run the Hunger NG actions only if the item has hunger
-- information registered.
if user:is_player() ~= true or hunger_def == nil then return end
local player_name = user:get_player_name()
local current_hunger = f.get_data(player_name, a.hunger_value)
local hunger_disabled = f.get_data(player_name, a.hunger_disabled)
local item_sound = definition.sound or {}
local eating_sound = item_sound.eat or 'hunger_ng_eat'
-- If hunger is disabled by configuration the reular eating functionality
-- is restored with chat message on eating.
if core.is_yes(hunger_disabled) then
chat_send(player_name, S('Hunger is disabled for you! Eating normally.'))
return
end
-- If a mod disabled the hunger effect the regular eating functionality
-- is restored without chat message.
if f.get_data(player_name,a.effect_hunger,true) == 'disabled' then return end
local heals = hunger_def.heals or 0
local satiates = hunger_def.satiates or 0
if current_hunger == s.hunger.maximum and heals <= 0 and satiates >= 0 then
chat_send(player_name, S('Youre fully satiated already!'))
return itemstack
end
if hunger_def.returns then
local inventory = user:get_inventory()
if not inventory:room_for_item('main', hunger_def.returns..' 1') then
local message = S('You have no inventory space to keep the leftovers.')
chat_send(player_name, message)
return itemstack
end
end
local timeout = hunger_def.timeout or s.hunger.timeout
local current_timestamp = os.time()
local player_timestamp = f.get_data(player_name, a.eating_timestamp)
if current_timestamp < player_timestamp + timeout then
local wait = player_timestamp + timeout - current_timestamp
local message = S('Youre eating too fast!')
local info = S('Wait for eating timeout to end: @1s', wait)
chat_send(player_name, message..' '..info)
return itemstack
else
f.set_data(player_name, a.eating_timestamp, current_timestamp)
end
core.sound_play(eating_sound, { to_player = player_name })
f.alter_hunger(player_name, satiates, 'eating')
f.alter_health(player_name, heals, 'eating')
itemstack:take_item(1)
if hunger_def.returns then
local inventory = user:get_inventory()
inventory:add_item('main', hunger_def.returns..' 1')
end
return itemstack
end)
-- Initial hunger and hunger bar configuration
--
-- When a player joins it is checked if the custom attribute for hunger is set.
-- If hunger persistence is used then the value gets read and applied to the
-- hunger bar.
--
-- If the value is not set or hunger persistence is not used then the hunger
-- value to start with will be used. This can be different from the maximum
-- hunger value.
core.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local unset = not f.get_data(player_name, a.hunger_value)
local reset = f.get_data(player_name, a.hunger_value) and not s.hunger.persistent
-- Only set if the value is not set or if hunger is configured not
-- being persistent.
if unset or reset then
if c.debug_mode then
local message = 'Set initial hunger values for '..player_name
core_log('action', c.log_prefix..message)
end
f.set_data(player_name, a.hunger_value, s.hunger.start_with)
f.set_data(player_name, a.eating_timestamp, 0)
f.set_data(player_name, a.hunger_disabled, 0)
end
-- Always reset (enable) hunger effect settings
f.set_data(player_name, a.effect_hunger, 'enabled')
f.set_data(player_name, a.effect_heal, 'enabled')
f.set_data(player_name, a.effect_starve, 'enabled')
-- Only set hunger bar ID if hunger bar is configured to be used
if s.hunger_bar.use then
f.set_data(player_name, a.hunger_bar_id, player:hud_add({
type = 'statbar',
position = { x=0.5, y=1 },
text = hunger_ng.hunger_bar_image,
direction = 0,
number = f.get_data(player_name, a.hunger_value),
size = { x=24, y=24 },
offset = {x=25,y=-(48+24+16)},
}))
end
end)

130
system/timers.lua Normal file
View file

@ -0,0 +1,130 @@
-- vim: set sw=2:
-- Set Vims shiftwidth to 2 instead of 4 because the functions in this file
-- are deeply nested and there are some long lines. 2 instead of 4 gives a tiny
-- bit more space for each indentation level.
local alter_health = hunger_ng.functions.alter_health
local alter_hunger = hunger_ng.functions.alter_hunger
local base_interval = hunger_ng.settings.timers.basal_metabolism
local costs_base = hunger_ng.costs.base
local costs_movement = hunger_ng.costs.movement
local effect_heal = hunger_ng.attributes.effect_heal
local effect_hunger = hunger_ng.attributes.effect_hunger
local effect_starve = hunger_ng.attributes.effect_starve
local get_data = hunger_ng.functions.get_data
local heal_above = hunger_ng.effects.heal.above
local heal_amount = hunger_ng.effects.heal.amount
local heal_interval = hunger_ng.settings.timers.heal
local hunger_attribute = hunger_ng.attributes.hunger_value
local hunger_bar_id = hunger_ng.attributes.hunger_bar_id
local hunger_disabled_attribute = hunger_ng.attributes.hunger_disabled
local move_interval = hunger_ng.settings.timers.movement
local starve_amount = hunger_ng.effects.starve.amount
local starve_below = hunger_ng.effects.starve.below
local starve_die = hunger_ng.effects.starve.die
local starve_interval = hunger_ng.settings.timers.starve
local use_hunger_bar = hunger_ng.settings.hunger_bar.use
-- Localize Luanti
is_yes = core.is_yes
get_connected_players = core.get_connected_players
-- Initiate globalstep timers
local base_timer = 0
local heal_timer = 0
local move_timer = 0
local starve_timer = 0
core.register_globalstep(function(dtime)
-- Do not run if there are no satiating food items registered
if hunger_ng.food_items.satiating == 0 then return end
-- Raise timer values if needed
if costs_base ~= 0 then base_timer = base_timer + dtime end
if heal_amount ~= 0 then heal_timer = heal_timer + dtime end
if costs_movement ~= 0 then move_timer = move_timer + dtime end
if starve_amount ~= 0 then starve_timer = starve_timer + dtime end
-- Reset timers if needed
if costs_base ~= 0 and base_timer >= base_interval then base_timer = 0 end
if heal_amount ~= 0 and heal_timer >= heal_interval then heal_timer = 0 end
if costs_movement ~= 0 and move_timer >= move_interval then move_timer=0 end
if starve_amount~=0 and starve_timer>=starve_interval then starve_timer=0 end
-- Iterate over all players
--
-- If the value and the timer for the corresponding attribute are not zero
-- (value) and zero (timer) then the alteration of that attribute is executed.
for _,player in ipairs(get_connected_players()) do
if player:is_player() then
local playername = player:get_player_name()
local hp_max = player:get_properties().hp_max
local e_heal = get_data(playername, effect_heal, true) == 'enabled'
local e_hunger = get_data(playername, effect_hunger, true) == 'enabled'
local e_starve = get_data(playername, effect_starve, true) == 'enabled'
-- Basal metabolism costs
if costs_base ~= 0 and base_timer == 0 and e_hunger then
alter_hunger(player:get_player_name(), -costs_base, 'base')
end
-- Heal player if possible and needed
if heal_amount ~= 0 and heal_timer == 0 then
local hunger = get_data(playername, hunger_attribute)
local health = player:get_hp()
local awash = player:get_breath() < player:get_properties().breath_max
local can_heal = hunger >= heal_above and not awash
local needs_health = health < hp_max
if can_heal and needs_health and e_heal then
alter_health(playername, heal_amount, 'healing')
end
end
-- Alter hunger based on movement costs
if costs_movement ~= 0 and move_timer == 0 then
local move = player:get_player_control()
local moving = move.up or move.down or move.left or move.right
if moving and e_hunger then
alter_hunger(playername, -costs_movement, 'movement')
end
end
-- Starve player if starvation requirements are fulfilled
if starve_amount ~= 0 and starve_timer == 0 then
local hunger = get_data(playername, hunger_attribute)
local health = player:get_hp()
local starves = hunger < starve_below
local playername = player:get_player_name()
if starves and e_starve then
if health == 1 and not starve_die then return end
alter_health(playername, -starve_amount, 'starving')
end
end
end -- is player
end -- players iteration
end)
-- Show/hide hunger bar on player breath status or functionality status
if use_hunger_bar then
core.register_globalstep(function(dtime)
for _,player in ipairs(get_connected_players()) do
if player:is_player() then
local player_name = player:get_player_name()
local bar_id = get_data(player_name, hunger_bar_id)
local awash = player:get_breath() < player:get_properties().breath_max
local disabled = get_data(player_name, hunger_disabled_attribute)
local no_food = hunger_ng.food_items.satiating == 0
if awash or is_yes(disabled) or no_food then
player:hud_change(bar_id, 'text', '')
else
player:hud_change(bar_id, 'text', hunger_ng.hunger_bar_image)
end
end
end
end)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B