Compare commits

..

10 Commits

Author SHA1 Message Date
Niklp
ef3e6616e9
Minor changes (#49)
- Optimize textures w/ optipng
- Remove mt 0.4 compatibility stuff
- Other minor stuff (play sounds ephemeral, tweak style of some comments, ...)
2024-06-05 17:56:45 +02:00
fluxionary
9f1acb4eaa
Behavior tweaks when eating "empty" food (#46)
- Allow eating food which doesn't restore saturation when the player is full
- Don't apply poison effect when eating food that isn't actually poisonous
2023-05-18 14:14:36 +02:00
fluxionary
b5df973174
Allow healing when max_hp is higher than max stamina (#45) 2023-05-14 14:51:49 +02:00
fluxionary
6e979b7cd8
Fix eaten item being replaced with copies of itself (#43) 2023-04-28 17:27:05 +02:00
fluxionary
78be994cab
Check that hp is less than hp_max when trying to heal (#44) 2023-03-18 08:53:50 +01:00
fluxionary
1b767e820b
Provide a proper reason table to set_hp instead of a string (#42) 2023-01-10 17:48:14 +01:00
fluxionary
86ac78d683
Add reasons to hp change calls (#41) 2023-01-04 14:36:06 +01:00
fluxionary
d2d2aef013
Show particles while eating foods without an inventory image (#40) 2022-10-29 21:36:04 +02:00
SX
1a6e893f09
Mitigate error if metadata is not valid (disconnected player) (#38) 2021-10-12 20:36:19 +02:00
OgelGames
9fa18c564b
Add hidden background texture (#35)
* Add hidden background texture

* Remove old texture
2020-12-28 11:30:24 +01:00
7 changed files with 75 additions and 65 deletions

View File

@ -1,3 +0,0 @@
default
3d_armor?
player_monoids?

View File

@ -1 +0,0 @@
Adds stamina and hunger effects.

131
init.lua
View File

@ -65,23 +65,17 @@ local function is_player(player)
end
local function set_player_attribute(player, key, value)
if player.get_meta then
if value == nil then
player:get_meta():set_string(key, "")
else
player:get_meta():set_string(key, tostring(value))
end
local meta = player:get_meta()
if value == nil then
meta:set_string(key, "")
else
player:set_attribute(key, value)
meta:set_string(key, tostring(value))
end
end
local function get_player_attribute(player, key)
if player.get_meta then
return player:get_meta():get_string(key)
else
return player:get_attribute(key)
end
local meta = player:get_meta()
return meta:get_string(key)
end
local hud_ids_by_player_name = {}
@ -123,7 +117,7 @@ function stamina.update_saturation(player, level)
local old = stamina.get_saturation(player)
if level == old then -- To suppress HUD update
if level == old then -- To suppress HUD update
return
end
@ -160,7 +154,7 @@ function stamina.set_poisoned(player, poisoned)
set_player_attribute(player, attribute.poisoned, "yes")
else
player:hud_change(hud_id, "text", "stamina_hud_fg.png")
set_player_attribute(player, attribute.poisoned, "no")
set_player_attribute(player, attribute.poisoned, nil)
end
end
@ -173,7 +167,7 @@ local function poison_tick(player_name, ticks, interval, elapsed)
else
local hp = player:get_hp() - 1
if hp > 0 then
player:set_hp(hp)
player:set_hp(hp, {type = "set_hp", cause = "stamina:poison"})
end
minetest.after(interval, poison_tick, player_name, ticks, interval, elapsed + 1)
end
@ -242,7 +236,7 @@ function stamina.exhaust_player(player, change, cause)
if exhaustion >= settings.exhaust_lvl then
exhaustion = exhaustion - settings.exhaust_lvl
stamina.change(player, -1)
stamina.change_saturation(player, -1)
end
stamina.set_exhaustion(player, exhaustion)
@ -297,7 +291,7 @@ function stamina.set_sprinting(player, sprinting)
end
if settings.sprint_particles and sprinting then
local pos = player:getpos()
local pos = player:get_pos()
local node = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
local def = minetest.registered_nodes[node.name] or {}
local drawtype = def.drawtype
@ -329,7 +323,7 @@ local function move_tick()
for _,player in ipairs(minetest.get_connected_players()) do
local controls = player:get_player_control()
local is_moving = controls.up or controls.down or controls.left or controls.right
local velocity = player:get_player_velocity()
local velocity = player:get_velocity()
velocity.y = 0
local horizontal_speed = vector.length(velocity)
local has_velocity = horizontal_speed > 0.05
@ -375,12 +369,13 @@ local function health_tick()
for _,player in ipairs(minetest.get_connected_players()) do
local air = player:get_breath() or 0
local hp = player:get_hp()
local hp_max = player:get_properties().hp_max
local saturation = stamina.get_saturation(player)
-- don't heal if dead, drowning, or poisoned
local should_heal = (
saturation >= settings.heal_lvl and
saturation >= hp and
hp < hp_max and
hp > 0 and
air > 0
and not stamina.is_poisoned(player)
@ -392,10 +387,10 @@ local function health_tick()
)
if should_heal then
player:set_hp(hp + settings.heal)
player:set_hp(hp + settings.heal, {type = "set_hp", cause = "stamina:heal"})
stamina.exhaust_player(player, settings.exhaust_lvl, stamina.exhaustion_reasons.heal)
elseif is_starving then
player:set_hp(hp - settings.starve)
player:set_hp(hp - settings.starve, {type = "set_hp", cause = "stamina:starve"})
end
end
end
@ -425,6 +420,43 @@ local function stamina_globaltimer(dtime)
end
end
local function show_eat_particles(player, itemname)
-- particle effect when eating
local pos = player:get_pos()
pos.y = pos.y + (player:get_properties().eye_height * .923) -- assume mouth is slightly below eye_height
local dir = player:get_look_dir()
local def = minetest.registered_items[itemname]
local texture = def.inventory_image or def.wield_image
local particle_def = {
amount = 5,
time = 0.1,
minpos = pos,
maxpos = pos,
minvel = {x = dir.x - 1, y = dir.y, z = dir.z - 1},
maxvel = {x = dir.x + 1, y = dir.y, z = dir.z + 1},
minacc = {x = 0, y = -5, z = 0},
maxacc = {x = 0, y = -9, z = 0},
minexptime = 1,
maxexptime = 1,
minsize = 1,
maxsize = 2,
}
if texture and texture ~= "" then
particle_def.texture = texture
elseif def.type == "node" then
particle_def.node = {name = itemname, param2 = 0}
else
particle_def.texture = "blank.png"
end
minetest.add_particlespawner(particle_def)
end
-- override minetest.do_item_eat() so we can redirect hp_change to stamina
stamina.core_item_eat = minetest.do_item_eat
function minetest.do_item_eat(hp_change, replace_with_item, itemstack, player, pointed_thing)
@ -440,8 +472,8 @@ function minetest.do_item_eat(hp_change, replace_with_item, itemstack, player, p
end
local level = stamina.get_saturation(player) or 0
if level >= settings.visual_max then
-- don't eat if player is full
if level >= settings.visual_max and hp_change > 0 then
-- don't eat if player is full and item provides saturation
return itemstack
end
@ -453,58 +485,33 @@ function minetest.do_item_eat(hp_change, replace_with_item, itemstack, player, p
stamina.log("action", "%s eats %s for %s stamina",
player:get_player_name(), itemname, hp_change)
end
minetest.sound_play("stamina_eat", {to_player = player:get_player_name(), gain = 0.7})
minetest.sound_play("stamina_eat", {to_player = player:get_player_name(), gain = 0.7}, true)
if hp_change > 0 then
stamina.change_saturation(player, hp_change)
stamina.set_exhaustion(player, 0)
else
-- assume hp_change < 0.
elseif hp_change < 0 then
stamina.poison(player, -hp_change, settings.poison_tick)
end
if settings.eat_particles then
-- particle effect when eating
local pos = player:getpos()
pos.y = pos.y + 1.5 -- mouth level
local texture = minetest.registered_items[itemname].inventory_image
local dir = player:get_look_dir()
minetest.add_particlespawner({
amount = 5,
time = 0.1,
minpos = pos,
maxpos = pos,
minvel = {x = dir.x - 1, y = dir.y, z = dir.z - 1},
maxvel = {x = dir.x + 1, y = dir.y, z = dir.z + 1},
minacc = {x = 0, y = -5, z = 0},
maxacc = {x = 0, y = -9, z = 0},
minexptime = 1,
maxexptime = 1,
minsize = 1,
maxsize = 2,
texture = texture,
})
show_eat_particles(player, itemname)
end
itemstack:take_item()
if replace_with_item then
if itemstack:is_empty() then
itemstack:add_item(replace_with_item)
else
local inv = player:get_inventory()
if inv:room_for_item("main", {name=replace_with_item}) then
inv:add_item("main", replace_with_item)
else
local pos = player:getpos()
pos.y = math.floor(pos.y - 1.0)
minetest.add_item(pos, replace_with_item)
end
player:set_wielded_item(itemstack)
replace_with_item = ItemStack(replace_with_item)
if not replace_with_item:is_empty() then
local inv = player:get_inventory()
replace_with_item = inv:add_item("main", replace_with_item)
if not replace_with_item:is_empty() then
local pos = player:get_pos()
pos.y = math.floor(pos.y - 1.0)
minetest.add_item(pos, replace_with_item)
end
end
return itemstack
return nil -- don't overwrite wield item a second time
end
minetest.register_on_joinplayer(function(player)
@ -516,6 +523,8 @@ minetest.register_on_joinplayer(function(player)
size = {x = 24, y = 24},
text = "stamina_hud_fg.png",
number = level,
text2 = "stamina_hud_bg.png",
item = settings.visual_max,
alignment = {x = -1, y = -1},
offset = {x = -266, y = -110},
max = 0,

View File

@ -1 +1,6 @@
name = stamina
title = Stamina
description = Adds stamina and hunger effects.
min_minetest_version = 5.4
depends = default
optional_depends = 3d_armor, player_monoids

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 402 B