Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
3ae96044a6 | |||
cd4833fae7 | |||
a39c32d1d0 | |||
26ae940ec9 | |||
41bd87405d | |||
c328513513 | |||
7912e7c95b |
98
README.md
Normal file
98
README.md
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
Minetest mod "Stamina"
|
||||||
|
=====================
|
||||||
|
|
||||||
|
It adds a stamina, or "hunger" mechanic to Minetest
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Information:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This mod adds a stamina, or "hunger" mechanic to Minetest. Actions like
|
||||||
|
crafting, walking, digging or fighting make the player exhausted. When
|
||||||
|
enough exhaustion has been accumulated, the player gets more hungry,
|
||||||
|
and loses stamina.
|
||||||
|
|
||||||
|
If a player is low on stamina, they start taking periodical damage,
|
||||||
|
and ultimately will die if they do not eat food.
|
||||||
|
|
||||||
|
Eating food no longer heals the player. Instead, it increases the
|
||||||
|
stamina of the player. The stamina bar shows how well fed the player
|
||||||
|
is. More bread pieces means more stamina.
|
||||||
|
|
||||||
|
Walking while holding down Aux1 (usually E key) will make player sprint so
|
||||||
|
long as their stamina bar is 3 or more bread. This will make the player run
|
||||||
|
that bit faster and jump a tiny bit higher.
|
||||||
|
|
||||||
|
### Q&A time: Why won't I move the stamina bar to the right?
|
||||||
|
|
||||||
|
Answer: this conflicts with the builtin breath bar. To move the
|
||||||
|
builtin breath bar, I basically have to entirely re-implement it
|
||||||
|
in lua including timers to catch breath changes for each online
|
||||||
|
player, which is all a waste of time, just to move a few pixels
|
||||||
|
around.
|
||||||
|
|
||||||
|
### Downloads
|
||||||
|
|
||||||
|
Original mod is at github on https://github.com/minetest-mods/stamina, this
|
||||||
|
version is a fork over the Tenplus1 version (Check the tech info below), you
|
||||||
|
can download at https://codeberg.org/minenux/minetest-mod-stamina .
|
||||||
|
|
||||||
|
This version just try to be sure works over minetst 0.4 and also 5.X, with
|
||||||
|
some checks focused on olders versions like 5.0, 5.2 and 0.4.17
|
||||||
|
|
||||||
|
|
||||||
|
Technical information:
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This mod intercepts minetest.item_eat(), and applies the hp_change
|
||||||
|
as stamina change. The value can be positive (increase stamina) or
|
||||||
|
negative (periodically damage the player by 1 hp).
|
||||||
|
|
||||||
|
### Depends
|
||||||
|
|
||||||
|
* default
|
||||||
|
* 3d_armor (optional)
|
||||||
|
* player_monoids/pova (both alternative it, both optionally)
|
||||||
|
|
||||||
|
### TenPlus1 Additions:
|
||||||
|
|
||||||
|
- Added support for POVA and player_monoids
|
||||||
|
- Added Pipeworks checks for fake players
|
||||||
|
- Added 60 second drunk effect when foods have {alcohol=1} group (eat 4 or more)
|
||||||
|
- Moved exhaustion and hud_id to player table instead of player attributes
|
||||||
|
|
||||||
|
The player phishics are set on Pova or Player_monoids but
|
||||||
|
not both at the same time, only the first detected is apply.
|
||||||
|
|
||||||
|
### Callbacks
|
||||||
|
|
||||||
|
Callbacks that are registered via minetest.register_on_item_eat()
|
||||||
|
are called after this mod, so the itemstack will have changed already
|
||||||
|
when callbacks are called. You can get the original itemstack as 6th
|
||||||
|
parameter of your function then.
|
||||||
|
|
||||||
|
A global function is available for mods to change player stamina levels:
|
||||||
|
|
||||||
|
stamina.change(player, change)
|
||||||
|
|
||||||
|
|
||||||
|
License:
|
||||||
|
--------
|
||||||
|
|
||||||
|
(C) 2015 - BlockMen
|
||||||
|
(C) 2016 - Auke Kok <sofar@foo-projects.org>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Code:
|
||||||
|
- all code LGPL-2.1+
|
||||||
|
Textures:
|
||||||
|
- stamina_hud_poison.png - BlockMen (CC-BY 3.0)
|
||||||
|
- stamina_hud_fg.png - PilzAdam (WTFPL), modified by BlockMen
|
||||||
|
- stamina_hud_bg.png - PilzAdam (WTFPL), modified by BlockMen
|
||||||
|
Sounds:
|
||||||
|
- stamina_eat.*.ogg - http://www.freesound.org/people/sonictechtonic/sounds/242215/ CC-BY-3.0
|
||||||
|
|
||||||
|
stamina_burp.ogg - https://www.freesfx.co.uk/sfx/burp (small burp)
|
||||||
|
stamina_sip.ogg - https://elements.envato.com/sip-16081-C7V5YLG
|
15
README.txt
15
README.txt
@ -56,3 +56,18 @@ TenPlus1 Additions:
|
|||||||
- Added 60 second drunk effect when foods have {alcohol=1} group (eat 4 or more)
|
- Added 60 second drunk effect when foods have {alcohol=1} group (eat 4 or more)
|
||||||
- Moved exhaustion and hud_id to player table instead of player attributes
|
- Moved exhaustion and hud_id to player table instead of player attributes
|
||||||
- Added 4 lucky block effects
|
- Added 4 lucky block effects
|
||||||
|
|
||||||
|
|
||||||
|
License:
|
||||||
|
--------
|
||||||
|
Code:
|
||||||
|
- all code LGPL-2.1+
|
||||||
|
Textures:
|
||||||
|
- stamina_hud_poison.png - BlockMen (CC-BY 3.0)
|
||||||
|
- stamina_hud_fg.png - PilzAdam (WTFPL), modified by BlockMen
|
||||||
|
- stamina_hud_bg.png - PilzAdam (WTFPL), modified by BlockMen
|
||||||
|
Sounds:
|
||||||
|
- stamina_eat.*.ogg - http://www.freesound.org/people/sonictechtonic/sounds/242215/ CC-BY-3.0
|
||||||
|
|
||||||
|
stamina_burp.ogg - https://www.freesfx.co.uk/sfx/burp (small burp)
|
||||||
|
stamina_sip.ogg - https://elements.envato.com/sip-16081-C7V5YLG
|
||||||
|
77
init.lua
77
init.lua
@ -36,16 +36,32 @@ SPRINT_JUMP = clamp(tonumber(minetest.settings:get("stamina_sprint_jump")) or 0
|
|||||||
-- how fast to drain satation while sprinting (0-1)
|
-- how fast to drain satation while sprinting (0-1)
|
||||||
SPRINT_DRAIN = clamp(tonumber(minetest.settings:get("stamina_sprint_drain")) or 0.35, 0.0, 1.0)
|
SPRINT_DRAIN = clamp(tonumber(minetest.settings:get("stamina_sprint_drain")) or 0.35, 0.0, 1.0)
|
||||||
|
|
||||||
|
-- minetest 5.x check
|
||||||
|
local is_50 = minetest.has_feature("object_use_texture_alpha")
|
||||||
|
|
||||||
|
-- are we a real player ?
|
||||||
|
local function is_player(player)
|
||||||
|
|
||||||
|
-- pipeworks fake player check its not necesary with real player check:
|
||||||
|
if player then if minetest.is_player(player) then return true end end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
local function get_int_attribute(player)
|
local function get_int_attribute(player)
|
||||||
|
|
||||||
-- pipeworks fake player check
|
if not is_player(player) then
|
||||||
if not player or not player.get_attribute then
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local meta = player:get_meta()
|
local level
|
||||||
local level = meta and meta:get_string("stamina:level")
|
|
||||||
|
if is_50 then
|
||||||
|
|
||||||
|
local meta = player:get_meta()
|
||||||
|
level = meta and meta:get_string("stamina:level")
|
||||||
|
else
|
||||||
|
level = player and player:get_attribute("stamina:level")
|
||||||
|
end
|
||||||
|
|
||||||
if level then
|
if level then
|
||||||
return tonumber(level)
|
return tonumber(level)
|
||||||
@ -61,8 +77,7 @@ local damage_enabled = minetest.settings:get_bool("enable_damage")
|
|||||||
|
|
||||||
local function stamina_update_level(player, level)
|
local function stamina_update_level(player, level)
|
||||||
|
|
||||||
-- pipeworks fake player check
|
if not is_player(player) then
|
||||||
if not player.get_attribute or not stamina_enabled then
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -77,9 +92,14 @@ local function stamina_update_level(player, level)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local meta = player and player:get_meta() ; if not meta then return end
|
if is_50 then
|
||||||
|
|
||||||
meta:set_string("stamina:level", level)
|
local meta = player and player:get_meta() ; if not meta then return end
|
||||||
|
|
||||||
|
meta:set_string("stamina:level", level)
|
||||||
|
else
|
||||||
|
player:set_attribute("stamina:level", level)
|
||||||
|
end
|
||||||
|
|
||||||
player:hud_change(
|
player:hud_change(
|
||||||
stamina.players[player:get_player_name()].hud_id,
|
stamina.players[player:get_player_name()].hud_id,
|
||||||
@ -112,10 +132,7 @@ end
|
|||||||
|
|
||||||
local function exhaust_player(player, v)
|
local function exhaust_player(player, v)
|
||||||
|
|
||||||
if not player
|
if not is_player(player) then
|
||||||
or not player.is_player
|
|
||||||
or not player:is_player()
|
|
||||||
or not player.set_attribute then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -245,6 +262,8 @@ local function drunk_tick()
|
|||||||
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
|
if not is_player(player) then return end -- need cos some rare cases during game running object is not player
|
||||||
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
if name
|
if name
|
||||||
@ -292,6 +311,8 @@ local function health_tick()
|
|||||||
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
|
if not is_player(player) then return end -- need cos some rare cases during game running object is not player
|
||||||
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
if name then
|
if name then
|
||||||
@ -302,7 +323,7 @@ local function health_tick()
|
|||||||
|
|
||||||
-- damage player by 1 hp if saturation is < 2
|
-- damage player by 1 hp if saturation is < 2
|
||||||
if h and h < STAMINA_STARVE_LVL
|
if h and h < STAMINA_STARVE_LVL
|
||||||
and hp > 0 then
|
and hp > 1 then
|
||||||
player:set_hp(hp - STAMINA_STARVE, {hunger = true})
|
player:set_hp(hp - STAMINA_STARVE, {hunger = true})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -326,7 +347,9 @@ local function action_tick()
|
|||||||
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
local controls = player and player:get_player_control()
|
if not is_player(player) then return end -- need cos some rare cases during game running object is not player
|
||||||
|
|
||||||
|
local controls = player:get_player_control()
|
||||||
|
|
||||||
-- Determine if the player is walking or jumping
|
-- Determine if the player is walking or jumping
|
||||||
if controls then
|
if controls then
|
||||||
@ -345,7 +368,7 @@ local function action_tick()
|
|||||||
--- START sprint
|
--- START sprint
|
||||||
if enable_sprint then
|
if enable_sprint then
|
||||||
|
|
||||||
local name = player and player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
|
||||||
-- check if player can sprint (stamina must be over 6 points)
|
-- check if player can sprint (stamina must be over 6 points)
|
||||||
if name
|
if name
|
||||||
@ -410,7 +433,9 @@ local function poison_tick()
|
|||||||
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
local name = player and player:get_player_name()
|
if not is_player(player) then return end -- need cos some rare cases during game running object is not player
|
||||||
|
|
||||||
|
local name = player:get_player_name()
|
||||||
|
|
||||||
if name
|
if name
|
||||||
and stamina.players[name]
|
and stamina.players[name]
|
||||||
@ -448,7 +473,9 @@ local function stamina_tick()
|
|||||||
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
local h = player and get_int_attribute(player)
|
if not is_player(player) then return end -- need cos some rare cases during game running object is not player
|
||||||
|
|
||||||
|
local h = get_int_attribute(player)
|
||||||
|
|
||||||
if h and h > STAMINA_TICK_MIN then
|
if h and h > STAMINA_TICK_MIN then
|
||||||
stamina_update_level(player, h - 1)
|
stamina_update_level(player, h - 1)
|
||||||
@ -501,9 +528,7 @@ if damage_enabled and minetest.settings:get_bool("enable_stamina") ~= false then
|
|||||||
-- override core.do_item_eat() so we can redirect hp_change to stamina
|
-- override core.do_item_eat() so we can redirect hp_change to stamina
|
||||||
core.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
core.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||||
|
|
||||||
if user.is_fake_player then
|
if not is_player(user) then return end -- abort if called by fake player (eg. pipeworks-wielder)
|
||||||
return -- abort if called by fake player (eg. pipeworks-wielder)
|
|
||||||
end
|
|
||||||
|
|
||||||
local old_itemstack = itemstack
|
local old_itemstack = itemstack
|
||||||
|
|
||||||
@ -629,12 +654,15 @@ if damage_enabled and minetest.settings:get_bool("enable_stamina") ~= false then
|
|||||||
local level = STAMINA_VISUAL_MAX -- TODO
|
local level = STAMINA_VISUAL_MAX -- TODO
|
||||||
|
|
||||||
if get_int_attribute(player) then
|
if get_int_attribute(player) then
|
||||||
|
|
||||||
level = math.min(get_int_attribute(player), STAMINA_VISUAL_MAX)
|
level = math.min(get_int_attribute(player), STAMINA_VISUAL_MAX)
|
||||||
else
|
end
|
||||||
local meta = player:get_meta()
|
|
||||||
|
|
||||||
meta:set_string("stamina:level", level)
|
if is_50 then
|
||||||
|
|
||||||
|
local meta = player:get_meta()
|
||||||
|
if meta then meta:set_string("stamina:level", level) end
|
||||||
|
else
|
||||||
|
player:set_attribute("stamina:level", level)
|
||||||
end
|
end
|
||||||
|
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
@ -662,6 +690,7 @@ if damage_enabled and minetest.settings:get_bool("enable_stamina") ~= false then
|
|||||||
|
|
||||||
minetest.register_on_respawnplayer(function(player)
|
minetest.register_on_respawnplayer(function(player)
|
||||||
|
|
||||||
|
if not player then return end
|
||||||
local name = player:get_player_name() ; if not name then return end
|
local name = player:get_player_name() ; if not name then return end
|
||||||
|
|
||||||
if stamina.players[name].poisoned
|
if stamina.players[name].poisoned
|
||||||
|
@ -23,8 +23,8 @@ local effect_me = function(pos, player, def)
|
|||||||
|
|
||||||
minetest.chat_send_player(name, green .. "You seem a little tipsy!")
|
minetest.chat_send_player(name, green .. "You seem a little tipsy!")
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-- restore stamina function
|
-- restore stamina function
|
||||||
local full_stamina = function(pos, player, def)
|
local full_stamina = function(pos, player, def)
|
||||||
|
@ -4,10 +4,10 @@ sprint_particles (Enable sprint particles) bool true
|
|||||||
|
|
||||||
enable_stamina (Enable stamina/hunger) bool true
|
enable_stamina (Enable stamina/hunger) bool true
|
||||||
|
|
||||||
stamina_tick (Time in seconds after which 1 saturation point is taken) float 800
|
stamina_tick (Time in seconds after which 1 saturation point is taken) float 1600
|
||||||
|
|
||||||
stamina_sprint_speed (Extra sprint speed - 0.0 to 1.0) float 0.3
|
stamina_sprint_speed (Extra sprint speed - 0.0 to 1.0) float 0.3
|
||||||
|
|
||||||
stamina_sprint_jump (Extra sprint jump height - 0.0 to 1.0) float 0.1
|
stamina_sprint_jump (Extra sprint jump height - 0.0 to 1.0) float 0.1
|
||||||
|
|
||||||
stamina_sprint_drain (Sprint stamina drain - 0.0 to 1.0) float 0.35
|
stamina_sprint_drain (Sprint stamina drain - 0.0 to 1.0) float 0.2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user