From d6cb0dc6100d8f47e027c27f072603deb2249f05 Mon Sep 17 00:00:00 2001 From: Milan2018 Date: Sun, 10 Nov 2024 14:47:55 +0100 Subject: [PATCH] Update --- hbhunger/.mailmap | 2 + hbhunger/README.md | 96 ++ hbhunger/hunger.lua | 168 +++ hbhunger/init.lua | 188 +++ hbhunger/locale/hbhunger.de.tr | 9 + hbhunger/locale/hbhunger.fr.tr | 9 + hbhunger/locale/hbhunger.it.tr | 9 + hbhunger/locale/hbhunger.ms.tr | 9 + hbhunger/locale/hbhunger.pt.tr | 9 + hbhunger/locale/hbhunger.ru.tr | 9 + hbhunger/locale/template.txt | 9 + hbhunger/mod.conf | 7 + hbhunger/register_foods.lua | 331 ++++++ hbhunger/screenshot.png | Bin 0 -> 8498 bytes hbhunger/sounds/hbhunger_eat_generic.ogg | Bin 0 -> 34341 bytes hbhunger/textures/hbhunger_bar.png | Bin 0 -> 80 bytes .../textures/hbhunger_bar_health_poison.png | Bin 0 -> 151 bytes hbhunger/textures/hbhunger_bgicon.png | Bin 0 -> 417 bytes hbhunger/textures/hbhunger_icon.png | Bin 0 -> 522 bytes .../textures/hbhunger_icon_health_poison.png | Bin 0 -> 526 bytes hbsprint/.github/workflows/build.yml | 11 + hbsprint/.luacheckrc | 19 + hbsprint/LICENSE | 504 ++++++++ hbsprint/README.md | 39 + hbsprint/init.lua | 261 ++++ hbsprint/mod.conf | 6 + hbsprint/settingtypes.txt | 42 + hbsprint/textures/sprint_stamina_bar.png | Bin 0 -> 71 bytes hbsprint/textures/sprint_stamina_bgicon.png | Bin 0 -> 171 bytes hbsprint/textures/sprint_stamina_icon.png | Bin 0 -> 245 bytes hudbars/.mailmap | 2 + hudbars/API.md | 210 ++++ hudbars/README.md | 63 + hudbars/default_settings.lua | 49 + hudbars/init.lua | 583 +++++++++ hudbars/locale/hudbars.de.tr | 4 + hudbars/locale/hudbars.es.tr | 4 + hudbars/locale/hudbars.fr.tr | 4 + hudbars/locale/hudbars.it.tr | 6 + hudbars/locale/hudbars.ms.tr | 4 + hudbars/locale/hudbars.nl.tr | 6 + hudbars/locale/hudbars.pt.tr | 6 + hudbars/locale/hudbars.ru.tr | 4 + hudbars/locale/hudbars.tr.tr | 4 + hudbars/locale/template.txt | 6 + hudbars/mod.conf | 5 + hudbars/screenshot.png | Bin 0 -> 9556 bytes hudbars/settingtypes.txt | 122 ++ hudbars/textures/hudbars_bar_background.png | Bin 0 -> 140 bytes hudbars/textures/hudbars_bar_breath.png | Bin 0 -> 80 bytes hudbars/textures/hudbars_bar_health.png | Bin 0 -> 80 bytes hudbars/textures/hudbars_bgicon_breath.png | Bin 0 -> 811 bytes hudbars/textures/hudbars_bgicon_health.png | Bin 0 -> 302 bytes hudbars/textures/hudbars_icon_breath.png | Bin 0 -> 818 bytes hudbars/textures/hudbars_icon_health.png | Bin 0 -> 321 bytes thirsty/LICENSE | 505 ++++++++ thirsty/README.md | 349 ++++++ thirsty/components.lua | 324 +++++ thirsty/components_external_nodes_items.lua | 49 + thirsty/functions.lua | 583 +++++++++ thirsty/hud.lua | 75 ++ thirsty/init.lua | 168 +++ thirsty/interop_a_functions.lua | 56 + thirsty/interop_dungeon_loot.lua | 20 + thirsty/interop_ethereal.lua | 20 + thirsty/interop_farming_redo.lua | 71 ++ thirsty/interop_mobs_animal.lua | 19 + thirsty/mod.conf | 4 + thirsty/settingtypes.txt | 60 + ...hirsty_breviceps_drink-drinking-liquid.ogg | Bin 0 -> 14701 bytes thirsty/textures/src/bowl.svg | 132 +++ thirsty/textures/src/bronze_canteen.svg | 139 +++ thirsty/textures/src/cup_0.svg | 151 +++ thirsty/textures/src/cup_100.svg | 167 +++ thirsty/textures/src/cup_50.svg | 167 +++ thirsty/textures/src/drinkfount_bottom.svg | 100 ++ thirsty/textures/src/drinkfount_side.svg | 115 ++ thirsty/textures/src/drinkfount_top.svg | 114 ++ thirsty/textures/src/extractor.svg | 140 +++ thirsty/textures/src/injector.svg | 141 +++ thirsty/textures/src/steel_canteen.svg | 139 +++ .../src/thirsty_amulet_hydration_cc0.xcf | Bin 0 -> 9525 bytes .../src/thirsty_amulet_moisture_cc0.xcf | Bin 0 -> 13984 bytes .../src/thirsty_amulet_of _thirst _cc0.xcf | Bin 0 -> 14205 bytes thirsty/textures/src/thirsty_bowl_cc0.xcf | Bin 0 -> 6399 bytes .../src/thirsty_bronze_canteen_cc0.xcf | Bin 0 -> 9079 bytes thirsty/textures/src/thirsty_cup_100_cc0.xcf | Bin 0 -> 9014 bytes .../src/thirsty_steel_canteen_cc0.xcf | Bin 0 -> 8439 bytes thirsty/textures/src/waterextender_side.svg | 244 ++++ thirsty/textures/src/waterextender_top.svg | 309 +++++ thirsty/textures/src/waterfountain_side.svg | 268 +++++ thirsty/textures/src/waterfountain_top.svg | 1051 +++++++++++++++++ .../textures/thirsty_amulet_hydration_cc0.png | Bin 0 -> 11038 bytes .../textures/thirsty_amulet_moisture_cc0.png | Bin 0 -> 10343 bytes .../textures/thirsty_amulet_of_thirst_cc0.png | Bin 0 -> 10122 bytes .../thirsty_amulet_of_thirst_greater_cc0.png | Bin 0 -> 10734 bytes .../thirsty_amulet_of_thirst_lesser_cc0.png | Bin 0 -> 11008 bytes thirsty/textures/thirsty_bowl_cc0.png | Bin 0 -> 7066 bytes .../textures/thirsty_bronze_canteen_cc0.png | Bin 0 -> 8561 bytes .../textures/thirsty_drinkfount_bottom.png | Bin 0 -> 184 bytes thirsty/textures/thirsty_drinkfount_side.png | Bin 0 -> 182 bytes thirsty/textures/thirsty_drinkfount_top.png | Bin 0 -> 236 bytes thirsty/textures/thirsty_drop_100_16_cc0.png | Bin 0 -> 695 bytes thirsty/textures/thirsty_drop_100_24_cc0.png | Bin 0 -> 8654 bytes thirsty/textures/thirsty_hudbars_bar.png | Bin 0 -> 5503 bytes .../textures/thirsty_steel_canteen_cc0.png | Bin 0 -> 8223 bytes .../textures/thirsty_waterextender_side.png | Bin 0 -> 176 bytes .../textures/thirsty_waterextender_top.png | Bin 0 -> 326 bytes .../textures/thirsty_waterfountain_side.png | Bin 0 -> 280 bytes .../textures/thirsty_waterfountain_top.png | Bin 0 -> 750 bytes .../vessels_glass_bottle_full_cc_by_sa_3.png | Bin 0 -> 6608 bytes 111 files changed, 8499 insertions(+) create mode 100644 hbhunger/.mailmap create mode 100644 hbhunger/README.md create mode 100644 hbhunger/hunger.lua create mode 100644 hbhunger/init.lua create mode 100644 hbhunger/locale/hbhunger.de.tr create mode 100644 hbhunger/locale/hbhunger.fr.tr create mode 100644 hbhunger/locale/hbhunger.it.tr create mode 100644 hbhunger/locale/hbhunger.ms.tr create mode 100644 hbhunger/locale/hbhunger.pt.tr create mode 100644 hbhunger/locale/hbhunger.ru.tr create mode 100644 hbhunger/locale/template.txt create mode 100644 hbhunger/mod.conf create mode 100644 hbhunger/register_foods.lua create mode 100644 hbhunger/screenshot.png create mode 100644 hbhunger/sounds/hbhunger_eat_generic.ogg create mode 100644 hbhunger/textures/hbhunger_bar.png create mode 100644 hbhunger/textures/hbhunger_bar_health_poison.png create mode 100644 hbhunger/textures/hbhunger_bgicon.png create mode 100644 hbhunger/textures/hbhunger_icon.png create mode 100644 hbhunger/textures/hbhunger_icon_health_poison.png create mode 100644 hbsprint/.github/workflows/build.yml create mode 100644 hbsprint/.luacheckrc create mode 100644 hbsprint/LICENSE create mode 100644 hbsprint/README.md create mode 100644 hbsprint/init.lua create mode 100644 hbsprint/mod.conf create mode 100644 hbsprint/settingtypes.txt create mode 100644 hbsprint/textures/sprint_stamina_bar.png create mode 100644 hbsprint/textures/sprint_stamina_bgicon.png create mode 100644 hbsprint/textures/sprint_stamina_icon.png create mode 100644 hudbars/.mailmap create mode 100644 hudbars/API.md create mode 100644 hudbars/README.md create mode 100644 hudbars/default_settings.lua create mode 100644 hudbars/init.lua create mode 100644 hudbars/locale/hudbars.de.tr create mode 100644 hudbars/locale/hudbars.es.tr create mode 100644 hudbars/locale/hudbars.fr.tr create mode 100644 hudbars/locale/hudbars.it.tr create mode 100644 hudbars/locale/hudbars.ms.tr create mode 100644 hudbars/locale/hudbars.nl.tr create mode 100644 hudbars/locale/hudbars.pt.tr create mode 100644 hudbars/locale/hudbars.ru.tr create mode 100644 hudbars/locale/hudbars.tr.tr create mode 100644 hudbars/locale/template.txt create mode 100644 hudbars/mod.conf create mode 100644 hudbars/screenshot.png create mode 100644 hudbars/settingtypes.txt create mode 100644 hudbars/textures/hudbars_bar_background.png create mode 100644 hudbars/textures/hudbars_bar_breath.png create mode 100644 hudbars/textures/hudbars_bar_health.png create mode 100644 hudbars/textures/hudbars_bgicon_breath.png create mode 100644 hudbars/textures/hudbars_bgicon_health.png create mode 100644 hudbars/textures/hudbars_icon_breath.png create mode 100644 hudbars/textures/hudbars_icon_health.png create mode 100644 thirsty/LICENSE create mode 100644 thirsty/README.md create mode 100644 thirsty/components.lua create mode 100644 thirsty/components_external_nodes_items.lua create mode 100644 thirsty/functions.lua create mode 100644 thirsty/hud.lua create mode 100644 thirsty/init.lua create mode 100644 thirsty/interop_a_functions.lua create mode 100644 thirsty/interop_dungeon_loot.lua create mode 100644 thirsty/interop_ethereal.lua create mode 100644 thirsty/interop_farming_redo.lua create mode 100644 thirsty/interop_mobs_animal.lua create mode 100644 thirsty/mod.conf create mode 100644 thirsty/settingtypes.txt create mode 100644 thirsty/sounds/thirsty_breviceps_drink-drinking-liquid.ogg create mode 100644 thirsty/textures/src/bowl.svg create mode 100644 thirsty/textures/src/bronze_canteen.svg create mode 100644 thirsty/textures/src/cup_0.svg create mode 100644 thirsty/textures/src/cup_100.svg create mode 100644 thirsty/textures/src/cup_50.svg create mode 100644 thirsty/textures/src/drinkfount_bottom.svg create mode 100644 thirsty/textures/src/drinkfount_side.svg create mode 100644 thirsty/textures/src/drinkfount_top.svg create mode 100644 thirsty/textures/src/extractor.svg create mode 100644 thirsty/textures/src/injector.svg create mode 100644 thirsty/textures/src/steel_canteen.svg create mode 100644 thirsty/textures/src/thirsty_amulet_hydration_cc0.xcf create mode 100644 thirsty/textures/src/thirsty_amulet_moisture_cc0.xcf create mode 100644 thirsty/textures/src/thirsty_amulet_of _thirst _cc0.xcf create mode 100644 thirsty/textures/src/thirsty_bowl_cc0.xcf create mode 100644 thirsty/textures/src/thirsty_bronze_canteen_cc0.xcf create mode 100644 thirsty/textures/src/thirsty_cup_100_cc0.xcf create mode 100644 thirsty/textures/src/thirsty_steel_canteen_cc0.xcf create mode 100644 thirsty/textures/src/waterextender_side.svg create mode 100644 thirsty/textures/src/waterextender_top.svg create mode 100644 thirsty/textures/src/waterfountain_side.svg create mode 100644 thirsty/textures/src/waterfountain_top.svg create mode 100644 thirsty/textures/thirsty_amulet_hydration_cc0.png create mode 100644 thirsty/textures/thirsty_amulet_moisture_cc0.png create mode 100644 thirsty/textures/thirsty_amulet_of_thirst_cc0.png create mode 100644 thirsty/textures/thirsty_amulet_of_thirst_greater_cc0.png create mode 100644 thirsty/textures/thirsty_amulet_of_thirst_lesser_cc0.png create mode 100644 thirsty/textures/thirsty_bowl_cc0.png create mode 100644 thirsty/textures/thirsty_bronze_canteen_cc0.png create mode 100644 thirsty/textures/thirsty_drinkfount_bottom.png create mode 100644 thirsty/textures/thirsty_drinkfount_side.png create mode 100644 thirsty/textures/thirsty_drinkfount_top.png create mode 100644 thirsty/textures/thirsty_drop_100_16_cc0.png create mode 100644 thirsty/textures/thirsty_drop_100_24_cc0.png create mode 100644 thirsty/textures/thirsty_hudbars_bar.png create mode 100644 thirsty/textures/thirsty_steel_canteen_cc0.png create mode 100644 thirsty/textures/thirsty_waterextender_side.png create mode 100644 thirsty/textures/thirsty_waterextender_top.png create mode 100644 thirsty/textures/thirsty_waterfountain_side.png create mode 100644 thirsty/textures/thirsty_waterfountain_top.png create mode 100644 thirsty/textures/vessels_glass_bottle_full_cc_by_sa_3.png diff --git a/hbhunger/.mailmap b/hbhunger/.mailmap new file mode 100644 index 0000000..3d78b58 --- /dev/null +++ b/hbhunger/.mailmap @@ -0,0 +1,2 @@ +Wuzzy +Wuzzy diff --git a/hbhunger/README.md b/hbhunger/README.md new file mode 100644 index 0000000..cd29caa --- /dev/null +++ b/hbhunger/README.md @@ -0,0 +1,96 @@ +# Hunger with HUD Bar [`hbhunger`] + +* Version: 1.1.6 + +## Using the mod + +This mod adds a mechanic for hunger. +This mod depends on the HUD bars mod [`hudbars`], version 1.4.1 or any later version +starting with “1.” or “2.”. + +## About hunger +This mod adds a hunger mechanic to the game. Players get a new attribute called “satiation”: + +* A new player starts with 20 satiation points out of 30 +* Actions like digging, placing and walking cause exhaustion, which lower the satiation +* Every 800 seconds you lose 1 satiation point without doing anything +* At 1 or 0 satiation you will suffer damage and die in case you don't eat something +* If your satiation is 16 or higher, you will slowly regenerate health points +* Eating food will increase your satiation (Duh!) + +Important: Eating food will not directly increase your health anymore, as long as the food +item is supported by this mod (see below). + +Careful! Some foods may be poisoned. If you eat a poisoned item, you may still get a satiation +boost, but for a brief period you lose health points because of food poisoning. However, +food poisoning can never kill you. + +## Statbar mode +If you use the statbar mode of the HUD Bars mod, these things are important to know: +As with all mods using HUD Bars, the bread statbar symbols represent the rough percentage +out of 30 satiation points, in steps of 5%, so the symbols give you an estimate of your +satiation. This is different from the hunger mod by BlockMen. + +You gain health at 5.5 symbols or more, as 5.5 symbols correspond to 16 satiation points. +You *may* lose health at exactly 0.5 symbols, as 0.5 symbols correspond to 1-2 satiation points. + +## Supported food +All mods which add food through standard measures (`minetest.item_eat`) are already +supported automatically. Poisoned food needs special support. + +### Known supported food mods +* Apple and Blueberries from Minetest Game [`default`] +* Red and brown mushroom from Minetest Game [`flowers`] +* Bread from Minetest Game [`farming`] +* [`animalmaterials`] (Mob Framework (`mobf` modpack)) +* Bushes [`bushes`] +* [`bushes_classic`] +* Creatures [`creatures`] +* [`dwarves`] (beer and such) +* Docfarming [`docfarming`] +* Ethereal / Ethereal NG [`ethereal`] +* Farming Redo [`farming`] by TenPlus1 +* Farming plus [`farming_plus`] +* Ferns [`ferns`] +* Fishing [`fishing`] +* [`fruit`] +* Glooptest [`glooptest`] +* JKMod ([`jkanimals`], [`jkfarming`], [`jkwine`]) +* [`kpgmobs`] +* [`mobfcooking`] +* [`mooretrees`] +* [`mtfoods`] +* [`mushroom`] +* [`mush45`] +* Seaplants [`sea`] +* Simple mobs [`mobs`] +* Pizza [`pizza`] +* Not So Simple Mobs [`nssm`] + +### Supported mods without optional dependency (mods provide their own support) + +* Food ([`food`], [`food_basic`]) +* Sweet Foods [`food_sweet`] + +### Example + +* Eating an apple (from Minetest Game) increases your satiation by 2; + +## Licensing +This mod is free software. + +### Source code + +* License: [LGPL v2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) +* Author: by Wuzzy (2015-2016) +* Forked from the “Better HUD (and hunger)” mod by BlockMen (2013-2015), + most code comes from this mod. + +### Textures + +* `hbhunger_icon.png`—PilzAdam ([MIT License](https://opensource.org/licenses/MIT)), modified by BlockMen +* `hbhunger_bgicon.png`—PilzAdam (MIT License), modified by BlockMen +* `hbhunger_bar.png`—Wuzzy (MIT License) +* `hbhunger_icon_health_poison.png`—celeron55 ([CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)), modified by BlockMen, modified again by Wuzzy +* Everything else: MIT License, by BlockMen and Wuzzy + diff --git a/hbhunger/hunger.lua b/hbhunger/hunger.lua new file mode 100644 index 0000000..b05c8e2 --- /dev/null +++ b/hbhunger/hunger.lua @@ -0,0 +1,168 @@ +-- Keep these for backwards compatibility +function hbhunger.save_hunger(player) + hbhunger.set_hunger_raw(player) +end +function hbhunger.load_hunger(player) + hbhunger.get_hunger_raw(player) +end + +-- HACK: We register our on_item_eat handler after the other mods have loaded +-- so their on_item_eat handlers run first. This is because Minetest refuses +-- to run ANY further on_item_eat handler once one of the callback functions +-- has returned an itemstack. (as of Minetest 5.8.0) +-- FIXME: Remove the register_on_mods_loaded as soon Minetest handles +-- on_item_eat events in a less weird manner. +minetest.register_on_mods_loaded(function() + minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing) + -- Our own item eat handler + return hbhunger.eat(hp_change, replace_with_item, ItemStack(itemstack), user, pointed_thing) + end) +end) + +-- food functions +local food = hbhunger.food + +function hbhunger.register_food(name, hunger_change, replace_with_item, poisen, heal, sound) + food[name] = {} + food[name].saturation = hunger_change -- hunger points added + food[name].replace = replace_with_item -- what item is given back after eating + food[name].poisen = poisen -- time its poisening + food[name].healing = heal -- amount of HP + food[name].sound = sound -- special sound that is played when eating +end + +function hbhunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing) + local item = itemstack:get_name() + local def = food[item] + if not def then + def = {} + if type(hp_change) ~= "number" then + hp_change = 1 + minetest.log("error", "Wrong on_use() definition for item '" .. item .. "'") + end + def.saturation = hp_change * 1.3 + def.replace = replace_with_item + end + local func = hbhunger.item_eat(def.saturation, def.replace, def.poisen, def.healing, def.sound) + return func(itemstack, user, pointed_thing) +end + +-- Poison player +local function poisenp(tick, time, time_left, player) + -- First check if player is still there + if not player:is_player() then + return + end + time_left = time_left + tick + if time_left < time then + minetest.after(tick, poisenp, tick, time, time_left, player) + else + hbhunger.poisonings[player:get_player_name()] = hbhunger.poisonings[player:get_player_name()] - 1 + if hbhunger.poisonings[player:get_player_name()] <= 0 then + -- Reset HUD bar color + hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_health.png", nil, "hudbars_bar_health.png") + end + end + if player:get_hp()-1 > 0 then + player:set_hp(player:get_hp()-1) + end + +end + +function hbhunger.item_eat(hunger_change, replace_with_item, poisen, heal, sound) + return function(itemstack, user, pointed_thing) + if itemstack:take_item() ~= nil and user ~= nil then + local name = user:get_player_name() + local h = tonumber(hbhunger.hunger[name]) + local hp = user:get_hp() + if h == nil or hp == nil then + return + end + if user:is_player() then + local object, object_pos + -- Check if user is a "fake player" (unofficial imitation of a the player data structure) + if type(user) == "userdata" then + object = user + else + object_pos = user:get_pos() + end + minetest.sound_play( + {name = sound or "hbhunger_eat_generic", + gain = 1}, + {object=object, + pos=object_pos, + max_hear_distance = 16, + pitch = 1 + math.random(-10, 10)*0.005,}, + true + ) + end + + -- Saturation + if h < hbhunger.SAT_MAX and hunger_change then + h = h + hunger_change + if h > hbhunger.SAT_MAX then h = hbhunger.SAT_MAX end + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(user) + end + -- Healing + local hp_max = user:get_properties().hp_max or minetest.PLAYER_MAX_HP_DEFAULT or 20 + if hp < hp_max and heal then + hp = hp + heal + if hp > hp_max then hp = hp_max end + user:set_hp(hp) + end + -- Poison + if poisen then + -- Set poison bar + hb.change_hudbar(user, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hbhunger_bar_health_poison.png") + hbhunger.poisonings[name] = hbhunger.poisonings[name] + 1 + poisenp(1, poisen, 0, user) + end + + if itemstack:get_count() == 0 then + itemstack:add_item(replace_with_item) + else + local inv = user:get_inventory() + if inv:room_for_item("main", replace_with_item) then + inv:add_item("main", replace_with_item) + else + minetest.add_item(user:get_pos(), replace_with_item) + end + end + end + return itemstack + end +end + +-- player-action based hunger changes +function hbhunger.handle_node_actions(pos, oldnode, player, ext) + -- is_fake_player comes from the pipeworks, we are not interested in those + if not player or not player:is_player() or player.is_fake_player == true then + return + end + local name = player:get_player_name() + local exhaus = hbhunger.exhaustion[name] + if exhaus == nil then return end + local new = hbhunger.EXHAUST_PLACE + -- placenode event + if not ext then + new = hbhunger.EXHAUST_DIG + end + -- assume its send by main timer when movement detected + if not pos and not oldnode then + new = hbhunger.EXHAUST_MOVE + end + exhaus = exhaus + new + if exhaus > hbhunger.EXHAUST_LVL then + exhaus = 0 + local h = tonumber(hbhunger.hunger[name]) + h = h - 1 + if h < 0 then h = 0 end + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(player) + end + hbhunger.exhaustion[name] = exhaus +end + +minetest.register_on_placenode(hbhunger.handle_node_actions) +minetest.register_on_dignode(hbhunger.handle_node_actions) diff --git a/hbhunger/init.lua b/hbhunger/init.lua new file mode 100644 index 0000000..8d19e16 --- /dev/null +++ b/hbhunger/init.lua @@ -0,0 +1,188 @@ +local S = minetest.get_translator("hbhunger") + +if minetest.settings:get_bool("enable_damage") then + +hbhunger = {} +hbhunger.food = {} + +-- HUD statbar values +hbhunger.hunger = {} +hbhunger.hunger_out = {} + +-- Count number of poisonings a player has at once +hbhunger.poisonings = {} + +-- HUD item ids +local hunger_hud = {} + +hbhunger.HUD_TICK = 0.1 + +--Some hunger settings +hbhunger.exhaustion = {} -- Exhaustion is experimental! + +hbhunger.HUNGER_TICK = 800 -- time in seconds after that 1 hunger point is taken +hbhunger.EXHAUST_DIG = 3 -- exhaustion increased this value after digged node +hbhunger.EXHAUST_PLACE = 1 -- exhaustion increased this value after placed +hbhunger.EXHAUST_MOVE = 0.3 -- exhaustion increased this value if player movement detected +hbhunger.EXHAUST_LVL = 160 -- at what exhaustion player satiation gets lowerd +hbhunger.SAT_MAX = 30 -- maximum satiation points +hbhunger.SAT_INIT = 20 -- initial satiation points +hbhunger.SAT_HEAL = 15 -- required satiation points to start healing + + +--load custom settings +local set = io.open(minetest.get_modpath("hbhunger").."/hbhunger.conf", "r") +if set then + dofile(minetest.get_modpath("hbhunger").."/hbhunger.conf") + set:close() +end + +local function custom_hud(player) + hb.init_hudbar(player, "satiation", hbhunger.get_hunger_raw(player)) +end + +dofile(minetest.get_modpath("hbhunger").."/hunger.lua") +dofile(minetest.get_modpath("hbhunger").."/register_foods.lua") + +-- register satiation hudbar +hb.register_hudbar("satiation", 0xFFFFFF, S("Satiation"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, hbhunger.SAT_INIT, hbhunger.SAT_MAX, false, nil, { format_value = "%.1f", format_max_value = "%d" }) + +-- update hud elemtens if value has changed +local function update_hud(player) + local name = player:get_player_name() + --hunger + local h_out = tonumber(hbhunger.hunger_out[name]) + local h = tonumber(hbhunger.hunger[name]) + if h_out ~= h then + hbhunger.hunger_out[name] = h + hb.change_hudbar(player, "satiation", h) + end +end + +hbhunger.get_hunger_raw = function(player) + local inv = player:get_inventory() + if not inv then return nil end + local hgp = inv:get_stack("hunger", 1):get_count() + if hgp == 0 then + hgp = 21 + inv:set_stack("hunger", 1, ItemStack({name=":", count=hgp})) + else + hgp = hgp + end + return hgp-1 +end + +hbhunger.set_hunger_raw = function(player) + local inv = player:get_inventory() + local name = player:get_player_name() + local value = hbhunger.hunger[name] + if not inv or not value then return nil end + if value > hbhunger.SAT_MAX then value = hbhunger.SAT_MAX end + if value < 0 then value = 0 end + + inv:set_stack("hunger", 1, ItemStack({name=":", count=value+1})) + + return true +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + local inv = player:get_inventory() + inv:set_size("hunger",1) + hbhunger.hunger[name] = hbhunger.get_hunger_raw(player) + hbhunger.hunger_out[name] = hbhunger.hunger[name] + hbhunger.exhaustion[name] = 0 + hbhunger.poisonings[name] = 0 + custom_hud(player) + hbhunger.set_hunger_raw(player) +end) + +minetest.register_on_respawnplayer(function(player) + -- reset hunger (and save) + local name = player:get_player_name() + hbhunger.hunger[name] = hbhunger.SAT_INIT + hbhunger.set_hunger_raw(player) + hbhunger.exhaustion[name] = 0 +end) + +local main_timer = 0 +local timer = 0 +local timer2 = 0 +minetest.register_globalstep(function(dtime) + main_timer = main_timer + dtime + timer = timer + dtime + timer2 = timer2 + dtime + if main_timer > hbhunger.HUD_TICK or timer > 4 or timer2 > hbhunger.HUNGER_TICK then + if main_timer > hbhunger.HUD_TICK then main_timer = 0 end + for _,player in ipairs(minetest.get_connected_players()) do + local name = player:get_player_name() + + local h = tonumber(hbhunger.hunger[name]) + local hp = player:get_hp() + if timer > 4 then + -- heal player by 1 hp if not dead and satiation is > hbhunger.SAT_HEAL + if h > hbhunger.SAT_HEAL and hp > 0 and player:get_breath() > 0 then + player:set_hp(hp+1) + -- or damage player by 1 hp if satiation is < 2 + elseif h <= 1 then + if hp-1 >= 0 then player:set_hp(hp-1) end + end + end + -- lower satiation by 1 point after xx seconds + if timer2 > hbhunger.HUNGER_TICK then + if h > 0 then + h = h-1 + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(player) + end + end + + -- update all hud elements + update_hud(player) + + local controls = player:get_player_control() + -- Determine if the player is walking + if controls.up or controls.down or controls.left or controls.right then + hbhunger.handle_node_actions(nil, nil, player) + end + end + end + if timer > 4 then timer = 0 end + if timer2 > hbhunger.HUNGER_TICK then timer2 = 0 end +end) + +minetest.register_chatcommand("satiation", { + privs = {["server"]=true}, + params = S("[] "), + description = S("Set satiation of player or yourself"), + func = function(name, param) + if minetest.settings:get_bool("enable_damage") == false then + return false, S("Not possible, damage is disabled.") + end + local targetname, satiation = string.match(param, "(%S+) (%S+)") + if not targetname then + satiation = param + end + satiation = tonumber(satiation) + if not satiation then + return false, S("Invalid satiation!") + end + if not targetname then + targetname = name + end + local target = minetest.get_player_by_name(targetname) + if target == nil then + return false, S("Player @1 does not exist.", targetname) + end + if satiation > hbhunger.SAT_MAX then + satiation = hbhunger.SAT_MAX + elseif satiation < 0 then + satiation = 0 + end + hbhunger.hunger[targetname] = satiation + hbhunger.set_hunger_raw(target) + return true + end, +}) + +end diff --git a/hbhunger/locale/hbhunger.de.tr b/hbhunger/locale/hbhunger.de.tr new file mode 100644 index 0000000..1e480e6 --- /dev/null +++ b/hbhunger/locale/hbhunger.de.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar=Hunger mit HUD-Leiste +Adds a simple hunger meachanic with satiation, food poisoning and different healing.=Fügt ein einfaches Hungersystem hinzu, mit Sättigung, Lebensmittelvergiftung und anderer Heilung. +Satiation=Sättigung +[] =[] +Set satiation of player or yourself=Sättigung von Spieler oder Ihnen selbst setzen +Not possible, damage is disabled.=Nicht möglich, Schaden ist deaktiviert. +Invalid satiation!=Ungültige Sättigung! +Player @1 does not exist.=Spieler @1 existiert nicht. diff --git a/hbhunger/locale/hbhunger.fr.tr b/hbhunger/locale/hbhunger.fr.tr new file mode 100644 index 0000000..8466da3 --- /dev/null +++ b/hbhunger/locale/hbhunger.fr.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation=Satiété +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/locale/hbhunger.it.tr b/hbhunger/locale/hbhunger.it.tr new file mode 100644 index 0000000..15c6563 --- /dev/null +++ b/hbhunger/locale/hbhunger.it.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation=Sazietà +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/locale/hbhunger.ms.tr b/hbhunger/locale/hbhunger.ms.tr new file mode 100644 index 0000000..66ba1bf --- /dev/null +++ b/hbhunger/locale/hbhunger.ms.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation=Kekenyangan +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/locale/hbhunger.pt.tr b/hbhunger/locale/hbhunger.pt.tr new file mode 100644 index 0000000..2a7c129 --- /dev/null +++ b/hbhunger/locale/hbhunger.pt.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation=Saciedade +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/locale/hbhunger.ru.tr b/hbhunger/locale/hbhunger.ru.tr new file mode 100644 index 0000000..7142233 --- /dev/null +++ b/hbhunger/locale/hbhunger.ru.tr @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation=голод +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/locale/template.txt b/hbhunger/locale/template.txt new file mode 100644 index 0000000..d3c02c6 --- /dev/null +++ b/hbhunger/locale/template.txt @@ -0,0 +1,9 @@ +# textdomain:hbhunger +Hunger with HUD Bar= +Adds a simple hunger meachanic with satiation, food poisoning and different healing.= +Satiation= +[] = +Set satiation of player or yourself= +Not possible, damage is disabled.= +Invalid satiation!= +Player @1 does not exist.= diff --git a/hbhunger/mod.conf b/hbhunger/mod.conf new file mode 100644 index 0000000..34698a6 --- /dev/null +++ b/hbhunger/mod.conf @@ -0,0 +1,7 @@ +name = hbhunger +title = Hunger with HUD Bar +description = Adds a simple hunger meachanic with satiation, food poisoning and different healing. +depends = hudbars +optional_depends = default, flowers, animalmaterials, bucket, bushes, bushes_classic, cooking, creatures, docfarming, dwarves, ethereal, farming, farming_plus, ferns, fishing, fruit, glooptest, jkanimals, jkfarming, jkwine, kpgmobs, mobfcooking, mobs, moretrees, mtfoods, mush45, mushroom, seaplants, pizza, nssm +release = 26108 +author = Wuzzy diff --git a/hbhunger/register_foods.lua b/hbhunger/register_foods.lua new file mode 100644 index 0000000..c7dd5b0 --- /dev/null +++ b/hbhunger/register_foods.lua @@ -0,0 +1,331 @@ +if minetest.get_modpath("default") ~= nil then + hbhunger.register_food("default:apple", 2) + hbhunger.register_food("default:blueberries", 2) +end +if minetest.get_modpath("flowers") ~= nil then + hbhunger.register_food("flowers:mushroom_brown", 1) + hbhunger.register_food("flowers:mushroom_red", 1, "", 3) +end +if minetest.get_modpath("farming") ~= nil then + hbhunger.register_food("farming:bread", 5) +end + +if minetest.get_modpath("mobs") ~= nil then + if mobs.mod ~= nil and mobs.mod == "redo" then + hbhunger.register_food("mobs:cheese", 4) + hbhunger.register_food("mobs:meat", 8) + hbhunger.register_food("mobs:meat_raw", 4) + hbhunger.register_food("mobs:rat_cooked", 4) + hbhunger.register_food("mobs:honey", 2) + hbhunger.register_food("mobs:pork_raw", 3, "", 3) + hbhunger.register_food("mobs:pork_cooked", 8) + hbhunger.register_food("mobs:chicken_cooked", 6) + hbhunger.register_food("mobs:chicken_raw", 2, "", 3) + hbhunger.register_food("mobs:chicken_egg_fried", 2) + if minetest.get_modpath("bucket") then + hbhunger.register_food("mobs:bucket_milk", 3, "bucket:bucket_empty") + end + else + hbhunger.register_food("mobs:meat", 6) + hbhunger.register_food("mobs:meat_raw", 3) + hbhunger.register_food("mobs:rat_cooked", 5) + end +end + +if minetest.get_modpath("moretrees") ~= nil then + hbhunger.register_food("moretrees:coconut_milk", 1) + hbhunger.register_food("moretrees:raw_coconut", 2) + hbhunger.register_food("moretrees:acorn_muffin", 3) + hbhunger.register_food("moretrees:spruce_nuts", 1) + hbhunger.register_food("moretrees:pine_nuts", 1) + hbhunger.register_food("moretrees:fir_nuts", 1) +end + +if minetest.get_modpath("dwarves") ~= nil then + hbhunger.register_food("dwarves:beer", 2) + hbhunger.register_food("dwarves:apple_cider", 1) + hbhunger.register_food("dwarves:midus", 2) + hbhunger.register_food("dwarves:tequila", 2) + hbhunger.register_food("dwarves:tequila_with_lime", 2) + hbhunger.register_food("dwarves:sake", 2) +end + +if minetest.get_modpath("animalmaterials") ~= nil then + hbhunger.register_food("animalmaterials:milk", 2) + hbhunger.register_food("animalmaterials:meat_raw", 3) + hbhunger.register_food("animalmaterials:meat_pork", 3) + hbhunger.register_food("animalmaterials:meat_beef", 3) + hbhunger.register_food("animalmaterials:meat_chicken", 3) + hbhunger.register_food("animalmaterials:meat_lamb", 3) + hbhunger.register_food("animalmaterials:meat_venison", 3) + hbhunger.register_food("animalmaterials:meat_undead", 3, "", 3) + hbhunger.register_food("animalmaterials:meat_toxic", 3, "", 5) + hbhunger.register_food("animalmaterials:meat_ostrich", 3) + hbhunger.register_food("animalmaterials:fish_bluewhite", 2) + hbhunger.register_food("animalmaterials:fish_clownfish", 2) +end + +if minetest.get_modpath("fishing") ~= nil then + hbhunger.register_food("fishing:fish_raw", 2) + hbhunger.register_food("fishing:fish_cooked", 5) + hbhunger.register_food("fishing:sushi", 6) + hbhunger.register_food("fishing:shark", 4) + hbhunger.register_food("fishing:shark_cooked", 8) + hbhunger.register_food("fishing:pike", 4) + hbhunger.register_food("fishing:pike_cooked", 8) +end + +if minetest.get_modpath("glooptest") ~= nil then + hbhunger.register_food("glooptest:kalite_lump", 1) +end + +if minetest.get_modpath("bushes") ~= nil then + hbhunger.register_food("bushes:sugar", 1) + hbhunger.register_food("bushes:strawberry", 2) + hbhunger.register_food("bushes:berry_pie_raw", 3) + hbhunger.register_food("bushes:berry_pie_cooked", 4) + hbhunger.register_food("bushes:basket_pies", 15) +end + +if minetest.get_modpath("bushes_classic") then + -- bushes_classic mod, as found in the plantlife modpack + local berries = { + "strawberry", + "blackberry", + "blueberry", + "raspberry", + "gooseberry", + "mixed_berry"} + for _, berry in ipairs(berries) do + if berry ~= "mixed_berry" then + hbhunger.register_food("bushes:"..berry, 1) + end + hbhunger.register_food("bushes:"..berry.."_pie_raw", 2) + hbhunger.register_food("bushes:"..berry.."_pie_cooked", 5) + hbhunger.register_food("bushes:basket_"..berry, 15) + end +end + +if minetest.get_modpath("mushroom") ~= nil then + hbhunger.register_food("mushroom:brown", 1) + hbhunger.register_food("mushroom:red", 1, "", 3) + -- mushroom potions: red = strong poison, brown = light restorative + if minetest.get_modpath("vessels") then + hbhunger.register_food("mushroom:brown_essence", 1, "vessels:glass_bottle", nil, 4) + hbhunger.register_food("mushroom:poison", 1, "vessels:glass_bottle", 10) + end +end + +if minetest.get_modpath("docfarming") ~= nil then + hbhunger.register_food("docfarming:carrot", 3) + hbhunger.register_food("docfarming:cucumber", 2) + hbhunger.register_food("docfarming:corn", 3) + hbhunger.register_food("docfarming:potato", 4) + hbhunger.register_food("docfarming:bakedpotato", 5) + hbhunger.register_food("docfarming:raspberry", 3) +end + +if minetest.get_modpath("farming_plus") ~= nil then + hbhunger.register_food("farming_plus:carrot_item", 3) + hbhunger.register_food("farming_plus:banana", 2) + hbhunger.register_food("farming_plus:orange_item", 2) + hbhunger.register_food("farming:pumpkin_bread", 4) + hbhunger.register_food("farming_plus:strawberry_item", 2) + hbhunger.register_food("farming_plus:tomato_item", 2) + hbhunger.register_food("farming_plus:potato_item", 4) + hbhunger.register_food("farming_plus:rhubarb_item", 2) +end + +if minetest.get_modpath("mtfoods") ~= nil then + hbhunger.register_food("mtfoods:dandelion_milk", 1) + hbhunger.register_food("mtfoods:sugar", 1) + hbhunger.register_food("mtfoods:short_bread", 4) + hbhunger.register_food("mtfoods:cream", 1) + hbhunger.register_food("mtfoods:chocolate", 2) + hbhunger.register_food("mtfoods:cupcake", 2) + hbhunger.register_food("mtfoods:strawberry_shortcake", 2) + hbhunger.register_food("mtfoods:cake", 3) + hbhunger.register_food("mtfoods:chocolate_cake", 3) + hbhunger.register_food("mtfoods:carrot_cake", 3) + hbhunger.register_food("mtfoods:pie_crust", 3) + hbhunger.register_food("mtfoods:apple_pie", 3) + hbhunger.register_food("mtfoods:rhubarb_pie", 2) + hbhunger.register_food("mtfoods:banana_pie", 3) + hbhunger.register_food("mtfoods:pumpkin_pie", 3) + hbhunger.register_food("mtfoods:cookies", 2) + hbhunger.register_food("mtfoods:mlt_burger", 5) + hbhunger.register_food("mtfoods:potato_slices", 2) + hbhunger.register_food("mtfoods:potato_chips", 3) + --mtfoods:medicine + hbhunger.register_food("mtfoods:casserole", 3) + hbhunger.register_food("mtfoods:glass_flute", 2) + hbhunger.register_food("mtfoods:orange_juice", 2) + hbhunger.register_food("mtfoods:apple_juice", 2) + hbhunger.register_food("mtfoods:apple_cider", 2) + hbhunger.register_food("mtfoods:cider_rack", 2) +end + +if minetest.get_modpath("fruit") ~= nil then + hbhunger.register_food("fruit:apple", 2) + hbhunger.register_food("fruit:pear", 2) + hbhunger.register_food("fruit:bananna", 3) + hbhunger.register_food("fruit:orange", 2) +end + +if minetest.get_modpath("mush45") ~= nil then + hbhunger.register_food("mush45:meal", 4) +end + +if minetest.get_modpath("seaplants") ~= nil then + hbhunger.register_food("seaplants:kelpgreen", 1) + hbhunger.register_food("seaplants:kelpbrown", 1) + hbhunger.register_food("seaplants:seagrassgreen", 1) + hbhunger.register_food("seaplants:seagrassred", 1) + hbhunger.register_food("seaplants:seasaladmix", 6) + hbhunger.register_food("seaplants:kelpgreensalad", 1) + hbhunger.register_food("seaplants:kelpbrownsalad", 1) + hbhunger.register_food("seaplants:seagrassgreensalad", 1) + hbhunger.register_food("seaplants:seagrassgreensalad", 1) +end + +if minetest.get_modpath("mobfcooking") ~= nil then + hbhunger.register_food("mobfcooking:cooked_pork", 6) + hbhunger.register_food("mobfcooking:cooked_ostrich", 6) + hbhunger.register_food("mobfcooking:cooked_beef", 6) + hbhunger.register_food("mobfcooking:cooked_chicken", 6) + hbhunger.register_food("mobfcooking:cooked_lamb", 6) + hbhunger.register_food("mobfcooking:cooked_venison", 6) + hbhunger.register_food("mobfcooking:cooked_fish", 6) +end + +if minetest.get_modpath("creatures") ~= nil then + hbhunger.register_food("creatures:meat", 6) + hbhunger.register_food("creatures:flesh", 3) + hbhunger.register_food("creatures:rotten_flesh", 3, "", 3) +end + +if minetest.get_modpath("ethereal") then + hbhunger.register_food("ethereal:strawberry", 1) + hbhunger.register_food("ethereal:banana", 4) + hbhunger.register_food("ethereal:pine_nuts", 1) + hbhunger.register_food("ethereal:bamboo_sprout", 0, "", 3) + hbhunger.register_food("ethereal:fern_tubers", 1) + hbhunger.register_food("ethereal:banana_bread", 7) + hbhunger.register_food("ethereal:mushroom_plant", 2) + hbhunger.register_food("ethereal:coconut_slice", 2) + hbhunger.register_food("ethereal:golden_apple", 4, "", nil, 10) + hbhunger.register_food("ethereal:wild_onion_plant", 2) + hbhunger.register_food("ethereal:mushroom_soup", 4, "ethereal:bowl") + hbhunger.register_food("ethereal:mushroom_soup_cooked", 6, "ethereal:bowl") + hbhunger.register_food("ethereal:hearty_stew", 6, "ethereal:bowl") + hbhunger.register_food("ethereal:hearty_stew_cooked", 10, "ethereal:bowl") + if minetest.get_modpath("bucket") then + hbhunger.register_food("ethereal:bucket_cactus", 2, "bucket:bucket_empty") + end + hbhunger.register_food("ethereal:fish_raw", 2) + hbhunger.register_food("ethereal:fish_cooked", 5) + hbhunger.register_food("ethereal:seaweed", 1) + hbhunger.register_food("ethereal:yellowleaves", 1, "", nil, 1) + hbhunger.register_food("ethereal:sashimi", 4) + hbhunger.register_food("ethereal:orange", 2) +end + +if minetest.get_modpath("farming") and farming.mod == "redo" then + hbhunger.register_food("farming:bread", 6) + hbhunger.register_food("farming:potato", 1) + hbhunger.register_food("farming:baked_potato", 6) + hbhunger.register_food("farming:cucumber", 4) + hbhunger.register_food("farming:tomato", 4) + hbhunger.register_food("farming:carrot", 3) + hbhunger.register_food("farming:carrot_gold", 6, "", nil, 8) + hbhunger.register_food("farming:corn", 3) + hbhunger.register_food("farming:corn_cob", 5) + hbhunger.register_food("farming:melon_slice", 2) + hbhunger.register_food("farming:pumpkin_slice", 1) + hbhunger.register_food("farming:pumpkin_bread", 9) + hbhunger.register_food("farming:coffee_cup", 2, "farming:drinking_cup") + hbhunger.register_food("farming:coffee_cup_hot", 3, "farming:drinking_cup", nil, 2) + hbhunger.register_food("farming:cookie", 2) + hbhunger.register_food("farming:chocolate_dark", 3) + hbhunger.register_food("farming:donut", 4) + hbhunger.register_food("farming:donut_chocolate", 6) + hbhunger.register_food("farming:donut_apple", 6) + hbhunger.register_food("farming:raspberries", 1) + hbhunger.register_food("farming:blueberries", 1) + hbhunger.register_food("farming:muffin_blueberry", 4) + if minetest.get_modpath("vessels") then + hbhunger.register_food("farming:smoothie_raspberry", 2, "vessels:drinking_glass") + end + hbhunger.register_food("farming:rhubarb", 1) + hbhunger.register_food("farming:rhubarb_pie", 6) + hbhunger.register_food("farming:beans", 1) +end + +if minetest.get_modpath("kpgmobs") ~= nil then + hbhunger.register_food("kpgmobs:uley", 3) + hbhunger.register_food("kpgmobs:meat", 6) + hbhunger.register_food("kpgmobs:rat_cooked", 5) + hbhunger.register_food("kpgmobs:med_cooked", 4) + if minetest.get_modpath("bucket") then + hbhunger.register_food("kpgmobs:bucket_milk", 4, "bucket:bucket_empty") + end +end + +if minetest.get_modpath("jkfarming") ~= nil then + hbhunger.register_food("jkfarming:carrot", 3) + hbhunger.register_food("jkfarming:corn", 3) + hbhunger.register_food("jkfarming:melon_part", 2) + hbhunger.register_food("jkfarming:cake", 3) +end + +if minetest.get_modpath("jkanimals") ~= nil then + hbhunger.register_food("jkanimals:meat", 6) +end + +if minetest.get_modpath("jkwine") ~= nil then + hbhunger.register_food("jkwine:grapes", 2) + hbhunger.register_food("jkwine:winebottle", 1) +end + +if minetest.get_modpath("cooking") ~= nil then + hbhunger.register_food("cooking:meat_beef_cooked", 4) + hbhunger.register_food("cooking:fish_bluewhite_cooked", 3) + hbhunger.register_food("cooking:fish_clownfish_cooked", 1) + hbhunger.register_food("cooking:meat_chicken_cooked", 2) + hbhunger.register_food("cooking:meat_cooked", 2) + hbhunger.register_food("cooking:meat_pork_cooked", 3) + hbhunger.register_food("cooking:meat_toxic_cooked", -3) + hbhunger.register_food("cooking:meat_venison_cooked", 3) + hbhunger.register_food("cooking:meat_undead_cooked", 1) +end + +-- ferns mod of plantlife_modpack +if minetest.get_modpath("ferns") ~= nil then + hbhunger.register_food("ferns:fiddlehead", 1, "", 1) + hbhunger.register_food("ferns:fiddlehead_roasted", 3) + hbhunger.register_food("ferns:ferntuber_roasted", 3) + hbhunger.register_food("ferns:horsetail_01", 1) +end + +if minetest.get_modpath("pizza") ~= nil then + hbhunger.register_food("pizza:pizza", 30, "", nil, 30) + hbhunger.register_food("pizza:pizzaslice", 5, "", nil, 5) +end + +if minetest.get_modpath("nssm") then + hbhunger.register_food("nssm:werewolf_leg", 3) + hbhunger.register_food("nssm:heron_leg", 2) + hbhunger.register_food("nssm:chichibios_heron_leg", 4) + hbhunger.register_food("nssm:crocodile_tail", 3) + hbhunger.register_food("nssm:duck_legs", 1) + hbhunger.register_food("nssm:ant_leg", 1) + hbhunger.register_food("nssm:spider_leg", 1) + hbhunger.register_food("nssm:tentacle", 2) + hbhunger.register_food("nssm:worm_flesh", 2, "", 2) -- poisonous + hbhunger.register_food("nssm:amphibian_heart", 1) + hbhunger.register_food("nssm:raw_scrausics_wing", 1) + -- superfoods + hbhunger.register_food("nssm:phoenix_nuggets", 20, "", nil, 20) + hbhunger.register_food("nssm:phoenix_tear", 20, "", nil, 20) +end + diff --git a/hbhunger/screenshot.png b/hbhunger/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..5af6583667df4ff97d008c7b503a307616773244 GIT binary patch literal 8498 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 XjSSm>(Iyuu=*7t{MzESo6!-rDJ|^lR literal 0 HcmV?d00001 diff --git a/hbhunger/textures/hbhunger_bar.png b/hbhunger/textures/hbhunger_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..c94bf528cffed7708a4150a498020dd3fbef492a GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea!3HF4R;=3sq{Ka4978y+C)-Rs_hEh`5Ogwf cu}x!Suzkzq*Q+o09;k%D)78&qol`;+0I)9Fdh=fP7(8A5T-G@yGywn`&?ATd literal 0 HcmV?d00001 diff --git a/hbhunger/textures/hbhunger_bgicon.png b/hbhunger/textures/hbhunger_bgicon.png new file mode 100644 index 0000000000000000000000000000000000000000..07e21e7be47ebfe19f972382f6ea5a086a33cbfc GIT binary patch literal 417 zcmV;S0bc%zP)pGQ%OWYRCt`Nlf7=jFcd~Z)s4q-V#j}S9N(Bo9uNaUNQ_8GOc{AB z-maBG`8vgdma0hS*v&hyhZwANsZfiVWoIXLI2s_N})-8TUd zjUfaO5kd%1O2HU|rfFcUg;ENPvG<1pBD&Od4Jjq8wTLldwOXO?dsu5Bgg{xAQ?fA& z_WS*8yWNh)7?foR&N5y3eJB7(IRbzSGHX|2bcfQT;6IdIP5z0X~xln_Ed zN(t{hy!V*u7-N@P!PPkj=Nw{;xm#6LIh9fhA%u(&0=I$>BFd4Sb1=q0YmKI9Af<#c z2Gf8i02IYA470=GaOt`(Prq&3%x%}(!$fqwdxhO@hZrMbjOe-!lkg`V?!kF}D%R^Y zQc6fEVX;^s#)y;>Hk%FlzQ@Bw8iwKJ(MJBpU4rBB`1&Wov!Ce`d<6U`HGiA|00000 LNkvXXu0mjf5NEV} literal 0 HcmV?d00001 diff --git a/hbhunger/textures/hbhunger_icon.png b/hbhunger/textures/hbhunger_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a5cc2a12339c1fcba9e605fb5cae51aabcefb60c GIT binary patch literal 522 zcmV+l0`>igP)pGyh%hsRCt`NlfP?IVHAd+ivNL21xFVL|C0n#xP+i^QAlWqIyfi| zNJ(|Dv}V%5Hsp#oVkM*!2m~Z0v~q__BmSVxu^J9O+YXXFK0RD zIWOP$9wae|CK~=f0DpR6MD-+cW1&hnQ0XQr+Wh>pZvIwADLRAaxBv4?74{TPENeux5e{O2973m*1$T%o?iuPB~-Xhx1 zqUJJcrcv`2GHc-ylSjtk_{=X1%2(7bphE|J$)kh(urY^PIn>IBGQ&kc_nDm%_0}w4oO^A8-asU7T M07*qoM6N<$g3~bIPx#24YJ`L;zF(Q~*>nW5M+R000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jB<= z4G|!{QJPu+00E9kL_t(I%f*v1ZxcZfg}+%lXOdHLDJW172~a|s6hY}|k>F2I&{(+S zS5PAOC6??q1w~?^5Xnu7C^1SLoEQ>=kMqr)cPUP1V&x!33SPClnwfoX-i$csxCsn5 zL^(ffuD;>L`Uhux0l~}kf5wD<$HgqiP2S`Qm#b>E>msvB1cwmS2 zdKc=gszkjAA|Z4k-SIJ@3$X)-i~m@i9*nW)u2{m^$8Rj(xyP@KA?n50fkO`!GGlNG z=B8~^|S literal 0 HcmV?d00001 diff --git a/hbsprint/.github/workflows/build.yml b/hbsprint/.github/workflows/build.yml new file mode 100644 index 0000000..05e6384 --- /dev/null +++ b/hbsprint/.github/workflows/build.yml @@ -0,0 +1,11 @@ +on: [push, pull_request] +name: build +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: lint + uses: Roang-zero1/factorio-mod-luacheck@master + with: + luacheckrc_url: "" diff --git a/hbsprint/.luacheckrc b/hbsprint/.luacheckrc new file mode 100644 index 0000000..855ad92 --- /dev/null +++ b/hbsprint/.luacheckrc @@ -0,0 +1,19 @@ +allow_defined_top = true +unused_args = false +max_line_length = false + +read_globals = { + string = {fields = {"split", "trim"}}, + table = {fields = {"copy", "getn"}}, + + "player_monoids", + "playerphysics", + "hb", + "vector", + "hunger_ng", +} + +globals = { + "minetest", + "hbhunger" +} diff --git a/hbsprint/LICENSE b/hbsprint/LICENSE new file mode 100644 index 0000000..82da218 --- /dev/null +++ b/hbsprint/LICENSE @@ -0,0 +1,504 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +(This is the first released version of the Lesser GPL. It also counts +as the successor of the GNU Library Public License, version 2, hence +the version number 2.1.) + + Preamble + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + +This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + +When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + +To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + +We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + +Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + +Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + +When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + +We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + +For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + +Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + +The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + +GNU LESSER GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + +You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + +Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + +However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + +When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + +If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +a) Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable "work that +uses the Library", as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the +Library. A suitable mechanism is one that (1) uses at run time a +copy of the library already present on the user's computer system, +rather than copying library functions into the executable, and (2) +will operate properly with a modified version of the library, if +the user installs one, as long as the modified version is +interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +e) Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +b) Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + +11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + +To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + +{description} +Copyright (C) {year} {fullname} + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the +library `Frob' (a library for tweaking knobs) written by James Random +Hacker. + +{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice + +That's all there is to it! diff --git a/hbsprint/README.md b/hbsprint/README.md new file mode 100644 index 0000000..c9d48b1 --- /dev/null +++ b/hbsprint/README.md @@ -0,0 +1,39 @@ +# hbSprint + +## Description +A flexible sprint mod supporting stamina, hunger and coexistance with other physics altering mods. + +## Licensing +- LGPLv2.1/CC BY-SA 3.0. Particle code: copyright (c) 2017 Elijah Duffy. +- sprint_stamina_\*icon textures: + - CC0 + - Created by Jordan Irwin (AntumDeluge) + - Based on [Running man icon by manio1](https://openclipart.org/detail/254287) + +## Notes +hbSprint can be played with Minetest 0.4.16 or above. +It has no dependencies, but supports [hudbars](https://repo.or.cz/minetest_hudbars.git) and [player_monoids](https://github.com/minetest-mods/player_monoids). + +Compatible hunger mods: [hbhunger](https://repo.or.cz/minetest_hbhunger.git) or [hunger_ng](https://gitlab.com/4w/hunger_ng). + +## List of features + +- Displays and drains stamina (by default, if hudbars is present). Hides stamina bar if full. +- Displays and drains satiation (by default, if compatible hunger mod found) +- Drains air faster while sprinting on walkable ground but in water (by default) +- Requires only forward key to be pressed, not left and right (by default) +- Requires walkable ground (no water surface sprinting) +- Particle spawning based on ground type (Thanks to [octacian](https://github.com/octacian/sprint/)) +- All variables customizable in Advanced settings or directly in minetest.conf + + +## Known issues +- Forward double tap support not implemented + +## Bug reports and suggestions +You can report bugs or suggest ideas by [filing an issue](http://github.com/tacotexmex/hbsprint/issues/new). + +## Links +* [Download ZIP](https://github.com/minetest-mods/hbsprint/archive/master.zip) +* [Source](https://github.com/minetest-mods/hbsprint) +* [Forum thread](https://forum.minetest.net/viewtopic.php?f=9&t=18069&p=282981) diff --git a/hbsprint/init.lua b/hbsprint/init.lua new file mode 100644 index 0000000..df4769a --- /dev/null +++ b/hbsprint/init.lua @@ -0,0 +1,261 @@ +-- Vars + +local function setting_get(name, default) + return minetest.settings:get(name) or default +end + +local speed = tonumber(setting_get("sprint_speed", "1.3")) +local jump = tonumber(setting_get("sprint_jump", "1.1")) +local dir = minetest.is_yes(setting_get("sprint_forward_only", "false")) +local particles = tonumber(setting_get("sprint_particles", "2")) +local stamina = minetest.is_yes(setting_get("sprint_stamina", "true")) +local stamina_drain = tonumber(setting_get("sprint_stamina_drain", "2")) +local stamina_heal = tonumber(setting_get("sprint_stamina_heal", "2")) +local standing = tonumber(setting_get("sprint_stamina_standing", "2.5")) +local replenish = tonumber(setting_get("sprint_stamina_replenish", "2")) +local starve = minetest.is_yes(setting_get("sprint_starve", "true")) +local starve_drain = tonumber(setting_get("sprint_starve_drain", "0.5")) +local starve_limit = tonumber(setting_get("sprint_starve_limit", "6")) +local breath = minetest.is_yes(setting_get("sprint_breath", "true")) +local breath_drain = tonumber(setting_get("sprint_breath_drain", "1")) +local autohide = minetest.is_yes(setting_get("hudbars_autohide_stamina", "true")) + +local sprint_timer_step = 0.5 +local sprint_timer = 0 +local sprinting = {} +local stamina_timer = {} +local breath_timer = {} + +local mod_hudbars = minetest.get_modpath("hudbars") ~= nil +local mod_player_monoids = minetest.get_modpath("player_monoids") ~= nil +local mod_playerphysics = minetest.get_modpath("playerphysics") ~= nil + +if starve then + if minetest.get_modpath("hbhunger") then + starve = "hbhunger" + elseif minetest.get_modpath("hunger_ng") then + starve = "hunger_ng" + else + starve = false + end +end +if minetest.settings:get_bool("creative_mode") then + starve = false +end + +-- Functions + +local function start_sprint(player) + local name = player:get_player_name() + if not sprinting[name] then + if mod_player_monoids then + player_monoids.speed:add_change(player, speed, "hbsprint:speed") + player_monoids.jump:add_change(player, jump, "hbsprint:jump") + elseif mod_playerphysics then + playerphysics.add_physics_factor(player, "speed", "hbsprint:speed", speed) + playerphysics.add_physics_factor(player, "jump", "hbsprint:jump", jump) + else + player:set_physics_override({speed = speed, jump = jump}) + end + sprinting[name] = true + end +end + +local function stop_sprint(player) + local name = player:get_player_name() + if sprinting[name] then + if mod_player_monoids then + player_monoids.speed:del_change(player, "hbsprint:speed") + player_monoids.jump:del_change(player, "hbsprint:jump") + elseif mod_playerphysics then + playerphysics.remove_physics_factor(player, "speed", "hbsprint:speed") + playerphysics.remove_physics_factor(player, "jump", "hbsprint:jump") + else + player:set_physics_override({speed = 1, jump = 1}) + end + sprinting[name] = false + end +end + +local function drain_stamina(player) + local player_stamina = player:get_meta():get_float("hbsprint:stamina") + if player_stamina > 0 then + player_stamina = math.max(0, player_stamina - stamina_drain) + player:get_meta():set_float("hbsprint:stamina", player_stamina) + end + if mod_hudbars then + if autohide and player_stamina < 20 then hb.unhide_hudbar(player, "stamina") end + hb.change_hudbar(player, "stamina", player_stamina) + end +end + +local function replenish_stamina(player) + local player_stamina = player:get_meta():get_float("hbsprint:stamina") + local ctrl = player:get_player_control() + if player_stamina < 20 and not ctrl.jump then + if not ctrl.right and not ctrl.left and not ctrl.down and not ctrl.up and not ctrl.LMB and not ctrl.RMB then + player_stamina = math.min(20, player_stamina + standing) + else + player_stamina = math.min(20, player_stamina + stamina_heal) + end + player:get_meta():set_float("hbsprint:stamina", player_stamina) + end + if mod_hudbars then + hb.change_hudbar(player, "stamina", player_stamina) + if autohide and player_stamina >= 20 then hb.hide_hudbar(player, "stamina") end + end +end + +local function drain_hunger(player, name) + if starve == "hbhunger" then + local hunger = tonumber(hbhunger.hunger[name]) - starve_drain + hbhunger.hunger[name] = math.max(0, hunger) + hbhunger.set_hunger_raw(player) + elseif starve == "hunger_ng" then + hunger_ng.alter_hunger(name, -starve_drain, "Sprinting") + end +end + +local function drain_breath(player) + local player_breath = player:get_breath() + if player_breath < player:get_properties().breath_max then + player_breath = math.max(0, player_breath - breath_drain) + player:set_breath(player_breath) + end +end + +local function is_walkable(ground) + local ground_def = minetest.registered_nodes[ground.name] + return ground_def and (ground_def.walkable and ground_def.liquidtype == "none") +end + +local function create_particles(player, name, ground) + local def = minetest.registered_nodes[ground.name] or {} + local tile = def.tiles and def.tiles[1] or def.inventory_image + if type(tile) == "table" then + tile = tile.name + end + if not tile then + return + end + + local pos = player:get_pos() + local rand = function() return math.random(-1,1) * math.random() / 2 end + for i = 1, particles do + minetest.add_particle({ + pos = {x = pos.x + rand(), y = pos.y + 0.1, z = pos.z + rand()}, + velocity = {x = 0, y = 5, z = 0}, + acceleration = {x = 0, y = -13, z = 0}, + expirationtime = math.random(), + size = math.random() + 0.5, + vertical = false, + texture = tile, + }) + end +end + +-- Registrations + +if mod_hudbars and stamina then + hb.register_hudbar( + "stamina", + 0xFFFFFF, + "Stamina", + { + bar = "sprint_stamina_bar.png", + icon = "sprint_stamina_icon.png", + bgicon = "sprint_stamina_bgicon.png" + }, + 20, + 20, + autohide) +end + +minetest.register_on_joinplayer(function(player) + if stamina then + if mod_hudbars then + hb.init_hudbar(player, "stamina", 20, 20, autohide) + end + player:get_meta():set_float("hbsprint:stamina", 20) + end +end) + +local function sprint_step(player, dtime) + local name = player:get_player_name() + local fast = minetest.get_player_privs(name).fast + + if not fast then + if stamina then + stamina_timer[name] = (stamina_timer[name] or 0) + dtime + end + if breath then + breath_timer[name] = (breath_timer[name] or 0) + dtime + end + end + + local ctrl = player:get_player_control() + local key_press + if dir then + key_press = ctrl.aux1 and ctrl.up and not ctrl.left and not ctrl.right + else + key_press = ctrl.aux1 and (ctrl.up or ctrl.left or ctrl.right or ctrl.down) + end + + if not key_press then + stop_sprint(player) + if stamina and not fast and stamina_timer[name] >= replenish then + replenish_stamina(player) + stamina_timer[name] = 0 + end + return + end + + local ground_pos = player:get_pos() + ground_pos.y = math.floor(ground_pos.y) + -- check if player is reasonably near a walkable node + local ground + for _, y_off in ipairs({0, -1, -2}) do + local testpos = vector.add(ground_pos, {x=0, y=y_off, z=0}) + local testnode = minetest.get_node_or_nil(testpos) + if testnode ~= nil and is_walkable(testnode) then + ground = testnode + break + end + end + + local player_stamina = 1 + if stamina then + player_stamina = player:get_meta():get_float("hbsprint:stamina") + end + local hunger = 30 + if starve == "hbhunger" then + hunger = tonumber(hbhunger.hunger[name]) + elseif starve == "hunger_ng" then + hunger = hunger_ng.get_hunger_information(name).hunger.exact + end + + if (player_stamina > 0 and hunger > starve_limit and ground) or fast then + start_sprint(player) + if stamina and not fast then drain_stamina(player) end + if starve and not fast then drain_hunger(player, name) end + if breath and not fast and breath_timer[name] >= 2 then + drain_breath(player) + breath_timer[name] = 0 + end + if particles and ground then + create_particles(player, name, ground) + end + else + stop_sprint(player) + end +end + +minetest.register_globalstep(function(dtime) + sprint_timer = sprint_timer + dtime + if sprint_timer >= sprint_timer_step then + for _, player in ipairs(minetest.get_connected_players()) do + sprint_step(player, sprint_timer) + end + sprint_timer = 0 + end +end) diff --git a/hbsprint/mod.conf b/hbsprint/mod.conf new file mode 100644 index 0000000..c10eedd --- /dev/null +++ b/hbsprint/mod.conf @@ -0,0 +1,6 @@ +name = hbsprint +optional_depends = player_monoids, hudbars, hbhunger, hunger_ng +description = A flexible sprint mod supporting stamina, hunger and monoids. +release = 16568 +author = texmex +title = Hbsprint diff --git a/hbsprint/settingtypes.txt b/hbsprint/settingtypes.txt new file mode 100644 index 0000000..aaac3c0 --- /dev/null +++ b/hbsprint/settingtypes.txt @@ -0,0 +1,42 @@ +#Sprint speed multiplier +sprint_speed (Sprint speed multiplier) float 1.3 + +#Sprint jump multiplier +sprint_jump (Sprint jump multiplier) float 1.1 + +#Require player to move forward only to be able to sprint +sprint_forward_only (Sprint forward only) bool true + +#The amount of particles to spawn behind a sprinting player +sprint_particles (Particles) float 2 + +#Drain stamina while sprinting +sprint_stamina (Stamina) bool true + +#The amount of stamina to drain while sprinting +sprint_stamina_drain (Stamina drain) float 2 + +#The amount of stamina to heal while not sprinting +sprint_stamina_heal (Stamina heal) float 2 + +#The amount of stamina to heal while not moving or taking any actions +sprint_stamina_standing (Stamina heal) float 2.5 + +#The amount of seconds before starting to replenish stamina +sprint_stamina_replenish (Stamina replenish) float 2 + +#Drain satiation while sprinting +sprint_starve (Starve) bool true + +#The amount of satiation to drain while sprinting +sprint_starve_drain (Starve drain) float 0.5 + +#Drain air while sprinting under water +sprint_breath (Breath) bool true + +#The amount of air to drain while sprinting under water +sprint_breath_drain (Breath drain) float 1 + +#If enabled (default), the stamina indicators in the HUD will be automatically hidden shortly +#after stamina has filled up. Otherwise, stamina will always be displayed. +hudbars_autohide_stamina (Automatically hide staminal indicator) bool true diff --git a/hbsprint/textures/sprint_stamina_bar.png b/hbsprint/textures/sprint_stamina_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..55e1462c531d641cf99a51d2274d4d94e1411f2a GIT binary patch literal 71 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea0U|e_vV07r_&i-4Ln;`P1!l85l`Lj>pCi`T TRH;$`lwt66^>bP0l+XkK-vXqJTnPo-U3d8t13_J904?aIAXq(5|-qU`LUwoRZHK7dDND0?TeZ zNtn$s;VoxC)q_oLvWM3F|F>1;*Q5tQ-p`I6ZJy^=VWq?!9&h5v%h#RFEB#r#(F$lP NgQu&X%Q~loCIE)!Hn;!) literal 0 HcmV?d00001 diff --git a/hbsprint/textures/sprint_stamina_icon.png b/hbsprint/textures/sprint_stamina_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..89fce3b041235d9540e412a768c4e7a1b62489c3 GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFP2=EDUt!H3R>K0X-ETJ)7Qe&2+ z=4?rw71BoQ6fHMuSZ&pG*lggm#n^SLna6fZ&+S&;`>g+{pL+|`%UBZR7tG-B>_!@p z!&%@FSq!x3ItVj5Y0Rzw3bL1Y`ns||i~3=ChF^0#Z=6L$j|%i!ti=d#Wzp$PyaO-khe literal 0 HcmV?d00001 diff --git a/hudbars/.mailmap b/hudbars/.mailmap new file mode 100644 index 0000000..3d78b58 --- /dev/null +++ b/hudbars/.mailmap @@ -0,0 +1,2 @@ +Wuzzy +Wuzzy diff --git a/hudbars/API.md b/hudbars/API.md new file mode 100644 index 0000000..0d62590 --- /dev/null +++ b/hudbars/API.md @@ -0,0 +1,210 @@ +API documentation for the HUD bars mod +====================================== + +## Introduction +This API allows you to add, change, hide and unhide custom HUD bars for this mod. + +## Overview +To give you a *very* brief overview over this API, here is the basic workflow on how to add your own custom HUD bar: + +* Create images for your HUD bar +* Call `hb.register_hudbar` to make the definition of the HUD bar known to this mod +* Call `hb.init_hudbar` for each player for which you want to use previously defined HUD bar +* Use `hb.change_hudbar` whenever you need to change the values of a HUD bar of a certain player +* If you need it: Use `hb.hide_hudbar` and `hb.unhide_hudbar` to hide or unhide HUD bars of a certain player + +## The basic rules +In order to use this API, you should be aware of a few basic rules in order to understand it: + +* A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%. +* The current value must always be equal to or smaller then the maximum +* Both current value and maximum must not be smaller than 0 +* Both current value and maximum must be real numbers. So no NaN, infinity, etc. +* The HUD bar will be hidden if the maximum equals 0. This is intentional. +* The health and breath HUD bars are hardcoded. + +These are soft rules, the HUD bars mod will not enforce all of these. +But this mod has been programmed under the assumption that these rules are followed, for integrity. + +## Adding a HUD bar +To make a new HUD bar known to this mod, you need … + +* … an image of size 2×16 for the bar +* … an icon of size 16×16 (optional) +* … to register it with `hb.register_hudbar` + +### Bar image +The image for the bar will be repeated horizontally to denote the “value” of the HUD bar. +It **must** be of size 2×16. +If neccessary, the image will be split vertically in half, and only the left half of the image +is displayed. So the final HUD bar will always be displayed on a per-pixel basis. + +The default bar images are single-colored, but you can use other styles as well, for instance, +a vertical gradient. + +### Icon +A 16×16 image shown left of the HUD bar. This is optional. + +### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` +This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden +and unhidden on a per-player basis. +Note this does not yet display the HUD bar. + +The HUD bars will be displayed in a “first come, first serve” order. This API does not allow fow a custom order or a way to set it +manually in a reliable way. However, you can use the setting `hudbars_sorting` for this. See the advanced setting menu in Minetest +for more information. + + +#### Parameters +* `identifier`: A globally unique internal name for the HUD bar, will be used later to refer to it. Please only rely on alphanumeric characters for now. The identifiers “`health`” and “`breath`” are used internally for the built-in health and breath bar, respectively. Please do not use these names. +* `text_color`: A 3-octet number defining the color of the text. The octets denote, in this order red, green and blue and range from `0x00` (complete lack of this component) to `0xFF` (full intensity of this component). Example: `0xFFFFFF` for white. +* `label`: A string which is displayed on the HUD bar itself to describe the HUD bar. Try to keep this string short. +* `textures`: A table with the following fields: + * `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section). + * `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used. + * `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode. +* `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value +* `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value +* `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it. +* `format_string`: Optional; You can specify an alternative format string to use for the final text on the HUD bar. The default format string is “`@1: @2/@3`” (The “@” numbers are placeholders that have a meaning in this order: @1 = Label, @2 = current value, @3 = maximum value). Do *not* use minetest.translator on this string, the string will be translated by `hudbars`, but you still must put this string into the translation catalogue file. +* `format_string_config`: Required if `format_string` is set. This allows to change which parameters to use in the format string. It's a table with these fields: +* `textdomain`: Text domain of the format string, used by `minetest.translate` if missing or set to `nil` will use `minetest.get_translator` + * `order`: Table that contains the order of the placeholders. It's also possible to remove placeholders. Default order: `{ "label", "value", "max_value" }` + * `format_value`: Format string to apply when displaying `value`. Syntax is same as in `string.format`. Default: `"%d"` + * `format_max_value`: Same as `format_value` but is applied to `max_value` + +#### Example +Example (mostly) from `hbarmor` mod: + +``` +hb.register_hudbar("armor", 0xFFFFFF, minetest.translator("hbarmor", "Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 100, hbarmor.autohide, N("@1: @2%"), { order = { "label", "value" }, textdomain = "hbarmor" } ) +``` + +Displays an armor HUD bar with a label of the form „Armor: 53%“. (`N` is a dummy function that returns its argument, used to make the string visible for translator scripts.) + +#### Return value +Always `nil`. + + +## Displaying a HUD bar +After a HUD bar has been registered, they are not yet displayed yet for any player. HUD bars must be +explicitly initialized on a per-player basis. + +You probably want to do this in the `minetest.register_on_joinplayer`. + +### `hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)` +This function initialzes and activates a previously registered HUD bar and assigns it to a +certain client/player. This has only to be done once per player and after that, you can change +the values using `hb.change_hudbar`. + +However, if `start_hidden` was set to `true` for the HUD bar (in `hb.register_hudbar`), the HUD bar +will initially be hidden, but the HUD elements are still sent to the client. Otherwise, +the HUD bar will be initially be shown to the player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. +* `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. +* `start_value`: The initial current value of the HUD bar. This is optional, `default_start_value` of the registration function will be used, if this is `nil`. +* `start_max`: The initial maximum value of the HUD bar. This is optional, `default_start_max` of the registration function will be used, if this is `nil` +* `start_hidden`: Whether the HUD bar is initially hidden. This is optional, `default_start_hidden` of the registration function will be used as default + +#### Return value +`true` on success, `false` otherwise. + + +## Modifying a HUD bar +After a HUD bar has been added, you can change the current and maximum value and other attributes on a per-player basis. +You use the function `hb.change_hudbar` for this. + +### `hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color)` +Changes the values and the appearance of an initialized HUD bar for a certain player. `new_value` +and `new_max_value` are the most important parameters as they specify the new current and maximum new values, you do not need +to worry too much about the other parameters. + +The following parameters are less important and provided for styling the HUD bar after registration (if +this is desired). The “styling” parameters parallel the parameters of `hb.register_hudbar`. It is +recommended to not change the style of a HUD bar too often as this can be distracting or confusing +for players. + +`new_value`, `new_max_value` `new_icon`, `new_bgicon`, `new_bar`, `new_label` and `new_text_color` can be +`nil`; if one of them is `nil`, that means the value is unchanged. If all those values are `nil`, this +function is a no-op. + +This function tries to minimize the amount of calls to `hud_change` of the Minetest Lua API +(and thus, network traffic), when you only change the value and/or maximum value. In this case, +`hud_change` is only called if it is actually needed, e.g. when the actual length of the bar +or the displayed string changed, so you do not have to worry about it. There is, however, no +such network optimization for the “styling” parameters, so keep this in mind. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to change, as specified in `hb.register_hudbar`. +* `new_value`: The new current value of the HUD bar +* `new_max_value`: The new maximum value of the HUD bar +* `new_icon`: File name of the new icon +* `new_bgicon`: File name of the new background icon for the modern-style statbar +* `new_bar`: File name of the new bar segment image +* `new_label`: A new text label of the HUD bar. Note the format string still applies +* `new_text_color`: A 3-octet number defining the new color of the text. + +#### Return value +`true` on success, `false` otherwise. + + +## Hiding and unhiding a HUD bar +You can also hide custom HUD bars, meaning they will not be displayed for a certain player. You can still +use `hb.change_hudbar` on a hidden HUD bar, the new values will be correctly displayed after the HUD bar +has been unhidden. Both functions will only call `hud_change` if there has been an actual change to avoid +unneccessary traffic. + +Note that the hidden state of a HUD bar will *not* be saved by this mod on server shutdown, so you may need +to write your own routines for this or by setting the correct value for `start_hidden` when calling +`hb.init_hudbar`. + +### `hb.hide_hudbar(player, identifier)` +Hides the specified HUD bar from the screen of the specified player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`. + +#### Return value +`true` on success, `false` otherwise. + + +### `hb.unhide_hudbar(player, identifier)` +Makes a previously hidden HUD bar visible again to a player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to unhide, as specified in `hb.register_hudbar`. + +#### Return value +`true` on success, `false` otherwise. + + +## Reading HUD bar information +It is also possible to read information about existing HUD bars. + +### `hb.get_hudbar_state(player, identifier)` +Returns the current state of the active player's HUD bar. Will return `nil` if the hudbar is not initialized. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`. + +#### Return value +On success, returns a table which holds information on the current state of the HUD bar. Note +the table is a deep copy of the internal HUD bar state, it is *not* a reference; the information +hold by the table is only true for the moment you called this function. The fields of this table are: + +* `value`: Current value of HUD bar. +* `max`: Current maximum value of HUD bar. +* `hidden`: Boolean denoting whether the HUD bar is hidden. +* `barlength`: The length of the HUD bar in pixels. This field is meaningless if the HUD bar is currently hidden. +* `text`: The text shown on the HUD bar. This fiels is meaningless if the HUD bar is currently hidden. + +If the player does not exist, returns `nil` instead. + +### `hb.get_hudbar_identifiers()` +Returns a table of all currently registered HUD bar identifiers. diff --git a/hudbars/README.md b/hudbars/README.md new file mode 100644 index 0000000..b02cbb0 --- /dev/null +++ b/hudbars/README.md @@ -0,0 +1,63 @@ +# HUD Bars + +## Description +This mod changes the HUD of Minetest. It replaces the default health and breath +symbols by horizontal colored bars with text showing the number. + +Furthermore, it enables other mods to add their own custom bars to the HUD, +this mod will place them accordingly. + +**Important**: Keep in mind if running a server with this mod, that the custom +position should be displayed correctly on every screen size. + +## Current version +The current version is 2.3.6. +It works for Minetest 5.3.0 or later. + +This software uses [semantic versioning](http://semver.org), as defined by version 2.0.0 of the SemVer +standard. + +## Settings +This mod can be configured quite a bit. You can change HUD bar appearance, offsets, ordering, and more. +Use the advanced settings menu in Minetest for detailed configuration. + +## API +The API is used to add your own custom HUD bars. +Documentation for the API of this mod can be found in `API.md`. + +## Legal +### License of source code +Author: Wuzzy (2015) + +Also: This mod was forked from the “Better HUD” [hud] mod by BlockMen. + +Translations: + +* German: Wuzzy +* Portuguese: BrunoMine +* Turkish: admicos +* Dutch: kingoscargames +* Italian: Hamlet +* Malay: muhdnurhidayat +* Russian: Imk +* Spanish: wuniversales +* French: syl + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the MIT License. + +### Licenses of textures + +* `hudbars_icon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen +* `hudbars_bgicon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen +* `hudbars_icon_breath.png`—kaeza (MIT License), modified by BlockMen, modified again by Wuzzy +* `hudbars_bgicon_breath.png`—based on previous image, edited by Wuzzy (MIT License) +* `hudbars_bar_health.png`—Wuzzy (MIT License) +* `hudbars_bar_breath.png`—Wuzzy (MIT License) +* `hudbars_bar_background.png`—Wuzzy (MIT License) + +### License references + +* [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) +* [MIT License](https://opensource.org/licenses/MIT) diff --git a/hudbars/default_settings.lua b/hudbars/default_settings.lua new file mode 100644 index 0000000..810f246 --- /dev/null +++ b/hudbars/default_settings.lua @@ -0,0 +1,49 @@ +-- (Hardcoded) default settings + +hb.settings.max_bar_length = 160 +hb.settings.statbar_length = 20 + +-- Statbar positions +hb.settings.pos_left = {} +hb.settings.pos_right = {} +hb.settings.start_offset_left = {} +hb.settings.start_offset_right= {} +hb.settings.pos_left.x = hb.load_setting("hudbars_pos_left_x", "number", 0.5) +hb.settings.pos_left.y = hb.load_setting("hudbars_pos_left_y", "number", 1) +hb.settings.pos_right.x = hb.load_setting("hudbars_pos_right_x", "number", 0.5) +hb.settings.pos_right.y = hb.load_setting("hudbars_pos_right_y", "number", 1) +hb.settings.bar_type = hb.load_setting("hudbars_bar_type", "string", "progress_bar", {"progress_bar", "statbar_classic", "statbar_modern"}) +if hb.settings.bar_type == "progress_bar" then + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_offset_left_x", "number", -175) + hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_offset_left_y", "number", -86) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15) + hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86) +else + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265) + hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25) + hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90) +end +hb.settings.vmargin = hb.load_setting("hudbars_vmargin", "number", 24) +hb.settings.tick = hb.load_setting("hudbars_tick", "number", 0.1) + +-- Experimental setting: Changing this setting is not officially supported, do NOT rely on it! +hb.settings.forceload_default_hudbars = hb.load_setting("hudbars_forceload_default_hudbars", "bool", true) + +-- Misc. settings +hb.settings.alignment_pattern = hb.load_setting("hudbars_alignment_pattern", "string", "zigzag", {"zigzag", "stack_up", "stack_down"}) +hb.settings.autohide_breath = hb.load_setting("hudbars_autohide_breath", "bool", true) +hb.settings.hide_labels = hb.load_setting("hudbars_hide_labels", "bool", false) + +local sorting = minetest.settings:get("hudbars_sorting") +if sorting ~= nil then + hb.settings.sorting = {} + hb.settings.sorting_reverse = {} + for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do + hb.settings.sorting[k] = tonumber(v) + hb.settings.sorting_reverse[tonumber(v)] = k + end +else + hb.settings.sorting = { ["health"] = 0, ["breath"] = 1 } + hb.settings.sorting_reverse = { [0] = "health", [1] = "breath" } +end diff --git a/hudbars/init.lua b/hudbars/init.lua new file mode 100644 index 0000000..0a72bac --- /dev/null +++ b/hudbars/init.lua @@ -0,0 +1,583 @@ +local S = minetest.get_translator("hudbars") +local NS = function(s) return s end + +-- Boilerplate for compatibiliity with pre-5.9.0 +-- versions of minetest +local hud_def_type_field +if minetest.features.hud_def_type_field then + hud_def_type_field = "type" +else + hud_def_type_field = "hud_elem_type" +end + +hb = {} + +hb.hudtables = {} + +-- number of registered HUD bars +hb.hudbars_count = 0 + +-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning +hb.registered_slots = {} + +hb.settings = {} + +function hb.load_setting(sname, stype, defaultval, valid_values) + local sval + if stype == "string" then + sval = minetest.settings:get(sname) + elseif stype == "bool" then + sval = minetest.settings:get_bool(sname) + elseif stype == "number" then + sval = tonumber(minetest.settings:get(sname)) + end + if sval ~= nil then + if valid_values ~= nil then + local valid = false + for i=1,#valid_values do + if sval == valid_values[i] then + valid = true + end + end + if not valid then + minetest.log("error", "[hudbars] Invalid value for "..sname.."! Using default value ("..tostring(defaultval)..").") + return defaultval + else + return sval + end + else + return sval + end + else + return defaultval + end +end + +-- Load default settings +dofile(minetest.get_modpath("hudbars").."/default_settings.lua") + +local function player_exists(player) + return player ~= nil and player:is_player() +end + +local function make_label(format_string, format_string_config, label, start_value, max_value) + if hb.settings.hide_labels then + return "" + end + + local params = {} + local order = format_string_config.order + for o=1, #order do + if order[o] == "label" then + table.insert(params, label) + elseif order[o] == "value" then + if format_string_config.format_value then + table.insert(params, string.format(format_string_config.format_value, start_value)) + else + table.insert(params, start_value) + end + elseif order[o] == "max_value" then + if format_string_config.format_max_value then + table.insert(params, string.format(format_string_config.format_max_value, max_value)) + else + table.insert(params, max_value) + end + end + end + local ret + if format_string_config.textdomain and minetest.translate then + ret = minetest.translate(format_string_config.textdomain, format_string, unpack(params)) + else + ret = S(format_string, unpack(params)) + end + return ret +end + +-- Table which contains all players with active default HUD bars (only for internal use) +hb.players = {} + +function hb.value_to_barlength(value, max) + if max == 0 then + return 0 + else + if hb.settings.bar_type == "progress_bar" then + local x + if value < 0 then x=-0.5 else x = 0.5 end + local ret = math.modf((value/max) * hb.settings.max_bar_length + x) + return ret + else + local x + if value < 0 then x=-0.5 else x = 0.5 end + local ret = math.modf((value/max) * hb.settings.statbar_length + x) + return ret + end + end +end + +function hb.get_hudtable(identifier) + return hb.hudtables[identifier] +end + +function hb.get_hudbar_position_index(identifier) + if hb.settings.sorting[identifier] ~= nil then + return hb.settings.sorting[identifier] + else + local i = 0 + while true do + if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then + return i + end + i = i + 1 + end + end +end + +function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) + minetest.log("action", "hb.register_hudbar: "..tostring(identifier)) + local hudtable = {} + local pos, offset + local index = math.floor(hb.get_hudbar_position_index(identifier)) + hb.registered_slots[index] = true + if hb.settings.alignment_pattern == "stack_up" then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y - hb.settings.vmargin * index + } + elseif hb.settings.alignment_pattern == "stack_down" then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y + hb.settings.vmargin * index + } + else + if index % 2 == 0 then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2) + } + else + pos = hb.settings.pos_right + offset = { + x = hb.settings.start_offset_right.x, + y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2) + } + end + end + if format_string == nil then + format_string = NS("@1: @2/@3") + end + if format_string_config == nil then + format_string_config = {} + end + if format_string_config.order == nil then + format_string_config.order = { "label", "value", "max_value" } + end + if format_string_config.format_value == nil then + format_string_config.format_value = "%d" + end + if format_string_config.format_max_value == nil then + format_string_config.format_max_value = "%d" + end + + hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden) + if start_value == nil then start_value = hudtable.default_start_value end + if start_max == nil then start_max = hudtable.default_start_max end + if start_hidden == nil then start_hidden = hudtable.default_start_hidden end + local ids = {} + local state = {} + local name = player:get_player_name() + local bgscale, iconscale, text, barnumber, bgiconnumber + if start_max == 0 or start_hidden then + bgscale = { x=0, y=0 } + else + bgscale = { x=1, y=1 } + end + if start_hidden then + iconscale = { x=0, y=0 } + barnumber = 0 + bgiconnumber = 0 + text = "" + else + iconscale = { x=1, y=1 } + barnumber = hb.value_to_barlength(start_value, start_max) + bgiconnumber = hb.settings.statbar_length + text = make_label(format_string, format_string_config, label, start_value, start_max) + end + if hb.settings.bar_type == "progress_bar" then + ids.bg = player:hud_add({ + [hud_def_type_field] = "image", + position = pos, + scale = bgscale, + text = "hudbars_bar_background.png", + alignment = {x=1,y=1}, + offset = { x = offset.x - 1, y = offset.y - 1 }, + z_index = 0, + }) + if textures.icon ~= nil then + ids.icon = player:hud_add({ + [hud_def_type_field] = "image", + position = pos, + scale = iconscale, + text = textures.icon, + alignment = {x=-1,y=1}, + offset = { x = offset.x - 3, y = offset.y }, + z_index = 1, + }) + end + end + local bar_image, bgicon, bar_size + if hb.settings.bar_type == "progress_bar" then + bar_image = textures.bar + -- NOTE: Intentionally set to nil. For some reason, on some systems, + -- the progress bar is displaced when the bar_size is set explicitly here. + -- On the other hand, setting this to nil is deprecated in MT 5.0.0 due to + -- a debug log warning, but nothing is explained in lua_api.txt. + -- This section is a potential bug magnet, please watch with care! + -- The size of the bar image is expected to be exactly 2×16 pixels. + bar_size = nil + elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then + bar_image = textures.icon + bgicon = textures.bgicon + bar_size = {x=24, y=24} + end + ids.bar = player:hud_add({ + [hud_def_type_field] = "statbar", + position = pos, + text = bar_image, + text2 = bgicon, + number = barnumber, + item = bgiconnumber, + alignment = {x=-1,y=-1}, + offset = offset, + direction = 0, + size = bar_size, + z_index = 1, + }) + if hb.settings.bar_type == "progress_bar" then + ids.text = player:hud_add({ + [hud_def_type_field] = "text", + position = pos, + text = text, + alignment = {x=1,y=1}, + number = text_color, + direction = 0, + offset = { x = offset.x + 2, y = offset.y - 1}, + z_index = 2, + }) + end + -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table + state.hidden = start_hidden + state.value = start_value + state.max = start_max + state.text = text + state.barlength = hb.value_to_barlength(start_value, start_max) + + local main_error_text = + "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."” for player "..name..". " + + if start_max < start_value then + minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!") + end + if start_max < 0 then + minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!") + end + if start_value < 0 then + minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!") + end + + hb.hudtables[identifier].hudids[name] = ids + hb.hudtables[identifier].hudstate[name] = state + end + + hudtable.identifier = identifier + hudtable.format_string = format_string + hudtable.format_string_config = format_string_config + hudtable.label = label + hudtable.hudids = {} + hudtable.hudstate = {} + hudtable.default_start_hidden = default_start_hidden + hudtable.default_start_value = default_start_value + hudtable.default_start_max = default_start_max + + hb.hudbars_count= hb.hudbars_count + 1 + + hb.hudtables[identifier] = hudtable +end + +function hb.init_hudbar(player, identifier, start_value, start_max, start_hidden) + if not player_exists(player) then return false end + local hudtable = hb.get_hudtable(identifier) + hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden) + return true +end + +function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color) + if new_value == nil and new_max_value == nil and new_icon == nil and new_bgicon == nil and new_bar == nil and new_label == nil and new_text_color == nil then + return true + end + if not player_exists(player) then + return false + end + + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + if not hudtable.hudstate[name] then + return false + end + local value_changed, max_changed = false, false + + if new_value ~= nil then + if new_value ~= hudtable.hudstate[name].value then + hudtable.hudstate[name].value = new_value + value_changed = true + end + else + new_value = hudtable.hudstate[name].value + end + if new_max_value ~= nil then + if new_max_value ~= hudtable.hudstate[name].max then + hudtable.hudstate[name].max = new_max_value + max_changed = true + end + else + new_max_value = hudtable.hudstate[name].max + end + + if hb.settings.bar_type == "progress_bar" then + if new_icon ~= nil and hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "text", new_icon) + end + if new_bgicon ~= nil and hudtable.hudids[name].bgicon ~= nil then + player:hud_change(hudtable.hudids[name].bgicon, "text", new_bgicon) + end + if new_bar ~= nil then + player:hud_change(hudtable.hudids[name].bar , "text", new_bar) + end + if new_label ~= nil then + hudtable.label = new_label + local new_text = make_label(hudtable.format_string, hudtable.format_string_config, new_label, hudtable.hudstate[name].value, hudtable.hudstate[name].max) + player:hud_change(hudtable.hudids[name].text, "text", new_text) + end + if new_text_color ~= nil then + player:hud_change(hudtable.hudids[name].text, "number", new_text_color) + end + else + if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then + player:hud_change(hudtable.hudids[name].bar, "text", new_icon) + end + if new_bgicon ~= nil and hudtable.hudids[name].bg ~= nil then + player:hud_change(hudtable.hudids[name].bg, "text", new_bgicon) + end + end + + local main_error_text = + "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. " + if new_max_value < new_value then + minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!") + end + if new_max_value < 0 then + minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!") + end + if new_value < 0 then + minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!") + end + + if hudtable.hudstate[name].hidden == false then + if max_changed and hb.settings.bar_type == "progress_bar" then + if hudtable.hudstate[name].max == 0 then + player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0}) + else + player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1}) + end + end + + if value_changed or max_changed then + local new_barlength = hb.value_to_barlength(new_value, new_max_value) + if new_barlength ~= hudtable.hudstate[name].barlength then + player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value)) + hudtable.hudstate[name].barlength = new_barlength + end + + if hb.settings.bar_type == "progress_bar" then + local new_text = make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, new_value, new_max_value) + if new_text ~= hudtable.hudstate[name].text then + player:hud_change(hudtable.hudids[name].text, "text", new_text) + hudtable.hudstate[name].text = new_text + end + end + end + end + return true +end + +function hb.hide_hudbar(player, identifier) + if not player_exists(player) then return false end + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == true then return true end + if hb.settings.bar_type == "progress_bar" then + if hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0}) + end + player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0}) + player:hud_change(hudtable.hudids[name].text, "text", "") + end + player:hud_change(hudtable.hudids[name].bar, "number", 0) + player:hud_change(hudtable.hudids[name].bar, "item", 0) + hudtable.hudstate[name].hidden = true + return true +end + +function hb.unhide_hudbar(player, identifier) + if not player_exists(player) then return false end + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == false then return true end + local value = hudtable.hudstate[name].value + local max = hudtable.hudstate[name].max + if hb.settings.bar_type == "progress_bar" then + if hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1}) + end + if hudtable.hudstate[name].max ~= 0 then + player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1}) + end + player:hud_change(hudtable.hudids[name].text, "text", make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, value, max)) + elseif hb.settings.bar_type == "statbar_modern" then + player:hud_change(hudtable.hudids[name].bar, "scale", {x=1,y=1}) + end + player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max)) + player:hud_change(hudtable.hudids[name].bar, "item", hb.value_to_barlength(max, max)) + hudtable.hudstate[name].hidden = false + return true +end + +function hb.get_hudbar_state(player, identifier) + if not player_exists(player) then return nil end + local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()] + if not ref then return nil end + -- Do not forget to update this chunk of code in case the state changes + local copy = { + hidden = ref.hidden, + value = ref.value, + max = ref.max, + text = ref.text, + barlength = ref.barlength, + } + return copy +end + +function hb.get_hudbar_identifiers() + local ids = {} + for id, _ in pairs(hb.hudtables) do + table.insert(ids, id) + end + return ids +end + +--register built-in HUD bars +if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false) + hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true) +end + +local function hide_builtin(player) + local flags = player:hud_get_flags() + flags.healthbar = false + flags.breathbar = false + player:hud_set_flags(flags) +end + + +local function custom_hud(player) + if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + local hide + if minetest.settings:get_bool("enable_damage") then + hide = false + else + hide = true + end + local hp = player:get_hp() + local hp_max = player:get_properties().hp_max + hb.init_hudbar(player, "health", math.min(hp, hp_max), hp_max, hide) + local breath = player:get_breath() + local breath_max = player:get_properties().breath_max + local hide_breath + if breath >= breath_max and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end + hb.init_hudbar(player, "breath", math.min(breath, breath_max), breath_max, hide_breath or hide) + end +end + +local function update_health(player) + local hp_max = player:get_properties().hp_max + local hp = math.min(player:get_hp(), hp_max) + hb.change_hudbar(player, "health", hp, hp_max) +end + +-- update built-in HUD bars +local function update_hud(player) + if not player_exists(player) then return end + if minetest.settings:get_bool("enable_damage") then + if hb.settings.forceload_default_hudbars then + hb.unhide_hudbar(player, "health") + end + --air + local breath_max = player:get_properties().breath_max + local breath = player:get_breath() + + if breath >= breath_max and hb.settings.autohide_breath == true then + hb.hide_hudbar(player, "breath") + else + hb.unhide_hudbar(player, "breath") + hb.change_hudbar(player, "breath", math.min(breath, breath_max), breath_max) + end + --health + update_health(player) + elseif hb.settings.forceload_default_hudbars then + hb.hide_hudbar(player, "health") + hb.hide_hudbar(player, "breath") + end +end + +minetest.register_on_player_hpchange(function(player) + if hb.players[player:get_player_name()] ~= nil then + update_health(player) + end +end) + +minetest.register_on_respawnplayer(function(player) + update_health(player) + hb.hide_hudbar(player, "breath") +end) + +minetest.register_on_joinplayer(function(player) + hide_builtin(player) + custom_hud(player) + hb.players[player:get_player_name()] = player +end) + +minetest.register_on_leaveplayer(function(player) + hb.players[player:get_player_name()] = nil +end) + +local main_timer = 0 +local timer = 0 +minetest.register_globalstep(function(dtime) + main_timer = main_timer + dtime + timer = timer + dtime + if main_timer > hb.settings.tick or timer > 4 then + if main_timer > hb.settings.tick then main_timer = 0 end + -- only proceed if damage is enabled + if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + for _, player in pairs(hb.players) do + -- update all hud elements + update_hud(player) + end + end + end + if timer > 4 then timer = 0 end +end) diff --git a/hudbars/locale/hudbars.de.tr b/hudbars/locale/hudbars.de.tr new file mode 100644 index 0000000..3d1e697 --- /dev/null +++ b/hudbars/locale/hudbars.de.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Leben +Breath=Atem +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.es.tr b/hudbars/locale/hudbars.es.tr new file mode 100644 index 0000000..bbf0279 --- /dev/null +++ b/hudbars/locale/hudbars.es.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Salud +Breath=Aliento +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.fr.tr b/hudbars/locale/hudbars.fr.tr new file mode 100644 index 0000000..fcdc615 --- /dev/null +++ b/hudbars/locale/hudbars.fr.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Santé +Breath=Respiration +@1: @2/@3=@1 : @2/@3 \ No newline at end of file diff --git a/hudbars/locale/hudbars.it.tr b/hudbars/locale/hudbars.it.tr new file mode 100644 index 0000000..3ada5b6 --- /dev/null +++ b/hudbars/locale/hudbars.it.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Salute +Breath=Ossigeno + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20” +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.ms.tr b/hudbars/locale/hudbars.ms.tr new file mode 100644 index 0000000..eb811ab --- /dev/null +++ b/hudbars/locale/hudbars.ms.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Kesihatan +Breath=Nafas +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.nl.tr b/hudbars/locale/hudbars.nl.tr new file mode 100644 index 0000000..b9c4a41 --- /dev/null +++ b/hudbars/locale/hudbars.nl.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Gezondheid +Breath=Adem + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20” +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.pt.tr b/hudbars/locale/hudbars.pt.tr new file mode 100644 index 0000000..a818f09 --- /dev/null +++ b/hudbars/locale/hudbars.pt.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Saude +Breath=Folego + +# Formato de string padrão para progresso bar-style de barras do HUD, por exemplo “Saude 5/20” +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.ru.tr b/hudbars/locale/hudbars.ru.tr new file mode 100644 index 0000000..2d278e3 --- /dev/null +++ b/hudbars/locale/hudbars.ru.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=HP +Breath=дыхание +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/hudbars.tr.tr b/hudbars/locale/hudbars.tr.tr new file mode 100644 index 0000000..6a2ce0b --- /dev/null +++ b/hudbars/locale/hudbars.tr.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Can +Breath=Nefes +@1: @2/@3=@1: @2/@3 diff --git a/hudbars/locale/template.txt b/hudbars/locale/template.txt new file mode 100644 index 0000000..278a8af --- /dev/null +++ b/hudbars/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health= +Breath= + +# Default format string for progress bar-style HUD bars, e.g. “Health: 5/20” +@1: @2/@3= diff --git a/hudbars/mod.conf b/hudbars/mod.conf new file mode 100644 index 0000000..7c61d8a --- /dev/null +++ b/hudbars/mod.conf @@ -0,0 +1,5 @@ +name = hudbars +title = HUD Bars +description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats. +release = 27446 +author = Wuzzy diff --git a/hudbars/screenshot.png b/hudbars/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..88ee3238dbaac6e7d3769e212c0ccd4eed023b96 GIT binary patch literal 9556 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 TgAVF{e>kZqXo9QcEI$7~BOnZ3 literal 0 HcmV?d00001 diff --git a/hudbars/settingtypes.txt b/hudbars/settingtypes.txt new file mode 100644 index 0000000..4ebb5ee --- /dev/null +++ b/hudbars/settingtypes.txt @@ -0,0 +1,122 @@ +[Appearance] +# Specifies how the value indicators (i.e. health, breah, etc.) look. There are 3 styles +# available. You can choose between the default progress-bar-like bars and the good +# old statbars like you know from vanilla Minetest. +# These values are possible: +# - progress_bar: A horizontal progress-bar-like bar with a label, showing numerical value +# (current, maximum), and an icon. These bars usually convey the most +# information. This is the default and recommended value. +# - statbar_classic: Classic statbar, like in vanilla Minetest. Made out of up to 20 +# half-symbols. Those bars represent the vague ratio between +# the current value and the maximum value. 1 half-symbol stands for +# approximately 5% of the maximum value. +# - statbar_modern: Like the classic statbar, but also supports background images, this +# kind of statbar may be considered to be more user-friendly than the +# classic statbar. This bar type closely resembles the mod +# “Better HUD” [hud] by BlockMen. +hudbars_bar_type (HUD bars style) enum progress_bar progress_bar,statbar_classic,statbar_modern + + +# If enabled (default), the breath indicators in the HUD will be automatically hidden shortly +# after the breath has been filled up. Otherwise, the breath will always be displayed. +hudbars_autohide_breath (Automatically hide breath indicators) bool true + +# This setting changes the way the HUD bars are ordered on the display. You can choose +# between a zig-zag pattern (default) or a vertically stacked pattern. +# The following values are allowed: +# - zigzag: Starting from the left bottom, the next is right from the first, +# the next is above the first, the next is right of the third, etc. +# - stack_up: The HUD bars are stacked vertically, going upwards. +# - stack_down: The HUD bars are stacked vertically, going downwards. +hudbars_alignment_pattern (HUD bars alignment pattern) enum zigzag zigzag,stack_up,stack_down + +# This setting allows you to specify the order of the HUD bars explicitly. If left empty +# (the default), the health and breath indicators come first, additional indicators +# may appear in any order. This setting is quite technical and normal users probably do not +# need to worry about it. +# +# Syntax: +# The setting has to be specified as a comma-seperated list of key=value pairs, where a key +# refers to the identifier of a HUD bar and the value refers to the slot number of where the +# HUD bar should be placed. The slot number must be an integer greater of equal to 0. Where +# the HUD bars will be displayed exactly depends on the alignment pattern being used. +# All HUD bars to which no order value has been applied will fill in all slots which have +# not been occupied by the HUD bars specified in this setting, the slots will be filled in +# from the lowest slot number. +# Note that the order of those remaining HUD bars is not fixed, it basically just boils +# down on which mod “came” first. Don't worry, the mod will still work perfectly fine, this +# setting is entirely optional. +# The identifier for the health bar is “health” and the identifier for the breath bar is +# “breath”. For other HUD bars, you have to learn it from the mod which is supplying them. +# +# Be careful not to use slot indices twice, or else different HUD bars will be drawn over +# each other! +# +# Example: “breath=0, health=1” +# This makes the breath bar first and the health bar second, which is the opposite order +# of the default one. +hudbars_sorting (HUD bars order) string + +# If enabled, hide the labels over the bars +hudbars_hide_labels (Hide bar labels) bool false + +[Positions and offsets] +# Horizontal (x) main position of the HUD bars over the entire screen. +# 0.0 is left-most, 1.0 is right-most. +# For the zig-zag alignment pattern, this is for the left HUD bars. +hudbars_pos_left_x (Left HUD bar screen x position) float 0.5 0.0 1.0 +# Vertical (y) main position of the HUD bars over the entire screen. +# 0.0 is top, 1.0 is bottom. +# For the zig-zag alignment pattern, this is for the left HUD bars. +hudbars_pos_left_y (Left HUD bar screen y position) float 1.0 0.0 1.0 +# Horizontal (x) main position of the right HUD bars over the entire screen. +# 0.0 is left-most, 1.0 is right-most. +# Only used for the zig-zag alignment pattern. +hudbars_pos_right_x (Right HUD bar screen x position) float 0.5 0.0 1.0 +# Vertical main position (y) of the right HUD bars over the entire screen. +# 0.0 is top, 1.0 is bottom. +# Only used for the zig-zag alignment pattern. +hudbars_pos_right_y (Right HUD bar screen y position) float 1.0 0.0 1.0 + +# Precise x offset in pixels from the basic screen x position of the HUD bars. +# For the zig-zag alignment pattern, this is for the left HUD bars. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_left_x (Left HUD bar x offset) int -175 +# Precise y offset in pixels from the basic screen y position of the HUD bars. +# For the zig-zag alignment pattern, this is for the left HUD bars. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_left_y (Left HUD bar y offset) int -86 +# Precise x offset in pixels from the basic screen x position of the right HUD bars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_right_x (Right HUD bar x offset) int 15 +# Precise y offset in pixels from the basic screen y position of the right HUD bars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_right_y (Right HUD bar y offset) int -86 + +# Precise x offset in pixels from the basic screen x position of the HUD statbars. +# For the zig-zag alignment pattern, this is for the left HUD statbars. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_left_x (Left HUD statbar x offset) int -265 +# Precise y offset in pixels from the basic screen y position of the HUD statbars. +# For the zig-zag alignment pattern, this is for the left HUD statbars. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_left_y (Left HUD statbar y offset) int -90 +# Precise x offset in pixels from the basic screen x position of the right HUD statbars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_right_x (Right HUD statbar x offset) int 25 +# Precise y offset in pixels from the basic screen y position of the right HUD statbars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_right_y (Right HUD statbar y offset) int -90 + +# The vertical distance between two HUD bars, in pixels. +hudbars_vmargin (Vertical distance between HUD bars) int 24 0 + +[Performance] +# The of seconds which need to pass before the server updates the default HUD bars +# (health and breath). Increase this number if you have a slow server or a slow network +# connection and experience performance problems. +hudbars_tick (Default HUD bars update interval) float 0.1 0.0 4.0 diff --git a/hudbars/textures/hudbars_bar_background.png b/hudbars/textures/hudbars_bar_background.png new file mode 100644 index 0000000000000000000000000000000000000000..cbc6c3f519956fab4bbe266ef26428e4ed8bb66c GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^i-1^&gAGXDuwcytQo)`sjv*QM-rh14JYXQe>}V;R zkoYBH-o%+lW$xTKs>gD6s+8xy1Bv;QLawHB`MrGib4H^yhoEAUfS?ivb!eU7@d&*Q Z3=a;oDeIOTssb9%;OXk;vd$@?2>|+XD)|5a literal 0 HcmV?d00001 diff --git a/hudbars/textures/hudbars_bar_breath.png b/hudbars/textures/hudbars_bar_breath.png new file mode 100644 index 0000000000000000000000000000000000000000..7d19a5752472cdbc05b2a331e2e7097f91a790fd GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea!3HF4R;=3sq{Ka4978y+C(qgcqTZGn2!xqM ccyyQ<`izFVdQ&MBb@0B0K!`v3p{ literal 0 HcmV?d00001 diff --git a/hudbars/textures/hudbars_bar_health.png b/hudbars/textures/hudbars_bar_health.png new file mode 100644 index 0000000000000000000000000000000000000000..653091603ac377f93c7f98ae1f6a97f07268014d GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea!3HF4R;=3sq{Ka4978y+C+|6Y;KTezAn0V| dVw=Xu!2g}`H{Xu=SAj|xJYD@<);T3K0RYvF74QH6 literal 0 HcmV?d00001 diff --git a/hudbars/textures/hudbars_bgicon_breath.png b/hudbars/textures/hudbars_bgicon_breath.png new file mode 100644 index 0000000000000000000000000000000000000000..176629affd6ac01b1e594163c0b7d9a2000d38d3 GIT binary patch literal 811 zcmV+`1JwM9P)Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jB<= z6D1%J!{^rk00OH?L_t(I%XO1aYm`?M#-DTU`)8&vX(~iY10_=gM`LTydy zDs9kr}T5@Tc>g=B8U`~=G&hz{;BDx?V zX8>rc5oVsK>TgMs4Dvj$(=?U;HQ3nLNUEwj&&=1E`5xX;B68b%zuWD053IFinx;Yk zu(`R}Ez9yEGk?R(cL5-ZqG!x}qN+#MS{0ESZIe49@}$%0{BEr+0s!1JO^=zsp23|? z=jGz!;-%T-EX%$x%knQGy3Ne@Rn=Q-%gJQ&r|I|moiGeHnE9tU_;UcT*4`D72SoI; zuIr(QjG6f=Gk>9~zcBObKve?(X8<4!!)LR}*4jHn^tfr7(fce89}v+k z080QOZnsnbFvgs;@Q(m?opW#Y_V((dqa!uOI3jujU^wR>1ud)qpsI)M`9f8PgTcV= z?CfxsWoNCmD|KDRWm(2V|C&cc#NK-WAOPT;LzZPXopT4qn0jq(EzGj42jJUoxBDEx z6(Tw}+geo-Fte!YTLAFh-*C>2%CdZAj2Rb2fjEvoiR1WDOI#tMui6F^B5KU>@v$r~ zFIOTmWaeu`bXi1Rt7>Mg^~RWw>bf2jMNv0Rb8VIdB6@mydiu8kp#6To$n*RyfB`dq z$;?+(^@NB%Zkpy(@BNDR{<{|bK}2?=DEcFcqWZrmZ*6Ub)9G}@7<1hi^YDF97LlLh zI6iRB6=|A!nip(uZwI5%XqkvEipW_248Q;YGasw!uSt>&^E|I+Ka$=th*wuv!>XzR pW@c(Vi=xOK9v(L1@z~9a{{h8odh1caBsu^9002ovPDHLkV1i5Ccm4nX literal 0 HcmV?d00001 diff --git a/hudbars/textures/hudbars_bgicon_health.png b/hudbars/textures/hudbars_bgicon_health.png new file mode 100644 index 0000000000000000000000000000000000000000..e2be2768e569748d3d19bc3fd02e8bf36f5bfa03 GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5he4R}c>anMpx^^f z7srr_IY%!Wt~#P1z?SfSf|H6XhjMUF(nP1G4)!fyTJAl$uhp1yZF~OBr0&d?|HUb8 ztPZuo@vZs}>wN_UXGosmQF2=E`}Nk9O*$K{HO*YO)ouM-J^{g`9*w07rZh*az&zt8kNnXyH@^QZnikZw^;`Xc6*GSF+1Ni!UT}Sx6G#5x+uIUj zuU|i4bH2W8VsTr?o_U81jRYl`&h7jt!GA!4`TbwrH+$O+pWW$IEKpEtnqypauHank yq5Q_U*_Wc6T@;kkZ_6{ftDiULZ=C=482iEurPx#24YJ`L;wH)0002_L%V+f000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jB<= z6A3j$FKChg00Oc}L_t(I%dL~kYZFlv#=m>#&SWMtNm`m1rPan1k*bvnK5*p&T)8N= zx>G6WA0WDQk&U?UA1H!YDLxhj?Z$+5ydt|Ew-c9rk$BSGLy{fUKi5(qOSaQ z2hQ(19L{$L{?PEVSJbj?*{cQ8qUTFhHz0lh5eg}eIE^lz=?;GFmwqkgs-B!mXVQ?A z&0xy5nCY!tP8C8)E5^h~da)L6+I_6{=HU&o%#an>trIWgvZ0WZUVsY~5A@TlOPA^* zbew9<`ep@|T|Jj+G#-APG~H{ZBm6f5bKYf|EZwbm(V@Jq;N=MGvn@EO6!iRtxZO2^ z{jbMn7slU?oz3L4L*~>}_4@f9&H!MhS|^n7)0P(=+}M!Bt(&yedjh3p^Zo%=Diqk% zz8$$!f{07+-j04-mtXe;fJ=Vt?iVBAu|nzEp+U9+_YeFu0f4RBd8ci7UC&>BC~FDn z!2Q9?6$${9(x#6UFZW_Z>RSy4fN7IVWOW*B+tS+nx%@0Ik(g2dAOim9rAV?ZIIF<` zU^`@y2oh5zRzh!ng33DM}RwDpF zMiyUdwc4(cCr_sd01S^Uu%t%z%*@vwg@hp+rtjF((uCuXMO_zKbE_yyx#}TJV-4%m ziWzaysS@F(wM2a-NDs;u%NmKDGmbwpUI~#&Q9qL;v6^6%F-grC6!|2p#1Zx;6Ox%x zJR7rSYgdL3vsfmRFOJP)i*xeHEY5*2VF)ZFa?!y$~Pu{Px{5DB^a2>VI} znyh9_r&kGU%jMDqdNG?q0Tyha(;5v}Hv7}OC7&_DKwDI+l4!D;|4crUdF(4F6#9V` zi?CAZce1k}oiss@(UKsdj|-e$FgYf8{lD=7v!7JP TVw+*X00000NkvXXu0mjfWm1X4 literal 0 HcmV?d00001 diff --git a/thirsty/LICENSE b/thirsty/LICENSE new file mode 100644 index 0000000..5f2dd7f --- /dev/null +++ b/thirsty/LICENSE @@ -0,0 +1,505 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +(This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.) + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random + Hacker. + + {signature of Ty Coon}, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/thirsty/README.md b/thirsty/README.md new file mode 100644 index 0000000..213a505 --- /dev/null +++ b/thirsty/README.md @@ -0,0 +1,349 @@ +# Thirsty [thirsty] + +A Minetest mod that adds a "thirst" mechanic. + +Version: 0.10.2 + +## *License* +**Code** +LGPL 2.1 (see included LICENSE file) + +**Textures** +vessels_glass_bottle_full_cc_by_sa_3.png +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +modified from vessels_glass_bottle.png +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2016 Thomas-S + +thirsty_drop_100_24_cc0.png +.xcf +thirsty_drop_100_16_cc0.png +thirsty_wooden_bowl_cc0.png +.xcf +thirsty_bronze_canteen_cc0.png +.xcf +thirsty_steel_canteen_cc0.png +thirsty_amulet_moisture_cc0.png +.xcf +thirsty_amulet_hydration_cc0.png +.xcf +Public Domain CC0 1.0 Universal +Sirrobzeroone + +All other Images CC BY-SA 4.0 +(see http://creativecommons.org/licenses/by-sa/4.0/) + +**Sounds** +thirsty_breviceps_drink-drinking-liquid.ogg +https://freesound.org/people/Breviceps/sounds/445970/ +Public Domain CC0 1.0 Universal + +Report bugs or request help on the forum topic. + +# Description + +This is a mod for MineTest. It adds a thirst mechanic to the +game, similar to many hunger mods (but independent of them). +Players will slowly get thirstier over time, and will need to +drink or suffer damage. + +The point of this mod is not to make the game more realistic, +or harder. The point is to have another mechanic that rewards +preparation and infrastructure. Players will now have an incentive +to build their base next to water (or add some water to their base), +and/or take some water with them when mining or travelling. + +# Terminology: "Thirst" vs. "hydration" + +"Thirst" is the absence of "hydration" (a term suggested by +everamzah on the Minetest forums, thanks!). The overall mechanic +is still called "thirst", but the visible bar is that of +"hydration", meaning a full bar represents full hydration, not full +thirst. Players lose hydration (or "hydro points") over time, and +gain hydration when drinking. + +# Current behavior +## *Tier 0* + +stand in water (running or standing) to slowly drink. +You may not move during drinking (or you could cross an ocean without +getting thirsty). + +To register additional drinkable nodes use the function: + +**thirsty.register_hydrate_node(node_name,also_drinkable_with_cup,regen_rate_per_second)** + +**"node_name"** - registered node name +**"also_drinkable_with_cup"** - optional will default to true, if true + registers as per thirsty.register_drinkable_node() with max_hydration + equal to thirsty.config.start (default 20) +**"regen_rate_per_second"** - optional will default to 0.5 hydration + points per second standing still in the liquid. + +**Example** + + thirsty.register_hydrate_node("default:water_source") + +## *Tier 1* + +Use a container (e.g. from `vessels`) on water to instantly +fill your hydration. Craftable wooden bowl included. + +**NODES** +Configure nodes that can be drunk from using a cup/glass etc assuming this was +not done as part of Tier 0 or if you wish to override max_hydration to be more +than the default value (normally 20): + +**thirsty.register_drinkable_node(node_name,max_hydration)** +**"item_name"** registered node name +**"max_hydration"** optional will default to thirsty.config.start (default 20) + max hydration can be set above 20 to encourage use of drinking fountains or + hydration/drinking infrastructure. + +**Example** + + thirsty.register_drinkable_node("thirsty:drinking_fountain",30) + +**ITEMS** +Configure cups/glasses/bowls etc that can be used to scoop up water and then +drink from: + +**thirsty.augment_item_for_drinking(item_name, max_hydration)** +**"item_name"** registered item name +**"max_hydration"** optional will default to thirsty.config.start (default 20) + max hydration can be set above 20 to encourage use of items to drink with. + +This will overide/replace any existing code the item may have in it's +item_name.on_use. So not recommended for items with custom on_use +code already. +**Example** + + thirsty.augment_item_for_drinking('vessels:drinking_glass', 20) + +**Integrate thirsty into item custom on_use code** +thirsty.on_use() +**Example** + + minetest.register_craftitem("mod_name:empty_cup", { + description = S("Empty Cup"), + inventory_image = "mod_name_empty_cup.png", + liquids_pointable = true, + on_use = function(itemstack,player,pointed_thing) + local pos = pointed_thing.under + local node_name + if pointed_thing.type == "node" then + local node = minetest.get_node(pos) + node_name = node.name + end + + if thirsty.config.node_drinkable[node_name] then + thirsty.on_use() + else + -- do something else + end + end, + })* +## *Tier 2* + +Pre-made drinks and craftable canteens + +**PREMADE DRINKS** +Pre-made drinks can include anything the player may have had to craft +or cook and you wish the player to restore some hydration on_use: + +**thirsty.drink(player, amount, max_hydration, empty_vessel)** + +**"player"** player object see minetest player object +**"amount"** number of hydration points to restore +**"max hydration"** - optional will default to thirsty.config.start (default 20) + max hydration can be set above 20 to encourage use of items to drink with. +**"empty_vessel"** - optional empty vessel or item to return to player. + +**Example** + + minetest.register_craftitem("mod_name:cup_of_soup", { + description = S("Cup of Soup"), + inventory_image = "mod_name_cup_of_soup.png", + on_use = function(itemstack,player,pointed_thing) + thirsty.drink(player, 2, 20, "mod_name:empty_cup") + itemstack:take_item() + return itemstack + end, + }) + +**CANTEENS, FLASKS or BOTTLES** + Craftable items that you may wish to configure to hold a certain amount of + liquid hydration points. If used these items are converted to registered tools + rather than straight regsitered items with stack maximum of 1 so that current + full/empty value is displayed to the player (using wear). Thirsty includes a + Steel canteen with 40 hydration point capacity and a Bronze canteen with 60 + hydration point capacity. These can be refilled by clicking on any thirsty + registered hydrate_node. + +**thirsty.register_canteen(item_name,hydrate_capacity,max_hydration,on_use)** + +**"item_name"** Registered item name to convert to canteen type container +**"hydrate_capacity"** How many hydration points the container holds 1 full bar = 20 +**"max hydration"** Optional will default to thirsty.config.start (default 20) + max hydration can be set above 20 to encourage use of items to drink with. +**"on_use"** Optional default is true. Will set item.on_use function to; thirsty.on_use(), however if set to false on_use wont be over written. Mod registering item will need to manually include "thirsty.on_use()" inside its on_use item definition or canteen will not work note see Tier 1 - thirsty.on_use() + +**Example** + + thirsty.register_canteen("thirsty:bronze_canteen",60,25) + + + **COMPLEX CANTEENS, FLASKS or BOTTLES** + Using the above will mean items can no longer be stacked most importantly when they are empty. The below function will overcome this as it will register a full version + of the empty vessel as a tool. Naturally if you do not wish or need the empty containers to stack just use thirsty.register_canteen. Once a container is empty it will be replaced with the empty version. + +**thirsty.register_canteen_complex(item/node_name,hydrate_capacity,max_hydration,full_image)** + +**"item_name" or "node_name"** Registered item name to convert to canteen type tool container +**"hydrate_capacity"** How many hydration points the container holds 1 full bar = 20 +**"max hydration"** Optional will default to thirsty.config.start (default 20) + max hydration can be set above 20 to encourage use of items to drink with. + **"full_image"** The full image of the empty item used for inventory image and wield image + +**Example** + + thirsty.register_canteen_complex("vessels:glass_bottle",10,22,"vessels_glass_bottle_full.png") + + +## *Tier 3* + +Placeable drinking fountain / wash basin node: instantly +fills your hydration when used. + +Add the below to the on_rightclick function inside your node definition, +you'll also need to register the node as a drinkable node so you'll need +to also run - thirsty.register_drinkable_node(node_name). Recommended that +the node.drop for your node dosen't equal itself otherwise players will simply +use these as endless canteens/bottles. + +**thirsty.on_rightclick()** + + minetest.register_node('thirsty:drinking_fountain', { + description = 'Drinking fountain', + .... + def info + .... + drop = "default:stone 4", + on_rightclick = thirsty.on_rightclick(), + }) + + + minetest.register_craft({ + output = "thirsty:drinking_fountain", + recipe = { + { "default:stone", "bucket:bucket_water", "default:stone"}, + { "" , "default:stone" , ""}, + { "" , "default:stone" , ""} + }, + replacements = { + {"bucket:bucket_water", "bucket:bucket_empty"} + } + }) + + thirsty.register_drinkable_node("thirsty:drinking_fountain",30) + + +## *Tier 4* +Placeable fountain node(s) to fill the hydration of all +players within range. Placing more nodes increases the range. + +**thirsty.register_water_fountain(node_name)** + +**Example** + + thirsty.register_water_fountain("thirsty:water_fountain") + +**HOW TO USE WATER FOUNTAINS** *(Taken from forum posts)* +Water fountains are placeable, but these are not usable. Instead, +they constantly fill the hydration of all players within a 5 node +radius, as if they were standing in water. Water fountains need +actual water (source or flowing) near them to work. + +You can extend the radius of water fountains with "water extenders", +placeable nodes without any function of their own. + +Specifically, a water fountain will check all the nodes in a +5-node-high pyramid starting one node above itself. It will count all +water nodes (source or flowing), and count all water fountains / +water extenders. The smaller of these numbers is the "level" of the fountain, +up to 20 (in other words, you need an equal amount of water and fountain blocks). +Each level adds 5 more nodes to the working radius. A large fountain +should cover a city block or two. + +I'd recommend placing one water source above the "fountain" node, and +arranging extenders under it, but the plan is to allow many working designs. + + +## *Tier 5* + +Craftable trinkets/gadgets/amulets that constantly keep your +hydration filled when in your inventory, solving your thirst problem +once and for all. + +**thirsty.register_amulet_extractor(item_name,value)** + +**"item_name"** Registered item name +**"value"** Number of Hydration points extracted per half second (thirsty.config.tick_time) + *Note: Container must be avaliable in Inventory with avaliable space to add hydration points to.* + +**Example** + + thirsty.register_amulet_extractor("thirsty:amulet_of_moisture", 0.6) + +**Amulet of Moisture** - Absorbs moisture from the surronding environment places it into a canteen or other water holding item. Must be held in Inventory. + +**thirsty.register_amulet_supplier(item_name,value)** + +**"item_name"** Registered item name +**"value"** Number of Hydration points supplied to player per half second.(thirsty.config.tick_time) + *Note: Container must be avaliable in Inventory with avaliable space to add hydration points to.* + +**Example** + + thirsty.register_amulet_supplier("thirsty:amulet_of_hydration", 0.5) + +**Amulet of Hydration** - Feeds water from a Canteen or other water holding +item directly into the player to keep them always hydrated. Must be held in Inventory. + +The above two Amulets can be used in combination with each other plus a +canteen. However this does permenantly fill 3 inventory slots the delibrate +downside to offset the significant bonus. + +**Amulets of Thirst** - Three versions lesser,normal and greater each will slower the rate at which +a player becomes thirsty. Normal thirst factor is 1, however a "cursed" version could be created +which makes a player become thirsty faster. + + thirsty.register_amulet_thirst(item_name, thirst_factor) + +**"item_name"** Registered item name +**"thirst_factor"** Float value that represents the speed at which a player uses hydration points + +**Example** + + minetest.register_craftitem("thirsty:greater_amulet_thirst", { + description = "Greater Amulet of Thirst", + inventory_image = "thirsty_amulet_of_thirst_greater_cc0.png", + }) + + thirsty.register_amulet_thirst("thirsty:lesser_amulet_thirst",0.85) + +*Note: Included Amulets of Thirst have no craft recipes and are only avaliable as +*dungeon loot with more powerful versions only found in deeper dungeons. + + +## *Additional Functions* + +*thirsty.get_hydro(player) : returns the current hydration of a player* + +"player" refers to a player object, i.e. with a get_player_name() method. + +Future plans +------------ +Continued tidy and updating + +Dependencies +------------ +* default (optional but needed for included components) +* bucket (optional but needed for some included components) +* hudbars (optional): https://forum.minetest.net/viewtopic.php?f=11&t=11153 +* vessels (optional): https://forum.minetest.net/viewtopic.php?id=2574 \ No newline at end of file diff --git a/thirsty/components.lua b/thirsty/components.lua new file mode 100644 index 0000000..180cdea --- /dev/null +++ b/thirsty/components.lua @@ -0,0 +1,324 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [components] -- +------------------------------------------------------------ +-- See init.lua for license -- +------------------------------------------------------------ + +local E = thirsty.ext_nodes_items + +-------------------------- +-- Tier 0 Hydrate Nodes -- +-------------------------- +if minetest.registered_items[E.water_source] then + thirsty.register_hydrate_node(E.water_source) +end + +if minetest.registered_items[E.water_source_f] then + thirsty.register_hydrate_node(E.water_source_f) +end + +if minetest.registered_items[E.water_source_riv] then + thirsty.register_hydrate_node(E.water_source_riv) +end + +if minetest.registered_items[E.water_source_riv_f] then + thirsty.register_hydrate_node(E.water_source_riv_f) +end + + +------------------------------------------- +-- Tier 1 Drink from nodes using cup etc -- +------------------------------------------- + -- Nodes -- + -- see drinking fountain + + -- Items -- + if minetest.registered_items[E.drinking_glass] and thirsty.config.register_vessels then + -- add "drinking" to vessels + thirsty.augment_item_for_drinking(E.drinking_glass, 20) + end + + if thirsty.config.register_bowl and not minetest.registered_items[E.wood_bowl] then + -- our own simple wooden bowl + minetest.register_craftitem('thirsty:wooden_bowl', { + description = "Wooden bowl", + inventory_image = "thirsty_bowl_cc0.png", + liquids_pointable = true, + }) + + minetest.register_craft({ + output = "thirsty:wooden_bowl", + recipe = { + {E.group_wood, "", E.group_wood}, + { "",E.group_wood, ""} + } + }) + + thirsty.augment_item_for_drinking("thirsty:wooden_bowl", 22) + + -- modify farming redo wooden bowl to be usable. + elseif thirsty.config.register_bowl and minetest.registered_items[E.wood_bowl] then + + thirsty.augment_item_for_drinking(E.wood_bowl, 22) + + end + + +--[[ + +Tier 2 Hydro Containers + +Defines canteens (currently two types, with different capacities), +tools which store hydro. They use wear to show their content +level in their durability bar; they do not disappear when used up. + +Wear corresponds to hydro level as follows: +- a wear of 0 shows no durability bar -> empty (initial state) +- a wear of 1 shows a full durability bar -> full +- a wear of 65535 shows an empty durability bar -> empty + +]] + +if thirsty.config.register_vessels and minetest.registered_items[E.glass_bottle] then + thirsty.register_canteen_complex(E.glass_bottle,10,22,E.glass_bottle_f) +end + +if thirsty.config.register_vessels and minetest.registered_items[E.steel_bottle] then + thirsty.register_canteen_complex(E.steel_bottle,20,24) +end + + +if thirsty.config.register_canteens and + minetest.registered_items[E.steel_ingot] and + minetest.registered_items[E.bronze_ingot] then + + minetest.register_craftitem('thirsty:steel_canteen', { + description = 'Steel canteen', + inventory_image = "thirsty_steel_canteen_cc0.png", + }) + + minetest.register_craftitem("thirsty:bronze_canteen", { + description = "Bronze canteen", + inventory_image = "thirsty_bronze_canteen_cc0.png", + }) + + thirsty.register_canteen("thirsty:steel_canteen",40,25) + thirsty.register_canteen("thirsty:bronze_canteen",60,25) + + minetest.register_craft({ + output = "thirsty:steel_canteen", + recipe = { + {E.group_wood, ""}, + {E.steel_ingot,E.steel_ingot}, + {E.steel_ingot,E.steel_ingot} + } + }) + minetest.register_craft({ + output = "thirsty:bronze_canteen", + recipe = { + {E.group_wood, ""}, + {E.bronze_ingot,E.bronze_ingot}, + {E.bronze_ingot,E.bronze_ingot} + } + }) + +end + + +------------------------------- +-- Tier 3 Drinking Fountain -- +------------------------------- + +if thirsty.config.register_drinking_fountain and + minetest.registered_items[E.stone] and + minetest.registered_items[E.bucket_water]then + + minetest.register_node('thirsty:drinking_fountain', { + description = 'Drinking fountain', + drawtype = 'nodebox', + drop = E.stone.." 4", + tiles = { + -- top, bottom, right, left, front, back + 'thirsty_drinkfount_top.png', + 'thirsty_drinkfount_bottom.png', + 'thirsty_drinkfount_side.png', + 'thirsty_drinkfount_side.png', + 'thirsty_drinkfount_side.png', + 'thirsty_drinkfount_side.png', + }, + paramtype = 'light', + groups = { cracky = 2 }, + node_box = { + type = "fixed", + fixed = { + { -3/16, -8/16, -3/16, 3/16, 3/16, 3/16 }, + { -8/16, 3/16, -8/16, 8/16, 6/16, 8/16 }, + { -8/16, 6/16, -8/16, 8/16, 8/16, -6/16 }, + { -8/16, 6/16, 6/16, 8/16, 8/16, 8/16 }, + { -8/16, 6/16, -6/16, -6/16, 8/16, 6/16 }, + { 6/16, 6/16, -6/16, 8/16, 8/16, 6/16 }, + }, + }, + selection_box = { + type = "regular", + }, + collision_box = { + type = "regular", + }, + on_rightclick = thirsty.on_rightclick(nil), + }) + + minetest.register_craft({ + output = "thirsty:drinking_fountain", + recipe = { + {E.stone,E.bucket_water,E.stone}, + { "" ,E.stone , ""}, + { "" ,E.stone , ""} + }, + replacements = { + {E.bucket_water,E.bucket_empty} + } + }) + + thirsty.register_drinkable_node("thirsty:drinking_fountain",30) + +end + + +---------------------------------------------- +-- Tier 4: Water fountains, Water extenders -- +---------------------------------------------- + +if thirsty.config.register_fountains and + minetest.registered_items[E.copper_ingot] and + minetest.registered_items[E.mese_crystal] and + minetest.registered_items[E.bucket_water] then + + minetest.register_node('thirsty:water_fountain', { + description = 'Water fountain', + tiles = { + -- top, bottom, right, left, front, back + 'thirsty_waterfountain_top.png', + 'thirsty_waterfountain_top.png', + 'thirsty_waterfountain_side.png', + 'thirsty_waterfountain_side.png', + 'thirsty_waterfountain_side.png', + 'thirsty_waterfountain_side.png', + }, + paramtype = 'light', + groups = { cracky = 2 }, + }) + + minetest.register_node('thirsty:water_extender', { + description = 'Water fountain extender', + tiles = { + 'thirsty_waterextender_top.png', + 'thirsty_waterextender_top.png', + 'thirsty_waterextender_side.png', + 'thirsty_waterextender_side.png', + 'thirsty_waterextender_side.png', + 'thirsty_waterextender_side.png', + }, + paramtype = 'light', + groups = { cracky = 2 }, + }) + + minetest.register_craft({ + output = "thirsty:water_fountain", + recipe = { + {E.copper_ingot,E.bucket_water,E.copper_ingot}, + {"" ,E.copper_ingot, ""}, + {E.copper_ingot,E.mese_crystal,E.copper_ingot} + } + }) + minetest.register_craft({ + output = "thirsty:water_extender", + recipe = { + { "" ,E.bucket_water, ""}, + { "" ,E.copper_ingot, ""}, + {E.copper_ingot,E.mese_crystal,E.copper_ingot} + } + }) + + thirsty.register_water_fountain("thirsty:water_fountain") + thirsty.register_water_fountain("thirsty:water_extender") + + minetest.register_abm({ + nodenames = {"thirsty:water_fountain"}, + interval = 2, + chance = 5, + action = thirsty.fountain_abm, + }) + +end + + +--[[ +Tier 5 + +These amulets don't do much; the actual code is above, where +they are searched for in player's inventories + +]] + +if thirsty.config.register_amulets and + minetest.registered_items[E.diamond] and + minetest.registered_items[E.mese_crystal] and + minetest.registered_items[E.bucket_water] then + + minetest.register_craftitem("thirsty:amulet_of_hydration", { + description = "Amulet of Hydration", + inventory_image = "thirsty_amulet_hydration_cc0.png", + }) + minetest.register_craft({ + output = "thirsty:amulet_of_hydration", + recipe = { + {E.diamond ,E.mese_crystal,E.diamond}, + {E.mese_crystal,E.bucket_water,E.mese_crystal}, + {E.diamond ,E.mese_crystal,E.diamond} + } + }) + + thirsty.register_amulet_supplier("thirsty:amulet_of_hydration", 0.5) + + minetest.register_craftitem("thirsty:amulet_of_moisture", { + description = "Amulet of Moisture", + inventory_image = "thirsty_amulet_moisture_cc0.png", + }) + minetest.register_craft({ + output = "thirsty:amulet_of_moisture", + recipe = { + {E.mese_crystal,E.diamond ,E.mese_crystal}, + {E.diamond ,E.bucket_water,E.diamond }, + {E.mese_crystal,E.diamond ,E.mese_crystal} + } + }) + + thirsty.register_amulet_extractor("thirsty:amulet_of_moisture", 0.6) + + minetest.register_craftitem("thirsty:lesser_amulet_thirst", { + description = "Lesser Amulet of Thirst", + inventory_image = "thirsty_amulet_of_thirst_lesser_cc0.png", + }) + + minetest.register_craftitem("thirsty:amulet_thirst", { + description = "Amulet of Thirst", + inventory_image = "thirsty_amulet_of_thirst_cc0.png", + }) + + minetest.register_craftitem("thirsty:greater_amulet_thirst", { + description = "Greater Amulet of Thirst", + inventory_image = "thirsty_amulet_of_thirst_greater_cc0.png", + }) + + thirsty.register_amulet_thirst("thirsty:lesser_amulet_thirst",0.85) + thirsty.register_amulet_thirst("thirsty:amulet_thirst",0.70) + thirsty.register_amulet_thirst("thirsty:greater_amulet_thirst",0.55) + +end diff --git a/thirsty/components_external_nodes_items.lua b/thirsty/components_external_nodes_items.lua new file mode 100644 index 0000000..e6b6c54 --- /dev/null +++ b/thirsty/components_external_nodes_items.lua @@ -0,0 +1,49 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod external nodes items -- +------------------------------------------------------------ +-- See init.lua for license -- +------------------------------------------------------------ + +--[[ +These are nodes and items required to make canteens and +fountains. Simply change the name here to change the reference +across the whole mod. +]]-- +local E = thirsty.ext_nodes_items + +-- item and node mod aliases, change these as needed. +-- if item dosen't exist as either Ingredient or Augumented +-- item it wont register. + +-- Basic Water, change here or register +-- using thirsty.register_hydrate_node() +-- and leave these unchanged. +E.water_source = "default:water_source" +E.water_source_f = "default:water_flowing" +E.water_source_riv = "default:river_water_source" +E.water_source_riv_f = "default:river_water_flowing" + +-- Ingredients +E.group_wood = "group:wood" +E.stone = "default:stone" +E.steel_ingot = "default:steel_ingot" +E.bronze_ingot = "default:bronze_ingot" +E.copper_ingot = "default:copper_ingot" +E.mese_crystal = "default:mese_crystal" +E.diamond = "default:diamond" +E.bucket_water = "bucket:bucket_water" +E.bucket_empty = "bucket:bucket_empty" + +-- Augumented Items +E.drinking_glass = "vessels:drinking_glass" +E.glass_bottle = "vessels:glass_bottle" -- looks like glass potion bottle +E.glass_bottle_f = "vessels_glass_bottle_full_cc_by_sa_3.png" -- image for registering full version of above +E.steel_bottle = "vessels:steel_bottle" +E.wood_bowl = "farming:bowl" +E.glass_milk = "mobs:glass_milk" -- note needs E.drinking_glass for empty return item diff --git a/thirsty/functions.lua b/thirsty/functions.lua new file mode 100644 index 0000000..69b044e --- /dev/null +++ b/thirsty/functions.lua @@ -0,0 +1,583 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [functions] -- +------------------------------------------------------------ +-- See init.lua for license -- +------------------------------------------------------------ + +-------------------------- +-- Tier 0 API Functions -- +-------------------------- +-- regen_from_node is a table defining, for each node type, the +-- amount of hydro per second a player drinks by standing in it. +-- Default is 0.5 of a hydration per second +function thirsty.register_hydrate_node(node_name,drink_cup,regen) + local drink_cup = drink_cup or true + local regen = regen or 0.5 + + thirsty.config.regen_from_node[node_name] = regen + thirsty.config.fountain_type[node_name] = "w" + + if drink_cup then + thirsty.register_drinkable_node(node_name) + end +end + +-------------------------- +-- Tier 1 API Functions -- +-------------------------- +-- node_drinkable: which nodes can we drink from, given a +-- container (a cup, a bowl etc.) +function thirsty.register_drinkable_node(node_name,max_hydrate) + local max_hydrate = max_hydrate or nil + + thirsty.config.node_drinkable[node_name] = true + + if max_hydrate then + thirsty.config.drink_from_node[node_name] = max_hydrate + end + +end + +function thirsty.on_use( old_on_use ) + return function(itemstack, player, pointed_thing) + local node = nil + if pointed_thing and pointed_thing.type == 'node' then + node = minetest.get_node(pointed_thing.under) + end + + thirsty.drink_handler(player, itemstack, node) + + -- call original on_use, if provided + if old_on_use ~= nil then + return old_on_use(itemstack, player, pointed_thing) + else + return itemstack + end + end +end + +function thirsty.augment_item_for_drinking( itemname, level ) + local new_definition = {} + local level = level or thirsty.config.start + -- we need to be able to point at the water + new_definition.liquids_pointable = true + -- call closure generator with original on_use handler + new_definition.on_use = thirsty.on_use( + minetest.registered_items[itemname].on_use + ) + -- overwrite the node definition with almost the original + minetest.override_item(itemname, new_definition) + + -- add configuration settings + thirsty.config.drink_from_container[itemname] = level +end + + +-------------------------- +-- Tier 2 API Functions -- +-------------------------- +function thirsty.drink(player, value, max_hyd, empty_vessel) + local max_hyd = max_hyd or 20 + local value = value or 2 + local pmeta = player:get_meta() + local hydro = pmeta:get_float("thirsty_hydro") + -- test whether we're not *above* max_hyd; + -- this function should not remove any overhydration + if hydro < max_hyd then + hydro = math.min(hydro + value, max_hyd) + --print("Drinking by "..value.." to "..hydro) + pmeta:set_float("thirsty_hydro", hydro) + minetest.sound_play("thirsty_breviceps_drink-drinking-liquid", { to_player = player:get_player_name(), gain = 2.0, }) + + if empty_vessel then + player:get_inventory():add_item("main", empty_vessel.." 1") + end + + return true + end + return false +end + +function thirsty.register_canteen(item_name,hydrate_capacity,max_hydrate,on_use) + + local on_use = on_use or true + local max_hydrate = max_hydrate or thirsty.config.start + + thirsty.config.container_capacity[item_name] = hydrate_capacity + thirsty.config.drink_from_container[item_name] = max_hydrate + + local def = table.copy(minetest.registered_items[item_name]) + def.liquids_pointable = true + def.stack_max = 1 + def.type = "tool" + + if on_use then + def.on_use = thirsty.on_use(nil) + end + + minetest.register_tool(":"..item_name, def) +end + +function thirsty.register_canteen_complex(item_name,hydrate_capacity,max_hydrate,full_image) + local full_item_name = item_name.."_full" + local max_hydrate = max_hydrate or thirsty.config.start + + -- register new full version of item into thirsty tables and as tool. + thirsty.config.container_capacity[full_item_name] = hydrate_capacity + thirsty.config.drink_from_container[full_item_name] = max_hydrate + + local def_f = table.copy(minetest.registered_items[item_name]) + def_f.inventory_image = full_image or def_f.inventory_image + def_f.wield_image = full_image or def_f.inventory_image + def_f.liquids_pointable = true + def_f.stack_max = 1 + def_f.type = "tool" + def_f.description = "Full "..def_f.description + def_f.on_use = thirsty.on_use(nil) + def_f.thirsty_empty = item_name + + minetest.register_tool(":"..full_item_name, def_f) + + -- modify empty_vessel registration + local def_e = table.copy(minetest.registered_items[item_name]) + + def_e.on_use = thirsty.on_use_empty() + def_e.liquids_pointable = true + def_e.name = nil + def_e.type = nil + minetest.override_item(item_name, def_e) +end + +-- note not offically exposed to API yet, use with caution may change +function thirsty.on_use_empty() + return function(itemstack, player, pointed_thing) + local node = nil + + if pointed_thing and pointed_thing.type == 'node' then + node = minetest.get_node(pointed_thing.under) + end + + + if node and thirsty.config.node_drinkable[node.name] then + local new_stack = {name = itemstack:get_name().."_full", count=1, wear=1, metadata=""} + player:get_inventory():add_item("main", new_stack) + itemstack:take_item() + return itemstack + end + end +end + + +-------------------------- +-- Tier 3 API Functions -- +-------------------------- +function thirsty.on_rightclick( old_on_rightclick ) + return function(pos, node, player, itemstack, pointed_thing) + + thirsty.drink_handler(player, itemstack, node) + + -- call original on_rightclick, if provided + if old_on_rightclick ~= nil then + return old_on_rightclick(pos, node, player, itemstack, pointed_thing) + else + return itemstack + end + end +end + + +-------------------------- +-- Tier 4 API Functions -- +-------------------------- +function thirsty.register_water_fountain(node_name) + thirsty.config.fountain_type[node_name] = "f" +end + + +-------------------------- +-- Tier 5 API Functions -- +-------------------------- +function thirsty.register_amulet_extractor(item_name,value) + thirsty.config.extraction_for_item[item_name] = value +end + + +function thirsty.register_amulet_supplier(item_name,value) + thirsty.config.injection_for_item[item_name] = value +end + +function thirsty.register_amulet_thirst(item_name,value) + thirsty.config.thirst_adjust_item[item_name] = value +end + +function thirsty.get_thirst_factor(player) + local name = player:get_player_name() + local pmeta = player:get_meta() + local pl = minetest.deserialize(pmeta:get_string("thirsty_values")) + return pl.thirst_factor +end + +function thirsty.set_thirst_factor(player, factor) + local name = player:get_player_name() + local pmeta = player:get_meta() + local pl = minetest.deserialize(pmeta:get_string("thirsty_values")) + pl.thirst_factor = factor + pmeta:set_string("thirsty_values",minetest.serialize(pl)) +end + + +------------------------- +-- Other API Functions -- +------------------------- +function thirsty.get_hydro(player) + local pmeta = player:get_meta() + local hydro = pmeta:get_float("thirsty_hydro") + return hydro +end + + +---------------------------- +-- Mod Internal Functions -- +---------------------------- +local damage_enabled = minetest.settings:get_bool("enable_damage") + + +function thirsty.on_joinplayer(player) + local name = player:get_player_name() + local pmeta = player:get_meta() + + -- setup initial thirst player meta value if not present + if pmeta:get_float("thirsty_hydro") == 0 then + pmeta:set_float("thirsty_hydro", thirsty.config.start) + end + + -- default entry for joining players + if pmeta:get_string("thirsty_values") == "" then + local pos = player:get_pos() + pmeta:set_string("thirsty_values", minetest.serialize({ + last_pos = math.floor(pos.x) .. ':' .. math.floor(pos.z), + time_in_pos = 0.0, + pending_dmg = 0.0, + thirst_factor = 1.0 + })) + end + + thirsty.hud_init(player) +end + + +function thirsty.on_dieplayer(player) + local name = player:get_player_name() + local pos = player:get_pos() + local pmeta = player:get_meta() + + pmeta:set_float("thirsty_hydro", thirsty.config.start) + pmeta:set_string("thirsty_values", minetest.serialize({ + last_pos = math.floor(pos.x) .. ':' .. math.floor(pos.z), + time_in_pos = 0.0, + pending_dmg = 0.0, + thirst_factor = 1.0 + })) +end + + +function thirsty.main_loop(dtime) + -- get thirsty + thirsty.time_next_tick = thirsty.time_next_tick - dtime + while thirsty.time_next_tick < 0.0 do + -- time for thirst + thirsty.time_next_tick = thirsty.time_next_tick + thirsty.config.tick_time + for _,player in ipairs(minetest.get_connected_players()) do + + -- dead players don't get thirsty, or full for that matter :-P + if player:get_hp() <= 0 then + break + end + + local name = player:get_player_name() + local pos = player:get_pos() + local pmeta = player:get_meta() + local hydro = pmeta:get_float("thirsty_hydro") + local pl = minetest.deserialize(pmeta:get_string("thirsty_values")) + + -- how long have we been standing "here"? + -- (the node coordinates in X and Z should be enough) + local pos_hash = math.floor(pos.x) .. ':' .. math.floor(pos.z) + if pl.last_pos == pos_hash then + pl.time_in_pos = pl.time_in_pos + thirsty.config.tick_time + else + -- you moved! + pl.last_pos = pos_hash + pl.time_in_pos = 0.0 + end + local pl_standing = pl.time_in_pos > thirsty.config.stand_still_for_drink + local pl_afk = pl.time_in_pos > thirsty.config.stand_still_for_afk + --print("Standing: " .. (pl_standing and 'true' or 'false' ) .. ", AFK: " .. (pl_afk and 'true' or 'false')) + + pos.y = pos.y + 0.1 + local node = minetest.get_node(pos) + local drink_per_second = thirsty.config.regen_from_node[node.name] or 0 + + -- fountaining (uses pos, slight changes ok) + for k, fountain in pairs(thirsty.fountains) do + local dx = fountain.pos.x - pos.x + local dy = fountain.pos.y - pos.y + local dz = fountain.pos.z - pos.z + local dist2 = dx * dx + dy * dy + dz * dz + local fdist = fountain.level * thirsty.config.fountain_distance_per_level -- max 100 nodes radius + --print (string.format("Distance from %s (%d): %f out of %f", k, fountain.level, math.sqrt(dist2), fdist )) + if dist2 < fdist * fdist then + -- in range, drink as if standing (still) in water + drink_per_second = math.max(thirsty.config.regen_from_fountain or 0, drink_per_second) + pl_standing = true + break -- no need to check the other fountains + end + end + + -- amulets + -- TODO: I *guess* we need to optimize this, but I haven't + -- measured it yet. No premature optimizations! + local pl_inv = player:get_inventory() + local extractor_max = 0.0 + local injector_max = 0.0 + local amulet_thirst = false + local container_not_full = nil + local container_not_empty = nil + local inv_main = player:get_inventory():get_list('main') + + for i, itemstack in ipairs(inv_main) do + local name = itemstack:get_name() + -- Amulets Hydration/Moisture + local injector_this = thirsty.config.injection_for_item[name] + if injector_this and injector_this > injector_max then + injector_max = injector_this + end + + local extractor_this = thirsty.config.extraction_for_item[name] + if extractor_this and extractor_this > extractor_max then + extractor_max = extractor_this + end + + if thirsty.config.container_capacity[name] then + local wear = itemstack:get_wear() + -- can be both! + if wear == 0 or wear > 1 then + container_not_full = { i, itemstack } + end + if wear > 0 and wear < 65534 then + container_not_empty = { i, itemstack } + end + end + -- Amulets of Thirst + local is_thirst_amulet = thirsty.config.thirst_adjust_item[name] + if is_thirst_amulet then + amulet_thirst = true + pl.thirst_factor = thirsty.config.thirst_adjust_item[name] + end + end + + if amulet_thirst ~= true and pl.thirst_factor ~= 1.0 then + pl.thirst_factor = 1.0 + end + + if extractor_max > 0.0 and container_not_full then + local i = container_not_full[1] + local itemstack = container_not_full[2] + local capacity = thirsty.config.container_capacity[itemstack:get_name()] + local wear = itemstack:get_wear() + if wear == 0 then wear = 65535.0 end + local drink = extractor_max * thirsty.config.tick_time + local drinkwear = drink / capacity * 65535.0 + wear = wear - drinkwear + if wear < 1 then wear = 1 end + itemstack:set_wear(wear) + player:get_inventory():set_stack("main", i, itemstack) + end + + if injector_max > 0.0 and container_not_empty then + local i = container_not_empty[1] + local itemstack = container_not_empty[2] + local capacity = thirsty.config.container_capacity[itemstack:get_name()] + local wear = itemstack:get_wear() + if wear == 0 then wear = 65535.0 end + local drink = injector_max * thirsty.config.tick_time + local drink_missing = 20 - hydro + drink = math.max(math.min(drink, drink_missing), 0) + local drinkwear = drink / capacity * 65535.0 + wear = wear + drinkwear + if wear > 65534 then wear = 65534 end + itemstack:set_wear(wear) + thirsty.drink(player, drink, 20) + hydro = pmeta:get_float("thirsty_hydro") + player:get_inventory():set_stack("main", i, itemstack) + end + + + if drink_per_second > 0 and pl_standing then + -- Drinking from the ground won't give you more than max + thirsty.drink(player, (drink_per_second * thirsty.config.tick_time)*2, 20) + pl.time_in_pos = 0.0 + --print("Raising hydration by "..(drink_per_second*thirsty.config.tick_time).." to "..PPA.get_value(player, 'thirsty_hydro')) + else + if not pl_afk then + -- only get thirsty if not AFK + local amount = thirsty.config.thirst_per_second * thirsty.config.tick_time * pl.thirst_factor + pmeta:set_float("thirsty_hydro",(hydro - amount)) + + hydro = pmeta:get_float("thirsty_hydro") + --print("Lowering hydration by "..amount.." to "..hydro) + end + end + + + -- should we only update the hud on an actual change? + -- minetest.debug(player:get_player_name().." "..hydro) + thirsty.hud_update(player, hydro) + + -- damage, if enabled + if damage_enabled then + -- maybe not the best way to do this, but it does mean + -- we can do anything with one tick loop + if hydro <= 0.0 and not pl_afk then + pl.pending_dmg = pl.pending_dmg + thirsty.config.damage_per_second * thirsty.config.tick_time + --print("Pending damage at " .. pl.pending_dmg) + if pl.pending_dmg > 1.0 then + local dmg = math.floor(pl.pending_dmg) + pl.pending_dmg = pl.pending_dmg - dmg + player:set_hp( player:get_hp() - dmg ) + end + else + -- forget any pending damage when not thirsty + pl.pending_dmg = 0.0 + end + end + pmeta:set_string("thirsty_values",minetest.serialize(pl)) + end -- for players + + -- check fountains for expiration + for k, fountain in pairs(thirsty.fountains) do + fountain.time_until_check = fountain.time_until_check - thirsty.config.tick_time + if fountain.time_until_check <= 0 then + -- remove fountain, the abm will set it again + --print("Removing fountain at " .. k) + thirsty.fountains[k] = nil + end + end + + end +end + + +function thirsty.drink_handler(player, itemstack, node) + local pmeta = player:get_meta() + local hydro = pmeta:get_float("thirsty_hydro") + local pl = minetest.deserialize(pmeta:get_string("thirsty_values")) + local old_hydro = hydro + + -- selectors, always true, to make the following code easier + local item_name = itemstack and itemstack:get_name() or ':' + local node_name = node and node.name or ':' + + if thirsty.config.node_drinkable[node_name] then + -- we found something to drink! + local cont_level = thirsty.config.drink_from_container[item_name] or 0 + local node_level = thirsty.config.drink_from_node[node_name] or 0 + -- drink until level + local level = math.max(cont_level, node_level) + --print("Drinking to level " .. level) + thirsty.drink(player, level, level) + + -- fill container, if applicable + if thirsty.config.container_capacity[item_name] then + --print("Filling a " .. item_name .. " to " .. thirsty.config.container_capacity[item_name]) + itemstack:set_wear(1) -- "looks full" + end + + elseif thirsty.config.container_capacity[item_name] then + -- drinking from a container + if itemstack:get_wear() ~= 0 then + local capacity = thirsty.config.container_capacity[item_name] + local hydro_missing = 20 - hydro; + if hydro_missing > 0 then + local wear_missing = hydro_missing / capacity * 65535.0; + local wear = itemstack:get_wear() + local new_wear = math.ceil(math.max(wear + wear_missing, 1)) + if (new_wear > 65534) then + wear_missing = 65534 - wear + new_wear = 65534 + end + + -- deal with full/empty vessels, when empty remove + -- tool version and supply empty name to thirsty.drink + -- so player recieves empty version back + local empty_vessel_name + + if new_wear >= 65534 then + + if minetest.registered_items[item_name].thirsty_empty then + itemstack:take_item(1) + empty_vessel_name = minetest.registered_items[item_name].thirsty_empty + else + itemstack:set_wear(new_wear) + end + -- end full/empty vessel code block + else + itemstack:set_wear(new_wear) + end + + if wear_missing > 0 then -- rounding glitches? + thirsty.drink(player, wear_missing * capacity / 65535.0, 20, empty_vessel_name) + hydro = pmeta:get_float("thirsty_hydro") + end + end + end + end + + -- update HUD if value changed + if hydro ~= old_hydro then + thirsty.hud_update(player, hydro) + end +end + + +function thirsty.fountain_abm(pos, node) + local fountain_count = 0 + local water_count = 0 + local total_count = 0 + for y = 0, thirsty.config.fountain_height do + for x = -y, y do + for z = -y, y do + local n = minetest.get_node({ + x = pos.x + x, + y = pos.y - y + 1, -- start one *above* the fountain + z = pos.z + z + }) + if n then + --print(string.format("%s at %d:%d:%d", n.name, pos.x+x, pos.y-y+1, pos.z+z)) + total_count = total_count + 1 + local type = thirsty.config.fountain_type[n.name] or '' + if type == 'f' then + fountain_count = fountain_count + 1 + elseif type == 'w' then + water_count = water_count + 1 + end + end + end + end + end + local level = math.min(thirsty.config.fountain_max_level, math.min(fountain_count, water_count)) + --print(string.format("Fountain (%d): %d + %d / %d", level, fountain_count, water_count, total_count)) + thirsty.fountains[string.format("%d:%d:%d", pos.x, pos.y, pos.z)] = { + pos = { x=pos.x, y=pos.y, z=pos.z }, + level = level, + -- time until check is 20 seconds, or twice the average + -- time until the abm ticks again. Should be enough. + time_until_check = 20, + } +end diff --git a/thirsty/hud.lua b/thirsty/hud.lua new file mode 100644 index 0000000..00e75f3 --- /dev/null +++ b/thirsty/hud.lua @@ -0,0 +1,75 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- HUD definitions for Thirsty -- +------------------------------------------------------------ +-- See init.lua for license -- +------------------------------------------------------------ + +--[[ +Optionally from one of the supported mods + +Any hud needs to define the following functions: + +- thirsty.hud_init(player) + Initialize the HUD for a new player. + +- thirsty.hud_update(player, value) + Display the new value "value" for the given player. "value" is + a floating point number, not necessarily bounded. You can use the + "thirsty.hud_clamp(value)" function to get an integer between 0 + and 20. + +]]-- + +function thirsty.hud_clamp(value) + if value < 0 then + return 0 + elseif value > 20 then + return 20 + else + return math.ceil(value) + end +end + +if minetest.get_modpath("hudbars") then + hb.register_hudbar('thirst', 0xffffff, "Hydration", { + bar = 'thirsty_hudbars_bar.png', + icon = 'thirsty_drop_100_24_cc0.png' + }, 20, 20, false) + function thirsty.hud_init(player) + local pmeta = player:get_meta() + hb.init_hudbar(player, 'thirst', + thirsty.hud_clamp(pmeta:get_float("thirsty_hydro")), + 20, false) + end + function thirsty.hud_update(player, value) + hb.change_hudbar(player, 'thirst', thirsty.hud_clamp(value), 20) + end +else + -- 'builtin' hud + function thirsty.hud_init(player) + -- above breath bar, for now + local name = player:get_player_name() + local pmeta = player:get_meta() + + thirsty_hud = player:hud_add({ + hud_elem_type = "statbar", + position = { x=0.5, y=1 }, + text = "thirsty_drop_100_24_cc0.png", + number = thirsty.hud_clamp(pmeta:get_float("thirsty_hydro")), + direction = 0, + size = { x=24, y=24 }, + offset = { x=25, y=-(48+24+16+32)}, + }) + end + function thirsty.hud_update(player, value) + local name = player:get_player_name() + local hud_id = thirsty_hud + player:hud_change(hud_id, 'number', thirsty.hud_clamp(value)) + end +end diff --git a/thirsty/init.lua b/thirsty/init.lua new file mode 100644 index 0000000..03f5598 --- /dev/null +++ b/thirsty/init.lua @@ -0,0 +1,168 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [thirsty] -- +------------------------------------------------------------ +-- A mod that adds a "thirst" mechanic, similar to hunger -- +-- Copyright (C) 2015 Ben Deutsch -- +------------------------------------------------------------ +-- name idea thirsty_revive or thirsty_renew +--------------- +--[[ License -- +--------------- + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +USA + +--Media/Images-- +See Readme.MD - Mix of: +CC BY-SA 3.0 +CC BY-SA 4.0 +CC0 1.0 Universal + +------------------------------------------- +-- Terminology: "Thirst" vs. "hydration" -- +------------------------------------------- + +"Thirst" is the absence of "hydration" (a term suggested by +everamzah on the Minetest forums, thanks!). The overall mechanic +is still called "thirst", but the visible bar is that of +"hydration", filled with "hydro points". +]]-- + +thirsty = {} + +thirsty.version = 0.103 + +-- simple toboolean function that handles nil +thirsty.tobool = function(value) + if value == nil then + return nil + elseif value == "true" or value == 1 then + return true + else + return false + end +end + + -- Configuration variables +thirsty.config = { + -- configuration in Settings>>Mods>>Thirsty + -- Best to not change defaults here + -- [General] + tick_time = minetest.settings:get("thirsty_tick_time") or 0.5, + start = minetest.settings:get("thirsty_starting_value") or 20, + thirst_per_second = minetest.settings:get("thirst_per_second") or 1.0 / 30, + damage_per_second = minetest.settings:get("damage_per_second") or 1.0 / 10.0, + stand_still_for_drink = minetest.settings:get("stand_still_for_drink") or 1.0, + stand_still_for_afk = minetest.settings:get("stand_still_for_afk") or 120.0, + + -- [Water Fountain] + regen_from_fountain = minetest.settings:get("regen_from_fountain") or 0.5, + fountain_height = minetest.settings:get("fountain_height") or 4, + fountain_max_level = minetest.settings:get("fountain_max_level") or 20, + fountain_distance_per_level = minetest.settings:get("fountain_distance_per_level") or 5, + + -- [Thirsty Mod Items] + register_bowl = thirsty.tobool(minetest.settings:get("register_bowl")) or true, + register_canteens = thirsty.tobool(minetest.settings:get("register_canteens")) or true, + register_drinking_fountain = thirsty.tobool(minetest.settings:get("register_drinking")) or true, + register_fountains = thirsty.tobool(minetest.settings:get("register_fountains")) or true, + register_amulets = thirsty.tobool(minetest.settings:get("register_amulets")) or true, + + -- [Other Mods] + register_vessels = thirsty.tobool(minetest.settings:get("register_vessels")) or true, + + -- [Node/Item Tables] Do not change names without code updates. + -- Use API functions to register to these tables + regen_from_node = {}, + node_drinkable = {}, + drink_from_container = {}, + container_capacity = {}, + drink_from_node = {}, + fountain_type = {}, + extraction_for_item = {}, + injection_for_item = {}, + thirst_adjust_item = {} + } + + -- water fountains +thirsty.fountains = { + --[[ + x:y:z = { + pos = { x=x, y=y, z=z }, + level = 4, + time_until_check = 20, + -- something about times + } + ]] + } + +thirsty.ext_nodes_items = { + --[[ acts as an internal + mod aliasing for ingredients + used in Canteen/Fountain recipes. + to change edit: + components_external_nodes_items.lua + + steel_ingot = default:steel_ingot + ]] + } + + -- general settings +thirsty.time_next_tick = 0.0 + + +local M = thirsty +local C = M.config +local modpath = minetest.get_modpath("thirsty") + +thirsty.time_next_tick = thirsty.config.tick_time + +dofile(modpath..'/hud.lua') +dofile(modpath..'/functions.lua') + +minetest.register_on_joinplayer(thirsty.on_joinplayer) +minetest.register_on_dieplayer(thirsty.on_dieplayer) +minetest.register_globalstep(thirsty.main_loop) + +dofile(modpath..'/components_external_nodes_items.lua') +dofile(modpath..'/components.lua') +dofile(modpath..'/interop_a_functions.lua') + +-- dungeon_loot for Aumlets of Thirst +if minetest.get_modpath("dungeon_loot") then + dofile(modpath..'/interop_dungeon_loot.lua') +end + +-- mobs_animal specific config +if minetest.get_modpath("mobs_animal") then + dofile(modpath..'/interop_mobs_animal.lua') +end + +-- farming(redo) specific config +if minetest.get_modpath("farming") and + farming.mod == "redo" then + dofile(modpath..'/interop_farming_redo.lua') +end + +-- ethereal specific config +if minetest.get_modpath("ethereal") then + dofile(modpath..'/interop_ethereal.lua') +end \ No newline at end of file diff --git a/thirsty/interop_a_functions.lua b/thirsty/interop_a_functions.lua new file mode 100644 index 0000000..c45b523 --- /dev/null +++ b/thirsty/interop_a_functions.lua @@ -0,0 +1,56 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [interoperability function] -- +------------------------------------------------------------ +-- because I'm lazy and like small code blocks -- +------------------------------------------------------------ + +thirsty.register_food_drink = function (item_name,satiate_value,heal_value,hyd_value,hyd_max,rtn_item_name) + + local is_hunger_ng = false + local is_hbhunger = false + if minetest.get_modpath("hunger_ng") then is_hunger_ng = true end + if minetest.get_modpath("hbhunger") then is_hbhunger = true end + + if is_hunger_ng then + hunger_ng.add_hunger_data(item_name,{ + satiates = satiate_value, + heals = heal_value, + returns = nil, + timeout = nil + }) + end + + if is_hbhunger then + hbhunger.register_food(item_name, satiate_value) + end + + local def = table.copy(minetest.registered_items[item_name]) + def.on_use = function(itemstack,player,pointed_thing) + + thirsty.drink(player,hyd_value,hyd_max,rtn_item_name) + + if minetest.registered_items[item_name]._hunger_ng then + minetest.sound_play("hunger_ng_eat", {to_player = player:get_player_name(), gain = 2.0 }) + hunger_ng.alter_hunger(player:get_player_name(), satiate_value, "from:thirsty-"..item_name) + player:set_hp(player:get_hp()+heal_value) + itemstack:take_item() + return itemstack + else + minetest.do_item_eat(satiate_value,nil, itemstack:take_item(), player, pointed_thing) + return itemstack + end + + end + + if def.type == "node" then + minetest.register_node(":"..item_name, def) + else + minetest.register_craftitem(":"..item_name, def) + end +end \ No newline at end of file diff --git a/thirsty/interop_dungeon_loot.lua b/thirsty/interop_dungeon_loot.lua new file mode 100644 index 0000000..7149abc --- /dev/null +++ b/thirsty/interop_dungeon_loot.lua @@ -0,0 +1,20 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [interop_ethereal] -- +------------------------------------------------------------ +-- Settings to support Dungeon Loot -- +------------------------------------------------------------ + + +if thirsty.config.register_amulets == true then + + dungeon_loot.register({name = "thirsty:lesser_amulet_thirst", chance = 0.1, count = {1,1}}) + dungeon_loot.register({name = "thirsty:amulet_thirst", chance = 0.05, count = {1,1}, y = {-100, 32768}}) + dungeon_loot.register({name = "thirsty:greater_amulet_thirst", chance = 0.05, count = {1,1}, y = {-200, 32768}}) + +end \ No newline at end of file diff --git a/thirsty/interop_ethereal.lua b/thirsty/interop_ethereal.lua new file mode 100644 index 0000000..9f2ad0b --- /dev/null +++ b/thirsty/interop_ethereal.lua @@ -0,0 +1,20 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [interop_ethereal] -- +------------------------------------------------------------ +-- Settings to support Ethereal -- +------------------------------------------------------------ + +local E = thirsty.ext_nodes_items +---------------------------- +-- Hydrate and Food Items -- +---------------------------- +thirsty.register_food_drink("ethereal:firethorn_jelly" ,1,0,1,20,E.glass_bottle) +thirsty.register_food_drink("ethereal:mushroom_soup" ,2.5,0,2,20,"ethereal:bowl") +thirsty.register_food_drink("ethereal:hearty_stew" ,7.0,0,1,20,"ethereal:bowl") +thirsty.register_food_drink("ethereal:golden_apple" ,10,10,10,30,nil) \ No newline at end of file diff --git a/thirsty/interop_farming_redo.lua b/thirsty/interop_farming_redo.lua new file mode 100644 index 0000000..66a4feb --- /dev/null +++ b/thirsty/interop_farming_redo.lua @@ -0,0 +1,71 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [interop_farming(redo)] -- +------------------------------------------------------------ +-- Settings to support farming redo -- +------------------------------------------------------------ + +local E = thirsty.ext_nodes_items + +-------------------- +-- Hydrate only -- +-------------------- +local def = table.copy(minetest.registered_items["farming:glass_water"]) +def.on_use = function(itemstack,player,pointed_thing) + thirsty.drink(player,2,20,E.drinking_glass) + itemstack:take_item() + return itemstack + end +minetest.register_craftitem(":farming:glass_water", def) + + +local def = table.copy(minetest.registered_items["farming:rose_water"]) +def.on_use = function(itemstack,player,pointed_thing) + thirsty.drink(player,12,24,E.glass_bottle) + itemstack:take_item() + return itemstack + end +minetest.register_craftitem(":farming:rose_water", def) + +---------------------------- +-- Hydrate and Food Items -- +---------------------------- +thirsty.register_food_drink("farming:soy_milk" ,1,0,4,22,E.drinking_glass) +thirsty.register_food_drink("farming:pineapple_juice" ,1,0,4,22,E.drinking_glass) +thirsty.register_food_drink("farming:carrot_juice" ,1,0,4,22,E.drinking_glass) +thirsty.register_food_drink("farming:smoothie_berry" ,2,0,4,23,E.drinking_glass) +thirsty.register_food_drink("farming:smoothie_raspberry",2,0,4,23,E.drinking_glass) +thirsty.register_food_drink("farming:mint_tea" ,2,0,4,24,E.drinking_glass) +thirsty.register_food_drink("farming:coffee_cup" ,2,0,4,22,E.drinking_glass) +thirsty.register_food_drink("farming:beetroot_soup" ,4,0,2,20,E.wood_bowl) +thirsty.register_food_drink("farming:onion_soup" ,5,0,2,20,E.wood_bowl) +thirsty.register_food_drink("farming:pea_soup" ,6,0,2,20,E.wood_bowl) +thirsty.register_food_drink("farming:tomato_soup" ,7,0,2,20,E.wood_bowl) +thirsty.register_food_drink("farming:chili_bowl" ,7,0,-2,20,E.wood_bowl) +thirsty.register_food_drink("farming:chili_pepper" ,1,-1,-5,40,nil) + +-------------------- +-- Complex/Custom -- +-------------------- +local def = table.copy(minetest.registered_items["farming:cactus_juice"]) +def.on_use = function(itemstack, player, pointed_thing) + if player then + if math.random(5) == 1 then + thirsty.drink(player,-2,20,E.drinking_glass) + itemstack:take_item() + return itemstack + else + thirsty.drink(player,6,20,E.drinking_glass) + itemstack:take_item() + return itemstack + end + end + end + +minetest.register_craftitem(":farming:cactus_juice", def) + diff --git a/thirsty/interop_mobs_animal.lua b/thirsty/interop_mobs_animal.lua new file mode 100644 index 0000000..70b566e --- /dev/null +++ b/thirsty/interop_mobs_animal.lua @@ -0,0 +1,19 @@ +------------------------------------------------------------ +-- _____ _ _ _ -- +-- |_ _| |_ (_)_ _ __| |_ _ _ -- +-- | | | ' \| | '_(_-< _| || | -- +-- |_| |_||_|_|_| /__/\__|\_, | -- +-- |__/ -- +------------------------------------------------------------ +-- Thirsty mod [interop_mobs_animal] -- +------------------------------------------------------------ +-- Settings to support mobs_animal -- +------------------------------------------------------------ +local E = thirsty.ext_nodes_items + +---------------------------- +-- Hydrate and Food Items -- +---------------------------- + thirsty.register_food_drink("mobs:glass_milk",1,0,4,22,E.drinking_glass) + thirsty.register_food_drink("mobs:honey" ,2,0,1,20,nil) + diff --git a/thirsty/mod.conf b/thirsty/mod.conf new file mode 100644 index 0000000..cbf27c9 --- /dev/null +++ b/thirsty/mod.conf @@ -0,0 +1,4 @@ +name = thirsty +description = A mod that adds a "thirst" mechanic, similar to hunger. +depends = +optional_depends = default, bucket, hudbars, vessels, farming, mobs_animal, hunger_ng, hbhunger, dungeon_loot, ethereal \ No newline at end of file diff --git a/thirsty/settingtypes.txt b/thirsty/settingtypes.txt new file mode 100644 index 0000000..6f044e0 --- /dev/null +++ b/thirsty/settingtypes.txt @@ -0,0 +1,60 @@ +[*General] +# Hudbar/player max value for hydration +thirsty_starting_value (Thirst Max Value) int 20 + +# The period, in seconds, in which this mod updates values. +# Changing this will not directly affect other values, but +# may change computation load or accuracy. +thirsty_tick_time (Thirst Tick Time) float 0.5 + +# Thirst per second (full hydration is 20 hydro points) +# Basic Calc 1/30 = 0.033 +thirst_per_second (Thirst Per Second) float 0.033 + +# Damage per second if completely thirsty / out of hydration. +# Basic Calc 1/10 = 0.1 +damage_per_second (Damage Per Second) float 0.1 + +# How long in seconds you have to remain still to drink from standing in water. +stand_still_for_drink (Stand Still to Drink) float 1.0 + +# How long in seconds of not moving before a player is deemed +# AFK (away from keyboard), such players no longer get thirsty +# or damaged. +stand_still_for_afk (AFK Time Seconds) int 120 + +[*Water Fountain] +# Regeneration from being within a fountain's radius. +# (it's as if you're standing in water) +regen_from_fountain (Regen from Fountains) float 0.5 + +# How far should the fountain scanning pyramid go? +fountain_height (Fountain Height) int 4 + +# The max level of a fountain +fountain_max_level (Fountain Max Level) int 20 + +# How many nodes away can you still benefit from a fountain, per fountain level +fountain_distance_per_level (Fountain Distance Per Level) int 5 + +[*Thirsty Mod Items] +# Add the wooden bowl and crafting recipe? +# Will Augument Farming Redo Wooden Bowl if set to true +# and Farming redo is being used +register_bowl (Simple Wooden Bowl) bool true + +# Add the canteens and crafting recipes? +register_canteens (Steel/Bronze Canteens) bool true + +# Add the drinking fountain and crafting recipes? +register_drinking_fountain (Drinking Fountains) bool true + +# Add the fountain and extenders and crafting recipes? +register_fountains (Water Fountains) bool true + +# Add the amulets (extractor / injector) and crafting recipes? +register_amulets (Amulets) bool true + +[*Other Mods] +# Should we augment the vessels from the "vessels" mod? +register_vessels (Vessels Mod) bool true diff --git a/thirsty/sounds/thirsty_breviceps_drink-drinking-liquid.ogg b/thirsty/sounds/thirsty_breviceps_drink-drinking-liquid.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cfd6cf5121a85ea93da64d39e1f23bb652416b63 GIT binary patch literal 14701 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 C%-@ax literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/bowl.svg b/thirsty/textures/src/bowl.svg new file mode 100644 index 0000000..1085aa3 --- /dev/null +++ b/thirsty/textures/src/bowl.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/thirsty/textures/src/bronze_canteen.svg b/thirsty/textures/src/bronze_canteen.svg new file mode 100644 index 0000000..3a33e99 --- /dev/null +++ b/thirsty/textures/src/bronze_canteen.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/cup_0.svg b/thirsty/textures/src/cup_0.svg new file mode 100644 index 0000000..037ec10 --- /dev/null +++ b/thirsty/textures/src/cup_0.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/cup_100.svg b/thirsty/textures/src/cup_100.svg new file mode 100644 index 0000000..7a081b2 --- /dev/null +++ b/thirsty/textures/src/cup_100.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/cup_50.svg b/thirsty/textures/src/cup_50.svg new file mode 100644 index 0000000..fc380fe --- /dev/null +++ b/thirsty/textures/src/cup_50.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/drinkfount_bottom.svg b/thirsty/textures/src/drinkfount_bottom.svg new file mode 100644 index 0000000..189a693 --- /dev/null +++ b/thirsty/textures/src/drinkfount_bottom.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/thirsty/textures/src/drinkfount_side.svg b/thirsty/textures/src/drinkfount_side.svg new file mode 100644 index 0000000..d0b3f4c --- /dev/null +++ b/thirsty/textures/src/drinkfount_side.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/thirsty/textures/src/drinkfount_top.svg b/thirsty/textures/src/drinkfount_top.svg new file mode 100644 index 0000000..a9b1993 --- /dev/null +++ b/thirsty/textures/src/drinkfount_top.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/thirsty/textures/src/extractor.svg b/thirsty/textures/src/extractor.svg new file mode 100644 index 0000000..f4c1112 --- /dev/null +++ b/thirsty/textures/src/extractor.svg @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/injector.svg b/thirsty/textures/src/injector.svg new file mode 100644 index 0000000..0969a78 --- /dev/null +++ b/thirsty/textures/src/injector.svg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/steel_canteen.svg b/thirsty/textures/src/steel_canteen.svg new file mode 100644 index 0000000..89f2f01 --- /dev/null +++ b/thirsty/textures/src/steel_canteen.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/thirsty_amulet_hydration_cc0.xcf b/thirsty/textures/src/thirsty_amulet_hydration_cc0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6d7352ce164bc887b8a902cb9de1838b970b4d14 GIT binary patch literal 9525 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/thirsty_amulet_moisture_cc0.xcf b/thirsty/textures/src/thirsty_amulet_moisture_cc0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..33ad67d54caffde61d7987802dc6d55e8c0653d4 GIT binary patch literal 13984 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 M`vZD{J@PU359qwB8UO$Q literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/thirsty_bronze_canteen_cc0.xcf b/thirsty/textures/src/thirsty_bronze_canteen_cc0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..243191d9d4856ee9502b72fe875fae48e0b5177d GIT binary patch literal 9079 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 CdOvUg literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/thirsty_cup_100_cc0.xcf b/thirsty/textures/src/thirsty_cup_100_cc0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..61c90f8470ad0a012f752e20370d05894561cc50 GIT binary patch literal 9014 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/thirsty_steel_canteen_cc0.xcf b/thirsty/textures/src/thirsty_steel_canteen_cc0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..e6c477254c9d0bd697890cbf865180e27d9f7a44 GIT binary patch literal 8439 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/src/waterextender_side.svg b/thirsty/textures/src/waterextender_side.svg new file mode 100644 index 0000000..fdf6326 --- /dev/null +++ b/thirsty/textures/src/waterextender_side.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/thirsty/textures/src/waterextender_top.svg b/thirsty/textures/src/waterextender_top.svg new file mode 100644 index 0000000..5f80814 --- /dev/null +++ b/thirsty/textures/src/waterextender_top.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/waterfountain_side.svg b/thirsty/textures/src/waterfountain_side.svg new file mode 100644 index 0000000..410234e --- /dev/null +++ b/thirsty/textures/src/waterfountain_side.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/thirsty/textures/src/waterfountain_top.svg b/thirsty/textures/src/waterfountain_top.svg new file mode 100644 index 0000000..4db3923 --- /dev/null +++ b/thirsty/textures/src/waterfountain_top.svg @@ -0,0 +1,1051 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirsty/textures/thirsty_amulet_hydration_cc0.png b/thirsty/textures/thirsty_amulet_hydration_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7384dba320c6163275d6be989e756ae49f1f41 GIT binary patch literal 11038 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 JOxY&%zW_phv9bUF literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_amulet_moisture_cc0.png b/thirsty/textures/thirsty_amulet_moisture_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..7513219ee3cba92d95761f08876a4015dd7ef3ae GIT binary patch literal 10343 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_amulet_of_thirst_cc0.png b/thirsty/textures/thirsty_amulet_of_thirst_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..8b2738d6b5795aff135d22cfc930f56740f44f63 GIT binary patch literal 10122 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_amulet_of_thirst_greater_cc0.png b/thirsty/textures/thirsty_amulet_of_thirst_greater_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..efe8d12941ba92e7c4f3ba09f03aa56a56b4b5ab GIT binary patch literal 10734 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_amulet_of_thirst_lesser_cc0.png b/thirsty/textures/thirsty_amulet_of_thirst_lesser_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..f74e4844779f38afb36ef2ea32ba39fb811c2e2c GIT binary patch literal 11008 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

53)q0W4I!{DP_`Pk0elR|?U4pyr_#PX4Ogng~W% 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 VozDQni@-vIIN5KuE7%aQ?_a@3B!d6| literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_bronze_canteen_cc0.png b/thirsty/textures/thirsty_bronze_canteen_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..6e45e293a273a628f5c2efa860d7e488826e4aa5 GIT binary patch literal 8561 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 ZDk#S!b9le?aGEf{+}PTv)W9qHzW{S(>6`!n literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_drinkfount_bottom.png b/thirsty/textures/thirsty_drinkfount_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcaf5638d32b355830117335e8853532f5ad029 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4K$R%*=ck$Ubo?Cne>`0hi9VJUl#$*?Oc5vKT}*7#KJdiSA@zs9nMK U#A}UtA2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4bP0l+XkKiYzvF literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_drinkfount_top.png b/thirsty/textures/thirsty_drinkfount_top.png new file mode 100644 index 0000000000000000000000000000000000000000..2440cbd653e1a25da63fa7330f28208cb720b340 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4o>>1UzJ)uX z!S`5;#^3#N^V1R%8YB+5%$d65;0ngYYz77kmL7@k_nVZ?AS^6=c%e&>vFeeJJyX)s Z85YlwdSta<-U?_bgQu&X%Q~loCIDGtQd|H4 literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_drop_100_16_cc0.png b/thirsty/textures/thirsty_drop_100_16_cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..6080442051bb1aa86f0358343d42828b3521c5af GIT binary patch literal 695 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 literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_waterextender_top.png b/thirsty/textures/thirsty_waterextender_top.png new file mode 100644 index 0000000000000000000000000000000000000000..a68aa442df8770469240bcb38dad349fa8238fe6 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR44{HWW82vEcX)6&m-`&zxo`hB?ZK1eqbnuXGahLQWR{R%5V&vtUPA8eRG@bl NJYD@<);T3K0RU{%d?5e; literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_waterfountain_side.png b/thirsty/textures/thirsty_waterfountain_side.png new file mode 100644 index 0000000000000000000000000000000000000000..310966ab4bb67a7e371eaf11067a06fca62d33d2 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4Sh!V?nWv>FKmEctq4W#~@y}xE84;|4$w>zopr02xeW)&Kwi literal 0 HcmV?d00001 diff --git a/thirsty/textures/thirsty_waterfountain_top.png b/thirsty/textures/thirsty_waterfountain_top.png new file mode 100644 index 0000000000000000000000000000000000000000..b4f4529eb4acf4b166011930cff135f73b781579 GIT binary patch literal 750 zcmV@hf%4R2 z&;17qB8Um8w9N6aXXyxq?EG+5rQFnoy_-DD72Qo=Kq@8XQm@B2Cb>iqoej@-;v-Va6eL z>2cp;REa&V7|ktuB1!*2 zfxKA6$*+_&}dXvLyJMDp`lTuN}T;|6EAxf@tn0V`SA?#Eh7$*rr)!G ztINvtN+;2T8M{c+?^(os&cftU7wg+5^*4UkHdD-3&|7uHw~XwwLcWT@rX!j#1CXho gGgx%2Z<_%41qY8h*(P_8sQ>@~07*qoM6N<$g7F$q{{R30 literal 0 HcmV?d00001 diff --git a/thirsty/textures/vessels_glass_bottle_full_cc_by_sa_3.png b/thirsty/textures/vessels_glass_bottle_full_cc_by_sa_3.png new file mode 100644 index 0000000000000000000000000000000000000000..613d1c4c89cf49498b2091e7042f4d51d5d6fd30 GIT binary patch literal 6608 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 literal 0 HcmV?d00001