Compare commits
10 Commits
b4519d13db
...
ef3e6616e9
Author | SHA1 | Date | |
---|---|---|---|
|
ef3e6616e9 | ||
|
9f1acb4eaa | ||
|
b5df973174 | ||
|
6e979b7cd8 | ||
|
78be994cab | ||
|
1b767e820b | ||
|
86ac78d683 | ||
|
d2d2aef013 | ||
|
1a6e893f09 | ||
|
9fa18c564b |
@ -1,3 +0,0 @@
|
||||
default
|
||||
3d_armor?
|
||||
player_monoids?
|
@ -1 +0,0 @@
|
||||
Adds stamina and hunger effects.
|
131
init.lua
131
init.lua
@ -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,
|
||||
|
5
mod.conf
5
mod.conf
@ -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 |
Loading…
x
Reference in New Issue
Block a user