Rewrite
This commit is contained in:
parent
98000d896e
commit
0df8facb4d
@ -1,187 +1,89 @@
|
||||
local minetest,vector,hud_manager = minetest,vector,hud_manager
|
||||
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
local pool = {}
|
||||
|
||||
local drowning_class = {}
|
||||
|
||||
drowning_class.get_group = minetest.get_item_group
|
||||
|
||||
local player_drowning = {}
|
||||
|
||||
drowning_class.tick = nil
|
||||
|
||||
drowning_class.breath = nil
|
||||
|
||||
drowning_pointer = {} -- allows other mods to access data
|
||||
|
||||
-- creates volitile data for the game to use
|
||||
drowning_class.set_data = function(player,data)
|
||||
local name = player:get_player_name()
|
||||
if not player_drowning[name] then
|
||||
player_drowning[name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in pairs(data) do
|
||||
player_drowning[name][index] = i_data
|
||||
end
|
||||
|
||||
if data.breath then
|
||||
|
||||
if data.breath > 20 then
|
||||
if hud_manager.hud_exists(player,"breath_bg") then
|
||||
hud_manager.remove_hud(player,"breath_bg")
|
||||
end
|
||||
if hud_manager.hud_exists(player,"breath") then
|
||||
hud_manager.remove_hud(player,"breath")
|
||||
end
|
||||
else
|
||||
if not hud_manager.hud_exists(player,"breath_bg") then
|
||||
hud_manager.add_hud(player,"breath_bg",{
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
text = "bubble_bg.png",
|
||||
number = 20,
|
||||
direction = 1,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = 24*10, y= -(48 + 52 + 39)},
|
||||
})
|
||||
end
|
||||
if not hud_manager.hud_exists(player,"breath") then
|
||||
hud_manager.add_hud(player,"breath",{
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
text = "bubble.png",
|
||||
number = data.breath,
|
||||
direction = 1,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = 24*10, y= -(48 + 52 + 39)},
|
||||
})
|
||||
end
|
||||
|
||||
hud_manager.change_hud({
|
||||
player = player ,
|
||||
hud_name = "breath",
|
||||
element = "number",
|
||||
data = data.breath
|
||||
-- updates bubble bar
|
||||
local update_breath_bar = function(player,breath)
|
||||
if breath > 20 then
|
||||
if hud_manager.hud_exists(player,"breath_bg") then
|
||||
hud_manager.remove_hud(player,"breath_bg")
|
||||
end
|
||||
if hud_manager.hud_exists(player,"breath") then
|
||||
hud_manager.remove_hud(player,"breath")
|
||||
end
|
||||
else
|
||||
if not hud_manager.hud_exists(player,"breath_bg") then
|
||||
hud_manager.add_hud(player,"breath_bg",{
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
text = "bubble_bg.png",
|
||||
number = 20,
|
||||
direction = 1,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = 24*10, y= -(48 + 52 + 39)},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- indexes drowning data and returns it
|
||||
drowning_class.get_data = function(player,requested_data)
|
||||
local name = player:get_player_name()
|
||||
if player_drowning[name] then
|
||||
local data_list = {}
|
||||
local count = 0
|
||||
for index,i_data in pairs(requested_data) do
|
||||
if player_drowning[name][i_data] then
|
||||
data_list[i_data] = player_drowning[name][i_data]
|
||||
count = count + 1
|
||||
end
|
||||
if not hud_manager.hud_exists(player,"breath") then
|
||||
hud_manager.add_hud(player,"breath",{
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
text = "bubble.png",
|
||||
number = breath,
|
||||
direction = 1,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = 24*10, y= -(48 + 52 + 39)},
|
||||
})
|
||||
end
|
||||
if count > 0 then
|
||||
return(data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
-- removes data
|
||||
drowning_class.terminate = function(player)
|
||||
local name = player:get_player_name()
|
||||
if player_drowning[name] then
|
||||
player_drowning[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- loads data from mod storage
|
||||
drowning_class.load_data = function(player)
|
||||
local name = player:get_player_name()
|
||||
if mod_storage:get_int(name.."d_save") > 0 then
|
||||
return({
|
||||
breath = mod_storage:get_float(name.."breath" ),
|
||||
breath_ticker = mod_storage:get_float(name.."breath_ticker"),
|
||||
drowning = mod_storage:get_float(name.."drowning" ),
|
||||
})
|
||||
else
|
||||
return({
|
||||
breath = 20,
|
||||
breath_ticker = 0 ,
|
||||
drowning = 0 ,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- saves data to be utilized on next login
|
||||
drowning_class.save_data = function(player)
|
||||
local name
|
||||
if type(player) ~= "string" and player:is_player() then
|
||||
name = player:get_player_name()
|
||||
elseif type(player) == "string" then
|
||||
name = player
|
||||
end
|
||||
if player_drowning[name] then
|
||||
for index,integer in pairs(player_drowning[name]) do
|
||||
mod_storage:set_float(name..index,integer)
|
||||
end
|
||||
end
|
||||
|
||||
mod_storage:set_int(name.."d_save", 1)
|
||||
|
||||
player_drowning[name] = nil
|
||||
end
|
||||
|
||||
-- is used for shutdowns to save all data
|
||||
drowning_class.save_all = function()
|
||||
for name,data in pairs(player_drowning) do
|
||||
drowning_class.save_data(name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- creates volitile data for the game to use
|
||||
drowning_pointer.set_data = function(player,data)
|
||||
local name = player:get_player_name()
|
||||
if not player_drowning[name] then
|
||||
player_drowning[name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in pairs(data) do
|
||||
player_drowning[name][index] = i_data
|
||||
end
|
||||
|
||||
if data.breath then
|
||||
hud_manager.change_hud({
|
||||
player = player ,
|
||||
hud_name = "breath",
|
||||
element = "number",
|
||||
data = data.breath
|
||||
data = breath
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- indexes drowning data and returns it
|
||||
drowning_pointer.get_data = function(player,requested_data)
|
||||
local name = player:get_player_name()
|
||||
if player_drowning[name] then
|
||||
local data_list = {}
|
||||
local count = 0
|
||||
for index,i_data in pairs(requested_data) do
|
||||
if player_drowning[name][i_data] then
|
||||
data_list[i_data] = player_drowning[name][i_data]
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > 0 then
|
||||
return(data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
-- loads data from mod storage
|
||||
local name
|
||||
local temp_pool
|
||||
local load_data = function(player)
|
||||
name = player:get_player_name()
|
||||
pool[name] = {}
|
||||
temp_pool = pool[name]
|
||||
if mod_storage:get_int(name.."d_save") > 0 then
|
||||
temp_pool.breath = mod_storage:get_float(name.."breath" )
|
||||
temp_pool.ticker = mod_storage:get_float(name.."breath_ticker")
|
||||
temp_pool.drowning = mod_storage:get_float(name.."drowning" )
|
||||
else
|
||||
temp_pool.breath = 21
|
||||
temp_pool.ticker = 0
|
||||
temp_pool.drowning = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- saves data to be utilized on next login
|
||||
local temp_pool
|
||||
local save_data = function(name)
|
||||
if type(player) ~= "string" and player:is_player() then
|
||||
name = name:get_player_name()
|
||||
end
|
||||
temp_pool = pool[name]
|
||||
|
||||
mod_storage:set_float(name.."breath", temp_pool.breath)
|
||||
mod_storage:set_float(name.."breath_ticker", temp_pool.ticker)
|
||||
mod_storage:set_float(name.."breath", temp_pool.drowning)
|
||||
mod_storage:set_int(name.."d_save", 1)
|
||||
|
||||
pool[name] = nil
|
||||
end
|
||||
|
||||
-- is used for shutdowns to save all data
|
||||
local save_all = function()
|
||||
for name,_ in pairs(pool) do
|
||||
save_data(name)
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
|
||||
@ -195,120 +97,100 @@ minetest.hud_replace_builtin("breath",{
|
||||
size = {x = 0, y = 0},
|
||||
offset = {x = 0, y= 0},
|
||||
})
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local data = drowning_class.load_data(player)
|
||||
drowning_class.set_data(player,data)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
load_data(player)
|
||||
player:hud_set_flags({breathbar=false})
|
||||
end)
|
||||
|
||||
-- saves specific users data for when they relog
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
drowning_class.save_data(player)
|
||||
drowning_class.terminate(player)
|
||||
save_data(player)
|
||||
end)
|
||||
|
||||
-- save all data to mod storage on shutdown
|
||||
minetest.register_on_shutdown(function()
|
||||
drowning_class.save_all()
|
||||
save_all()
|
||||
end)
|
||||
|
||||
local name
|
||||
is_player_drowning = function(player)
|
||||
name = player:get_player_name()
|
||||
return(pool[name].drowning)
|
||||
end
|
||||
|
||||
-- reset the player's data
|
||||
local name
|
||||
local temp_pool
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
drowning_class.set_data(player,{
|
||||
breath = 20,
|
||||
breath_ticker = 0 ,
|
||||
drowning = 0 ,
|
||||
})
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
temp_pool.breath = 21
|
||||
temp_pool.ticker = 0
|
||||
temp_pool.drowning = 0
|
||||
update_breath_bar(player,temp_pool.breath)
|
||||
end)
|
||||
|
||||
--handle the breath bar
|
||||
drowning_class.handle_breath = function(dtime)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
local name
|
||||
local temp_pool
|
||||
local head
|
||||
local hp
|
||||
local handle_breath = function(player,dtime)
|
||||
name = player:get_player_name()
|
||||
head = get_player_head_env(player)
|
||||
temp_pool = pool[name]
|
||||
hp = player:get_hp()
|
||||
if hp <= 0 then
|
||||
return
|
||||
end
|
||||
if minetest.get_item_group(head, "drowning") > 0 then
|
||||
|
||||
local data = environment_pointer.get_data(player,{"head"})
|
||||
temp_pool.ticker = temp_pool.ticker + dtime
|
||||
|
||||
if data then
|
||||
data = data.head
|
||||
if temp_pool.breath > 0 and temp_pool.ticker >= 1.3 then
|
||||
|
||||
if temp_pool.breath == 21 then
|
||||
temp_pool.breath = 20
|
||||
end
|
||||
temp_pool.breath = temp_pool.breath - 2
|
||||
|
||||
temp_pool.drowning = 0
|
||||
|
||||
update_breath_bar(player,temp_pool.breath)
|
||||
elseif temp_pool.breath <= 0 and temp_pool.ticker >= 1.3 then
|
||||
|
||||
temp_pool.drowning = 1
|
||||
|
||||
if hp > 0 then
|
||||
player:set_hp( hp - 2 )
|
||||
end
|
||||
end
|
||||
|
||||
if drowning_class.get_group(data, "drowning") > 0 then
|
||||
if temp_pool.ticker >= 1.3 then
|
||||
temp_pool.ticker = 0
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
temp_pool.ticker = temp_pool.ticker + dtime
|
||||
|
||||
if temp_pool.breath < 21 and temp_pool.ticker >= 0.25 then
|
||||
|
||||
drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
|
||||
|
||||
drowning_class.breath = drowning_class.get_data(player,{"breath"})
|
||||
|
||||
if drowning_class.breath then
|
||||
drowning_class.breath = drowning_class.breath.breath
|
||||
end
|
||||
|
||||
if drowning_class.ticker then
|
||||
drowning_class.ticker = drowning_class.ticker.breath_ticker
|
||||
end
|
||||
|
||||
drowning_class.ticker = drowning_class.ticker + dtime
|
||||
temp_pool.breath = temp_pool.breath + 2
|
||||
|
||||
if drowning_class.breath > 0 and drowning_class.ticker >= 1.3 then
|
||||
|
||||
drowning_class.breath = drowning_class.breath - 2
|
||||
|
||||
drowning_class.set_data(player,{breath = drowning_class.breath})
|
||||
|
||||
drowning_class.set_data(player,{drowning = 0})
|
||||
|
||||
elseif drowning_class.breath <= 0 and drowning_class.ticker >= 1.3 then
|
||||
|
||||
drowning_class.set_data(player,{drowning=1})
|
||||
|
||||
local hp = player:get_hp()
|
||||
|
||||
if hp > 0 then
|
||||
player:set_hp(hp-2)
|
||||
end
|
||||
end
|
||||
|
||||
if drowning_class.ticker >= 1.3 then
|
||||
drowning_class.ticker = 0
|
||||
end
|
||||
|
||||
drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
|
||||
temp_pool.drowning = 0
|
||||
|
||||
else
|
||||
temp_pool.ticker = 0
|
||||
|
||||
drowning_class.breath = drowning_class.get_data(player,{"breath"})
|
||||
|
||||
drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
|
||||
|
||||
if drowning_class.ticker then
|
||||
drowning_class.ticker = drowning_class.ticker.breath_ticker
|
||||
end
|
||||
|
||||
if drowning_class.breath then
|
||||
drowning_class.breath = drowning_class.breath.breath
|
||||
end
|
||||
|
||||
drowning_class.ticker = drowning_class.ticker + dtime
|
||||
|
||||
if drowning_class.breath < 21 and drowning_class.ticker >= 0.25 then
|
||||
|
||||
drowning_class.breath = drowning_class.breath + 2
|
||||
|
||||
drowning_class.set_data(player,{
|
||||
breath = drowning_class.breath,
|
||||
drowning = 0,
|
||||
breath_ticker = 0,
|
||||
})
|
||||
elseif drowning_class.breath < 21 then
|
||||
drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
|
||||
else
|
||||
drowning_class.set_data(player,{breath_ticker = 0})
|
||||
end
|
||||
update_breath_bar(player,temp_pool.breath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- inject into main loop
|
||||
minetest.register_globalstep(function(dtime)
|
||||
drowning_class.handle_breath(dtime)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
handle_breath(player,dtime)
|
||||
end
|
||||
end)
|
@ -1,127 +1,58 @@
|
||||
local minetest,math,ItemStack =
|
||||
minetest,math,ItemStack
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
local player_hunger_data = {} -- array to hold hunger data
|
||||
local hunger_class = {}
|
||||
hunger_pointer = {} -- allow other mods to access local data
|
||||
hunger_class.data = nil
|
||||
hunger_class.drowning = nil
|
||||
hunger_class.hp = nil
|
||||
hunger_class.name = nil
|
||||
hunger_class.i_data = nil
|
||||
hunger_class.count = nil
|
||||
hunger_class.food_data = {}
|
||||
hunger_class.pairs = pairs
|
||||
hunger_class.ipairs = ipairs
|
||||
hunger_class.get_connected = minetest.get_connected_players
|
||||
hunger_class.get_group = minetest.get_item_group
|
||||
local minetest,math = minetest,math
|
||||
|
||||
--this is the max exhaustion a player will get before their
|
||||
--satiation goes down and rolls over
|
||||
hunger_class.exhaustion_peak = 512
|
||||
--when satiation runs out this is when the hunger peak variable
|
||||
--is used, everytime the player rolls over this their hunger ticks down
|
||||
--based on what they're doing
|
||||
hunger_class.hunger_peak = 128
|
||||
local mod_storage = minetest.get_mod_storage()
|
||||
local pool = {}
|
||||
|
||||
-- creates volitile data for the game to use
|
||||
hunger_class.set_data = function(player,data)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if not player_hunger_data[hunger_class.name] then
|
||||
player_hunger_data[hunger_class.name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in hunger_class.pairs(data) do
|
||||
player_hunger_data[hunger_class.name][index] = i_data
|
||||
end
|
||||
|
||||
if data.hunger then
|
||||
hud_manager.change_hud({
|
||||
player = player ,
|
||||
hud_name = "hunger",
|
||||
element = "number",
|
||||
data = data.hunger
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- dynamic indexing
|
||||
hunger_class.get_data = function(player,requested_data)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if player_hunger_data[hunger_class.name] then
|
||||
hunger_class.i_data = {}
|
||||
hunger_class.count = 0
|
||||
for _,i_data in hunger_class.pairs(requested_data) do
|
||||
if player_hunger_data[hunger_class.name][i_data] then
|
||||
hunger_class.i_data[i_data] = player_hunger_data[hunger_class.name][i_data]
|
||||
hunger_class.count = hunger_class.count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if hunger_class.count > 0 then
|
||||
return(hunger_class.i_data)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
-- removes hunger data
|
||||
hunger_class.terminate = function(player)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if player_hunger_data[hunger_class.name] then
|
||||
player_hunger_data[hunger_class.name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- loads data from mod storage
|
||||
hunger_class.load_data = function(player)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if mod_storage:get_int(hunger_class.name.."h_save") > 0 then
|
||||
return({
|
||||
hunger = mod_storage:get_int(hunger_class.name.."hunger" ),
|
||||
satiation = mod_storage:get_int(hunger_class.name.."satiation" ),
|
||||
exhaustion = mod_storage:get_int(hunger_class.name.."exhaustion" ),
|
||||
regeneration_interval = mod_storage:get_int(hunger_class.name.."regeneration_interval")
|
||||
})
|
||||
local name
|
||||
local temp_pool
|
||||
local load_data = function(player)
|
||||
name = player:get_player_name()
|
||||
pool[name] = {}
|
||||
temp_pool = pool[name]
|
||||
if mod_storage:get_int(name.."h_save") > 0 then
|
||||
temp_pool.hunger = mod_storage:get_int(name.."hunger" )
|
||||
temp_pool.satiation = mod_storage:get_int(name.."satiation" )
|
||||
temp_pool.exhaustion = mod_storage:get_int(name.."exhaustion" )
|
||||
temp_pool.regeneration_interval = mod_storage:get_int(name.."regeneration_interval")
|
||||
else
|
||||
return({
|
||||
hunger = 20,
|
||||
satiation = 20,
|
||||
regeneration_interval = 0,
|
||||
exhaustion = 0
|
||||
})
|
||||
temp_pool.hunger = 20
|
||||
temp_pool.satiation = 20
|
||||
temp_pool.regeneration_interval = 0
|
||||
temp_pool.exhaustion = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- saves data to be utilized on next login
|
||||
hunger_class.save_data = function(player)
|
||||
local name
|
||||
local temp_pool
|
||||
local save_data = function(player)
|
||||
if type(player) ~= "string" and player:is_player() then
|
||||
hunger_class.name = player:get_player_name()
|
||||
elseif type(player) == "string" then
|
||||
hunger_class.name = player
|
||||
end
|
||||
if player_hunger_data[hunger_class.name] then
|
||||
for index,integer in hunger_class.pairs(player_hunger_data[hunger_class.name]) do
|
||||
mod_storage:set_int(hunger_class.name..index,integer)
|
||||
end
|
||||
name = player:get_player_name()
|
||||
end
|
||||
temp_pool = pool[name]
|
||||
|
||||
mod_storage:set_int(name.."hunger", temp_pool.hunger )
|
||||
mod_storage:set_int(name.."satiation", temp_pool.satiation )
|
||||
mod_storage:set_int(name.."exhaustion", temp_pool.exhaustion )
|
||||
mod_storage:set_int(name.."regeneration_interval",temp_pool.regeneration_interval)
|
||||
|
||||
mod_storage:set_int(hunger_class.name.."h_save", 1)
|
||||
mod_storage:set_int(name.."h_save",1)
|
||||
|
||||
player_hunger_data[hunger_class.name] = nil
|
||||
player_hunger_data[name] = nil
|
||||
end
|
||||
|
||||
|
||||
-- is used for shutdowns to save all data
|
||||
hunger_class.save_all = function()
|
||||
for name,data in hunger_class.pairs(player_hunger_data) do
|
||||
hunger_class.save_data(name)
|
||||
local save_all = function()
|
||||
for name,_ in pairs(pool) do
|
||||
save_data(name)
|
||||
end
|
||||
end
|
||||
|
||||
-- an easy translation pool
|
||||
hunger_class.satiation_pool = {
|
||||
local satiation_pool = {
|
||||
[0] = 1,
|
||||
[0.5] = 3,
|
||||
[1] = 6,
|
||||
@ -129,12 +60,12 @@ hunger_class.satiation_pool = {
|
||||
[3] = 1
|
||||
}
|
||||
-- ticks up the exhaustion when counting down satiation
|
||||
hunger_class.tick_up_satiation = function(m_data,exhaustion)
|
||||
return(exhaustion + hunger_class.satiation_pool[m_data])
|
||||
local tick_up_satiation = function(state,exhaustion)
|
||||
return(exhaustion + satiation_pool[state])
|
||||
end
|
||||
|
||||
-- an easy translation pool
|
||||
hunger_class.hunger_pool = {
|
||||
local hunger_pool = {
|
||||
[0] = 1,
|
||||
[0.5] = 2,
|
||||
[1] = 3,
|
||||
@ -142,70 +73,33 @@ hunger_class.hunger_pool = {
|
||||
[3] = 1
|
||||
}
|
||||
-- ticks up the exhaustion when counting down hunger
|
||||
hunger_class.tick_up_hunger = function(m_data,exhaustion)
|
||||
return(exhaustion + hunger_class.hunger_pool[m_data])
|
||||
local tick_up_hunger = function(state,exhaustion)
|
||||
return(exhaustion + hunger_pool[state])
|
||||
end
|
||||
|
||||
-- allows other mods to set hunger data
|
||||
hunger_pointer.set_data = function(player,data)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if not player_hunger_data[hunger_class.name] then
|
||||
player_hunger_data[hunger_class.name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in hunger_class.pairs(data) do
|
||||
player_hunger_data[hunger_class.name][index] = i_data
|
||||
end
|
||||
|
||||
if data.hunger then
|
||||
hud_manager.change_hud({
|
||||
player = player ,
|
||||
hud_name = "hunger",
|
||||
element = "number",
|
||||
data = data.hunger
|
||||
})
|
||||
end
|
||||
local name
|
||||
get_player_hunger = function(player)
|
||||
name = player:get_player_name()
|
||||
return(20)
|
||||
end
|
||||
|
||||
-- allows other mods to index hunger data
|
||||
hunger_pointer.get_data = function(player,requested_data)
|
||||
hunger_class.name = player:get_player_name()
|
||||
if player_hunger_data[hunger_class.name] then
|
||||
hunger_class.i_data = {}
|
||||
hunger_class.count = 0
|
||||
for _,i_data in hunger_class.pairs(requested_data) do
|
||||
if player_hunger_data[hunger_class.name][i_data] then
|
||||
hunger_class.i_data[i_data] = player_hunger_data[hunger_class.name][i_data]
|
||||
hunger_class.count = hunger_class.count + 1
|
||||
end
|
||||
end
|
||||
if hunger_class.count > 0 then
|
||||
return(hunger_class.i_data)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
-- saves specific users data for when they relog
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
hunger_class.save_data(player)
|
||||
hunger_class.terminate(player)
|
||||
save_data(player)
|
||||
end)
|
||||
|
||||
-- save all data to mod storage on shutdown
|
||||
minetest.register_on_shutdown(function()
|
||||
hunger_class.save_all()
|
||||
save_all()
|
||||
end)
|
||||
|
||||
-- create new data for hunger per player
|
||||
local name
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
hunger_class.name = player:get_player_name()
|
||||
hunger_class.data = hunger_class.load_data(player)
|
||||
|
||||
hunger_class.set_data(player,hunger_class.data)
|
||||
|
||||
name = player:get_player_name()
|
||||
load_data(player)
|
||||
hud_manager.add_hud(player,"hunger_bg",{
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
@ -219,7 +113,7 @@ minetest.register_on_joinplayer(function(player)
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
text = "hunger_icon.png",
|
||||
number = hunger_class.data.hunger,
|
||||
number = pool[name].hunger,
|
||||
direction = 1,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = 24*10, y= -(48 + 24 + 39)},
|
||||
@ -227,107 +121,116 @@ minetest.register_on_joinplayer(function(player)
|
||||
end)
|
||||
|
||||
-- resets the players hunger settings to max
|
||||
local name
|
||||
local temp_pool
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
hunger_class.set_data(player,{
|
||||
hunger = 20,
|
||||
satiation = 20,
|
||||
regeneration_interval = 0,
|
||||
exhaustion = 0,
|
||||
})
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
temp_pool.hunger = 20
|
||||
temp_pool.satiation = 20
|
||||
temp_pool.regeneration_interval = 0
|
||||
temp_pool.exhaustion = 0
|
||||
end)
|
||||
|
||||
|
||||
local function hunger_update()
|
||||
for _,player in hunger_class.ipairs(hunger_class.get_connected()) do
|
||||
local exhaustion_peak = 512
|
||||
local hunger_peak = 128
|
||||
local temp_pool
|
||||
local state
|
||||
local input
|
||||
local hp
|
||||
local drowning
|
||||
hunger_update = function()
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
--do not regen player's health if dead - this will be reused for 1up apples
|
||||
if player:get_hp() > 0 then
|
||||
|
||||
|
||||
hunger_class.data = hunger_class.get_data(player,{
|
||||
"hunger","satiation","exhaustion","regeneration_interval"
|
||||
})
|
||||
|
||||
print(dump(hunger_class.data))
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
--movement state
|
||||
local m_data = movement_pointer.get_data(player,{"state"})
|
||||
if m_data then
|
||||
m_data = m_data.state
|
||||
end
|
||||
|
||||
state = get_player_state(player)
|
||||
|
||||
-- if player is moving in state 0 add 0.5
|
||||
if m_data == 0 then
|
||||
local input = player:get_player_control()
|
||||
if state == 0 then
|
||||
input = player:get_player_control()
|
||||
if input.jump or input.right or input.left or input.down or input.up then
|
||||
m_data = 0.5
|
||||
state = 0.5
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- count down invisible satiation bar
|
||||
if hunger_class.data.satiation > 0 and hunger_class.data.hunger >= 20 then
|
||||
hunger_class.data.exhaustion = hunger_class.tick_up_satiation(m_data, hunger_class.data.exhaustion)
|
||||
if hunger_class.data.exhaustion >= hunger_class.exhaustion_peak then
|
||||
if temp_pool.satiation > 0 and temp_pool.hunger >= 20 then
|
||||
|
||||
hunger_class.data.satiation = hunger_class.data.satiation - 1
|
||||
hunger_class.data.exhaustion = hunger_class.data.exhaustion - hunger_class.exhaustion_peak
|
||||
temp_pool.exhaustion = tick_up_satiation(state, temp_pool.exhaustion)
|
||||
|
||||
if temp_pool.exhaustion > exhaustion_peak then
|
||||
|
||||
temp_pool.satiation = temp_pool.satiation - 1
|
||||
|
||||
temp_pool.exhaustion = temp_pool.exhaustion - exhaustion_peak
|
||||
|
||||
--reset this to use for the hunger tick
|
||||
if hunger_class.data.satiation == 0 then
|
||||
hunger_class.data.exhaustion = 0
|
||||
if temp_pool.satiation == 0 then
|
||||
temp_pool.exhaustion = 0
|
||||
end
|
||||
end
|
||||
-- count down hunger bars
|
||||
elseif temp_pool.hunger > 0 then
|
||||
|
||||
temp_pool.exhaustion = tick_up_hunger(state,temp_pool.exhaustion)
|
||||
|
||||
if temp_pool.exhaustion >= hunger_peak then
|
||||
--don't allow hunger to go negative
|
||||
if temp_pool.hunger > 0 then
|
||||
|
||||
temp_pool.exhaustion = temp_pool.exhaustion - hunger_peak
|
||||
|
||||
temp_pool.hunger = temp_pool.hunger - 1
|
||||
|
||||
end
|
||||
|
||||
hunger_class.set_data(player,{satiation=hunger_class.data.satiation})
|
||||
hud_manager.change_hud({
|
||||
player = player ,
|
||||
hud_name = "hunger",
|
||||
element = "number",
|
||||
data = temp_pool.hunger
|
||||
})
|
||||
end
|
||||
hunger_class.set_data(player,{exhaustion=hunger_class.data.exhaustion})
|
||||
-- count down hunger bars
|
||||
elseif hunger_class.data.hunger > 0 then
|
||||
hunger_class.data.exhaustion = hunger_class.tick_up_hunger(m_data,hunger_class.data.exhaustion)
|
||||
|
||||
if hunger_class.data.exhaustion >= hunger_class.hunger_peak then
|
||||
--don't allow hunger to go negative
|
||||
if hunger_class.data.hunger > 0 then
|
||||
hunger_class.data.exhaustion = hunger_class.data.exhaustion - hunger_class.hunger_peak
|
||||
hunger_class.data.hunger = hunger_class.data.hunger - 1
|
||||
hunger_class.set_data(player,{hunger=hunger_class.data.hunger})
|
||||
end
|
||||
end
|
||||
hunger_class.set_data(player,{exhaustion=hunger_class.data.exhaustion})
|
||||
-- hurt the player if hunger bar empty
|
||||
elseif hunger_class.data.hunger <= 0 then
|
||||
hunger_class.data.exhaustion = hunger_class.data.exhaustion + 1
|
||||
local hp = player:get_hp()
|
||||
if hp > 0 and hunger_class.data.exhaustion >= 2 then
|
||||
player:set_hp(hp-1)
|
||||
hunger_class.data.exhaustion = 0
|
||||
end
|
||||
hunger_class.set_data(player,{exhaustion=hunger_class.data.exhaustion})
|
||||
elseif temp_pool.hunger <= 0 then
|
||||
|
||||
temp_pool.exhaustion = temp_pool.exhaustion + 1
|
||||
|
||||
hp = player:get_hp()
|
||||
|
||||
if hp > 0 and temp_pool.exhaustion >= 2 then
|
||||
player:set_hp( hp - 1 )
|
||||
temp_pool.exhaustion = 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
hunger_class.hp = player:get_hp()
|
||||
hunger_class.drowning = drowning_pointer.get_data(player,{"drowning"}).drowning
|
||||
hp = player:get_hp()
|
||||
|
||||
drowning = is_player_drowning(player)
|
||||
|
||||
--make regeneration happen every second
|
||||
if hunger_class.drowning == 0 and hunger_class.data.hunger >= 20 and hunger_class.hp < 20 then -- meta:get_int("on_fire") == 0
|
||||
--print(regeneration_interval,"--------------------------")
|
||||
hunger_class.data.regeneration_interval = hunger_class.data.regeneration_interval + 1
|
||||
if hunger_class.data.regeneration_interval >= 2 then
|
||||
player:set_hp(hunger_class.hp+1)
|
||||
hunger_class.data.exhaustion = hunger_class.data.exhaustion + 32
|
||||
hunger_class.data.regeneration_interval = 0
|
||||
|
||||
hunger_class.set_data(player,{
|
||||
regeneration_interval = hunger_class.data.regeneration_interval,
|
||||
exhaustion = hunger_class.data.exhaustion ,
|
||||
satiation = hunger_class.data.satiation ,
|
||||
})
|
||||
else
|
||||
hunger_class.set_data(player,{regeneration_interval=hunger_class.data.regeneration_interval})
|
||||
if drowning == 0 and temp_pool.hunger >= 20 and hp < 20 then -- meta:get_int("on_fire") == 0
|
||||
|
||||
temp_pool.regeneration_interval = temp_pool.regeneration_interval + 1
|
||||
|
||||
if temp_pool.regeneration_interval >= 2 then
|
||||
|
||||
player:set_hp( hp + 1 )
|
||||
|
||||
temp_pool.exhaustion = temp_pool.exhaustion + 32
|
||||
|
||||
temp_pool.regeneration_interval = 0
|
||||
|
||||
end
|
||||
--reset the regen interval
|
||||
else
|
||||
hunger_class.set_data(player,{regeneration_interval=0})
|
||||
temp_pool.regeneration_interval = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -338,34 +241,37 @@ local function hunger_update()
|
||||
end
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
minetest.after(0,function()
|
||||
minetest.after(0.5,function()
|
||||
hunger_update()
|
||||
end)
|
||||
end)
|
||||
|
||||
--take away hunger and satiation randomly while mining
|
||||
local name
|
||||
minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
if digger and digger:is_player() then
|
||||
hunger_class.set_data(digger,{
|
||||
exhaustion = hunger_class.get_data(digger,{"exhaustion"}).exhaustion + math.random(0,2)
|
||||
})
|
||||
name = digger:get_player_name()
|
||||
pool[name].exhaustion = pool[name].exhaustion + math.random(0,2)
|
||||
end
|
||||
end)
|
||||
|
||||
-- take the eaten food
|
||||
hunger_class.take_food = function(player)
|
||||
hunger_class.data = player:get_wielded_item()
|
||||
hunger_class.data:take_item()
|
||||
player:set_wielded_item(hunger_class.data)
|
||||
local item
|
||||
local take_food = function(player)
|
||||
item = player:get_wielded_item()
|
||||
item:take_item()
|
||||
player:set_wielded_item(item)
|
||||
end
|
||||
|
||||
-- players eat food
|
||||
hunger_pointer.eat_food = function(player,item)
|
||||
hunger_class.data = hunger_class.get_data(player,{
|
||||
"hunger" ,
|
||||
"satiation",
|
||||
})
|
||||
|
||||
local name
|
||||
local temp_pool
|
||||
local item
|
||||
local satiation
|
||||
local hunger
|
||||
player_eat_food = function(player,item)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
if type(item) == "string" then
|
||||
item = ItemStack(item)
|
||||
elseif type(item) == "table" then
|
||||
@ -373,25 +279,20 @@ hunger_pointer.eat_food = function(player,item)
|
||||
end
|
||||
item = item:get_name()
|
||||
|
||||
hunger_class.food_data.satiation = hunger_class.get_group( item, "satiation" )
|
||||
hunger_class.food_data.hunger = hunger_class.get_group( item, "hunger" )
|
||||
satiation = minetest.get_item_group( item, "satiation" )
|
||||
hunger = minetest.get_item_group( item, "hunger" )
|
||||
|
||||
hunger_class.data.hunger = hunger_class.data.hunger + hunger_class.food_data.hunger
|
||||
temp_pool.hunger = temp_pool.hunger + hunger
|
||||
|
||||
if hunger_class.data.hunger > 20 then
|
||||
hunger_class.data.hunger = 20
|
||||
if temp_pool.hunger > 20 then
|
||||
temp_pool.hunger = 20
|
||||
end
|
||||
|
||||
-- unlimited
|
||||
-- this makes the game easier
|
||||
hunger_class.data.satiation = hunger_class.data.satiation + hunger_class.food_data.satiation
|
||||
temp_pool.satiation = temp_pool.satiation + satiation
|
||||
|
||||
hunger_class.set_data(player,{
|
||||
hunger = hunger_class.data.hunger ,
|
||||
satiation = hunger_class.data.satiation,
|
||||
})
|
||||
|
||||
hunger_class.take_food(player)
|
||||
take_food(player)
|
||||
end
|
||||
|
||||
-- easily allows mods to register food
|
||||
@ -414,11 +315,9 @@ minetest.register_chatcommand("hungry", {
|
||||
description = "A debug command to test food",
|
||||
privs = {server = true},
|
||||
func = function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
hunger_class.set_data(player,{
|
||||
exhaustion = 0,
|
||||
hunger = 1,
|
||||
satiation = 0
|
||||
})
|
||||
local temp_pool = pool[name]
|
||||
temp_pool.exhaustion = 0
|
||||
temp_pool.hunger = 1
|
||||
temp_pool.satiation = 0
|
||||
end
|
||||
})
|
||||
|
@ -1,255 +1,132 @@
|
||||
local minetest,math,vector,table = minetest,math,vector,table
|
||||
|
||||
local environment_class = {} -- environment class
|
||||
local pool = {}
|
||||
|
||||
environment_pointer = {} -- allows other mods to index
|
||||
|
||||
local player_environment = {} -- stores environment data per player
|
||||
|
||||
environment_class.registered_nodes = {} -- stored registered nodes into local table
|
||||
|
||||
environment_class.get_group = minetest.get_item_group
|
||||
|
||||
environment_class.get_node = minetest.get_node
|
||||
|
||||
environment_class.hurt_nodes = {}
|
||||
|
||||
environment_class.tick = nil
|
||||
|
||||
-- creates volitile player environment data for the game to use
|
||||
environment_class.set_data = function(player,data)
|
||||
local name = player:get_player_name()
|
||||
if not player_environment[name] then
|
||||
player_environment[name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in pairs(data) do
|
||||
player_environment[name][index] = i_data
|
||||
end
|
||||
local name
|
||||
get_player_head_env = function(player)
|
||||
name = player:get_player_name()
|
||||
return(pool[name].head)
|
||||
end
|
||||
|
||||
-- indexes player environment data and returns it
|
||||
environment_class.get_data = function(player,requested_data)
|
||||
local name = player:get_player_name()
|
||||
if player_environment[name] then
|
||||
local data_list = {}
|
||||
local count = 0
|
||||
for index,i_data in pairs(requested_data) do
|
||||
if player_environment[name][i_data] then
|
||||
data_list[i_data] = player_environment[name][i_data]
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > 0 then
|
||||
return(data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
local name
|
||||
get_player_legs_env = function(player)
|
||||
name = player:get_player_name()
|
||||
return(pool[name].legs)
|
||||
end
|
||||
|
||||
-- removes player environment data
|
||||
environment_class.terminate = function(player)
|
||||
local name = player:get_player_name()
|
||||
if player_environment[name] then
|
||||
player_environment[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- create blank list for player environment data
|
||||
local name
|
||||
local temp_pool
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
environment_class.set_data(player,{})
|
||||
name = player:get_player_name()
|
||||
pool[name] = {}
|
||||
temp_pool = pool[name]
|
||||
|
||||
temp_pool.under = ""
|
||||
temp_pool.legs = ""
|
||||
temp_pool.head = ""
|
||||
temp_pool.touch_hurt_ticker = 0
|
||||
temp_pool.hurt_inside_ticker = 0
|
||||
end)
|
||||
|
||||
-- destroy player environment data
|
||||
local name
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
environment_class.terminate(player)
|
||||
name = player:get_player_name()
|
||||
pool[name] = nil
|
||||
end)
|
||||
|
||||
-- creates smaller table of "touch_hurt" nodes
|
||||
minetest.register_on_mods_loaded(function()
|
||||
environment_class.registered_nodes = table.copy(minetest.registered_nodes)
|
||||
for _,def in pairs(environment_class.registered_nodes) do
|
||||
if environment_class.get_group(def.name, "touch_hurt") > 0 then
|
||||
table.insert(environment_class.hurt_nodes,def.name)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--reset their drowning settings
|
||||
--minetest.register_on_dieplayer(function(ObjectRef, reason))
|
||||
|
||||
|
||||
-- handle damage when touching node
|
||||
-- this is lua collision detection
|
||||
local collision_class = {}
|
||||
collision_class.player_pos = nil
|
||||
collision_class.damage_nodes = nil
|
||||
collision_class.a_min = nil
|
||||
collision_class.a_max = nil
|
||||
collision_class.damage_amount = nil
|
||||
collision_class.gotten_node = nil
|
||||
collision_class.tick = nil
|
||||
collision_class.table_max = table.getn
|
||||
collision_class.subtract = vector.subtract
|
||||
collision_class.add = vector.add
|
||||
collision_class.new = vector.new
|
||||
collision_class.abs = math.abs
|
||||
collision_class.floor = math.floor
|
||||
collision_class.find = minetest.find_nodes_in_area
|
||||
collision_class.get_node = minetest.get_node
|
||||
collision_class.get_group = minetest.get_item_group
|
||||
|
||||
collision_class.hurt_collide = function(player,dtime)
|
||||
pos = nil
|
||||
name = nil
|
||||
damage_nodes = nil
|
||||
a_min = nil
|
||||
a_max = nil
|
||||
damage_amount = nil
|
||||
gotten_node = nil
|
||||
tick = nil
|
||||
local hurt_collide = function(player,dtime)
|
||||
name = player:get_player_name()
|
||||
if player:get_hp() <= 0 then
|
||||
return
|
||||
end
|
||||
--used for finding a damage node from the center of the player
|
||||
collision_class.player_pos = player:get_pos()
|
||||
collision_class.player_pos.y = collision_class.player_pos.y + (player:get_properties().collisionbox[5]/2)
|
||||
collision_class.a_min = collision_class.new(
|
||||
collision_class.player_pos.x-0.25,
|
||||
collision_class.player_pos.y-0.9,
|
||||
collision_class.player_pos.z-0.25
|
||||
-- used for finding a damage node from the center of the player
|
||||
-- rudementary collision detection
|
||||
pos = player:get_pos()
|
||||
pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
|
||||
a_min = vector.new(
|
||||
pos.x-0.25,
|
||||
pos.y-0.9,
|
||||
pos.z-0.25
|
||||
)
|
||||
collision_class.a_max = collision_class.new(
|
||||
collision_class.player_pos.x+0.25,
|
||||
collision_class.player_pos.y+0.9,
|
||||
collision_class.player_pos.z+0.25
|
||||
a_max = vector.new(
|
||||
pos.x+0.25,
|
||||
pos.y+0.9,
|
||||
pos.z+0.25
|
||||
)
|
||||
|
||||
collision_class.damage_nodes = collision_class.find(collision_class.a_min, collision_class.a_max, {"group:touch_hurt"})
|
||||
_,damage_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:touch_hurt"})
|
||||
|
||||
collision_class.hurt = 0
|
||||
collision_class.damage_amount = nil
|
||||
collision_class.gotten_node = nil
|
||||
collision_class.damage_amount = nil
|
||||
|
||||
if collision_class.table_max(collision_class.damage_nodes) > 0 then
|
||||
for _,found_location in ipairs(collision_class.damage_nodes) do
|
||||
|
||||
collision_class.gotten_node = collision_class.get_node(found_location).name
|
||||
|
||||
collision_class.damage_amount = collision_class.get_group(collision_class.gotten_node, "touch_hurt")
|
||||
|
||||
if collision_class.damage_amount > collision_class.hurt then
|
||||
collision_class.hurt = collision_class.damage_amount
|
||||
hurt = 0
|
||||
-- find the highest damage node
|
||||
if table.getn(damage_nodes) > 0 then
|
||||
for node,_ in ipairs(damage_nodes) do
|
||||
damage_amount = minetest.get_item_group(node, "touch_hurt")
|
||||
if damage_amount > hurt then
|
||||
hurt = damage_amount
|
||||
end
|
||||
end
|
||||
collision_class.handle_touch_hurting(player,collision_class.damage_amount,dtime)
|
||||
handle_touch_hurting(player,damage_amount,dtime)
|
||||
else
|
||||
environment_class.set_data(player,{hurt_ticker = 0})
|
||||
pool[name].touch_hurt_ticker = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- damages players 4 times a second
|
||||
collision_class.handle_touch_hurting = function(player,damage,dtime)
|
||||
collision_class.tick = environment_class.get_data(player,{"hurt_ticker"})
|
||||
if collision_class.tick then
|
||||
collision_class.tick = collision_class.tick.hurt_ticker
|
||||
end
|
||||
if not collision_class.tick then
|
||||
environment_class.set_data(player,{hurt_ticker = 0.25})
|
||||
local name
|
||||
local temp_pool
|
||||
local tick
|
||||
handle_touch_hurting = function(player,damage,dtime)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
tick = temp_pool.touch_hurt_ticker
|
||||
|
||||
tick = tick - dtime
|
||||
if tick <= 0 then
|
||||
player:set_hp(player:get_hp()-damage)
|
||||
else
|
||||
collision_class.tick = collision_class.tick - dtime
|
||||
if collision_class.tick <= 0 then
|
||||
player:set_hp(player:get_hp()-damage)
|
||||
environment_class.set_data(player,{hurt_ticker = 0.25})
|
||||
else
|
||||
environment_class.set_data(player,{hurt_ticker = collision_class.tick})
|
||||
end
|
||||
tick = 0.25
|
||||
end
|
||||
temp_pool.touch_hurt_ticker = tick
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
-- handles being inside a hurt node
|
||||
collision_class.hurt_inside = function(player,dtime)
|
||||
set_on_fire = function(player,dtime)
|
||||
if player:get_hp() <= 0 then
|
||||
return
|
||||
end
|
||||
--used for finding a damage node from the center of the player
|
||||
collision_class.player_pos = player:get_pos()
|
||||
collision_class.player_pos.y = collision_class.player_pos.y + (player:get_properties().collisionbox[5]/2)
|
||||
collision_class.a_min = collision_class.new(
|
||||
collision_class.player_pos.x-0.25,
|
||||
collision_class.player_pos.y-0.85,
|
||||
collision_class.player_pos.z-0.25
|
||||
pos = player:get_pos()
|
||||
pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
|
||||
a_min = new(
|
||||
pos.x-0.25,
|
||||
pos.y-0.85,
|
||||
pos.z-0.25
|
||||
)
|
||||
collision_class.a_max = collision_class.new(
|
||||
collision_class.player_pos.x+0.25,
|
||||
collision_class.player_pos.y+0.85,
|
||||
collision_class.player_pos.z+0.25
|
||||
a_max = new(
|
||||
pos.x+0.25,
|
||||
pos.y+0.85,
|
||||
pos.z+0.25
|
||||
)
|
||||
|
||||
collision_class.damage_nodes = collision_class.find(collision_class.a_min, collision_class.a_max, {"group:hurt_inside"})
|
||||
damage_nodes = find( a_min, a_max, {"group:hurt_inside"})
|
||||
|
||||
collision_class.hurt = 0
|
||||
collision_class.damage_amount = nil
|
||||
collision_class.gotten_node = nil
|
||||
collision_class.damage_amount = nil
|
||||
|
||||
if collision_class.table_max(collision_class.damage_nodes) > 0 then
|
||||
for _,found_location in ipairs(collision_class.damage_nodes) do
|
||||
|
||||
collision_class.gotten_node = collision_class.get_node(found_location).name
|
||||
|
||||
collision_class.damage_amount = collision_class.get_group(collision_class.gotten_node, "hurt_inside")
|
||||
|
||||
if collision_class.damage_amount > collision_class.hurt then
|
||||
collision_class.hurt = collision_class.damage_amount
|
||||
end
|
||||
end
|
||||
collision_class.handle_inside_hurting(player,collision_class.damage_amount,dtime)
|
||||
else
|
||||
environment_class.set_data(player,{touch_hurt_ticker = 0})
|
||||
end
|
||||
end
|
||||
|
||||
-- damages players 4 times a second
|
||||
collision_class.handle_inside_hurting = function(player,damage,dtime)
|
||||
collision_class.tick = environment_class.get_data(player,{"touch_hurt_ticker"})
|
||||
if collision_class.tick then
|
||||
collision_class.tick = collision_class.tick.touch_hurt_ticker
|
||||
end
|
||||
if not collision_class.tick then
|
||||
environment_class.set_data(player,{touch_hurt_ticker = 0.25})
|
||||
player:set_hp(player:get_hp()-damage)
|
||||
else
|
||||
collision_class.tick = collision_class.tick - dtime
|
||||
if collision_class.tick <= 0 then
|
||||
player:set_hp(player:get_hp()-damage)
|
||||
environment_class.set_data(player,{touch_hurt_ticker = 0.25})
|
||||
else
|
||||
environment_class.set_data(player,{touch_hurt_ticker = collision_class.tick})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- handles being inside a hurt node
|
||||
collision_class.set_on_fire = function(player,dtime)
|
||||
if player:get_hp() <= 0 then
|
||||
return
|
||||
end
|
||||
--used for finding a damage node from the center of the player
|
||||
collision_class.player_pos = player:get_pos()
|
||||
collision_class.player_pos.y = collision_class.player_pos.y + (player:get_properties().collisionbox[5]/2)
|
||||
collision_class.a_min = collision_class.new(
|
||||
collision_class.player_pos.x-0.25,
|
||||
collision_class.player_pos.y-0.85,
|
||||
collision_class.player_pos.z-0.25
|
||||
)
|
||||
collision_class.a_max = collision_class.new(
|
||||
collision_class.player_pos.x+0.25,
|
||||
collision_class.player_pos.y+0.85,
|
||||
collision_class.player_pos.z+0.25
|
||||
)
|
||||
|
||||
collision_class.damage_nodes = collision_class.find(collision_class.a_min, collision_class.a_max, {"group:hurt_inside"})
|
||||
|
||||
if collision_class.table_max(collision_class.damage_nodes) > 0 then
|
||||
for _,found_location in ipairs(collision_class.damage_nodes) do
|
||||
if table_max( damage_nodes) > 0 then
|
||||
for _,found_location in ipairs( damage_nodes) do
|
||||
start_fire(player)
|
||||
end
|
||||
end
|
||||
@ -293,91 +170,54 @@ environment_class.handle_suffocation_hurt = function(player,damage,dtime)
|
||||
end
|
||||
end
|
||||
|
||||
]]--
|
||||
|
||||
-- environment indexing class
|
||||
local index_class = {}
|
||||
index_class.pos = nil
|
||||
index_class.data_table = nil
|
||||
index_class.get_node = minetest.get_node
|
||||
index_class.swimming = nil
|
||||
-- environment indexing
|
||||
|
||||
-- creates data at specific points of the player
|
||||
index_class.index_players_surroundings = function(dtime)
|
||||
local name
|
||||
local temp_pool
|
||||
local pos
|
||||
local swimming
|
||||
|
||||
local index_players_surroundings = function(dtime)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
index_class.pos = player:get_pos()
|
||||
|
||||
index_class.swimming = movement_pointer.get_data(player,{"swimming"})
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
if index_class.swimming then
|
||||
index_class.swimming = index_class.swimming.swimming
|
||||
end
|
||||
pos = player:get_pos()
|
||||
swimming = is_player_swimming(player)
|
||||
|
||||
index_class.data_table = {}
|
||||
|
||||
index_class.pos.y = index_class.pos.y - 0.1
|
||||
index_class.data_table.under = index_class.get_node(index_class.pos).name
|
||||
pos.y = pos.y - 0.1
|
||||
temp_pool.under = minetest.get_node(pos).name
|
||||
|
||||
index_class.pos.y = index_class.pos.y + 0.6
|
||||
index_class.data_table.legs = index_class.get_node(index_class.pos).name
|
||||
pos.y = pos.y + 0.6
|
||||
temp_pool.legs = minetest.get_node(pos).name
|
||||
|
||||
if index_class.swimming then
|
||||
index_class.pos.y = index_class.pos.y + 0.35
|
||||
if swimming then
|
||||
pos.y = pos.y + 0.35
|
||||
else
|
||||
index_class.pos.y = index_class.pos.y + 0.940
|
||||
pos.y = pos.y + 0.940
|
||||
end
|
||||
index_class.data_table.head = index_class.get_node(index_class.pos).name
|
||||
temp_pool.head = minetest.get_node(pos).name
|
||||
|
||||
environment_class.set_data(player,index_class.data_table)
|
||||
--hurt_collide(player,dtime)
|
||||
|
||||
collision_class.hurt_collide(player,dtime)
|
||||
--hurt_inside(player,dtime)
|
||||
|
||||
collision_class.hurt_inside(player,dtime)
|
||||
|
||||
environment_class.handle_player_suffocation(player,dtime)
|
||||
--handle_player_suffocation(player,dtime)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- creates volitile player environment data for the game to use
|
||||
environment_pointer.set_data = function(player,data)
|
||||
local name = player:get_player_name()
|
||||
if not player_environment[name] then
|
||||
player_environment[name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in pairs(data) do
|
||||
player_environment[name][index] = i_data
|
||||
end
|
||||
end
|
||||
|
||||
-- indexes player environment data and returns it
|
||||
environment_pointer.get_data = function(player,requested_data)
|
||||
local name = player:get_player_name()
|
||||
if player_environment[name] then
|
||||
local data_list = {}
|
||||
local count = 0
|
||||
for index,i_data in pairs(requested_data) do
|
||||
if player_environment[name][i_data] then
|
||||
data_list[i_data] = player_environment[name][i_data]
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > 0 then
|
||||
return(data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
-- insert all indexing data into main loop
|
||||
minetest.register_globalstep(function(dtime)
|
||||
index_class.index_players_surroundings(dtime)
|
||||
index_players_surroundings(dtime)
|
||||
end)
|
||||
|
||||
-- a custom helper function
|
||||
function minetest.get_nodedef(nodename, fieldname)
|
||||
minetest.get_nodedef = function(nodename, fieldname)
|
||||
if not minetest.registered_nodes[nodename] then
|
||||
return nil
|
||||
end
|
||||
@ -385,7 +225,7 @@ function minetest.get_nodedef(nodename, fieldname)
|
||||
end
|
||||
|
||||
-- a custom helper function
|
||||
function minetest.get_itemdef(itemname, fieldname)
|
||||
minetest.get_itemdef = function(itemname, fieldname)
|
||||
if not minetest.registered_items[itemname] then
|
||||
return nil
|
||||
end
|
||||
|
@ -1,37 +1,8 @@
|
||||
local minetest,math = minetest,math
|
||||
local api = {} -- api class
|
||||
local wield = {} -- wield item class
|
||||
local player_pool = {} -- holds data about the players
|
||||
player_pointer = {} -- allows other mods to modify player attributes
|
||||
api.registered_models = {}
|
||||
api.animation_blend = 0
|
||||
api.pairs = pairs
|
||||
api.ipairs = ipairs
|
||||
api.name = nil
|
||||
api.item = nil
|
||||
api.item_string = nil
|
||||
api.object = nil
|
||||
api.object_string = nil
|
||||
api.entity = nil
|
||||
api.data_index = nil
|
||||
api.current_animation = nil
|
||||
api.animations = nil
|
||||
api.opacity = nil
|
||||
api.pitch = nil
|
||||
api.control_table = nil
|
||||
api.controls = nil
|
||||
api.old_controls = nil
|
||||
api.update = nil
|
||||
api.player_data = nil
|
||||
api.state = nil
|
||||
api.mouse = nil
|
||||
api.translated = nil
|
||||
api.swimming = nil
|
||||
api.force_update = nil
|
||||
api.pi = math.pi
|
||||
api.get_connected = minetest.get_connected_players
|
||||
local minetest,math = minetest,math
|
||||
local pool = {}
|
||||
|
||||
-- player physical data constant
|
||||
api.player = {
|
||||
local player_constant = {
|
||||
visual = "mesh" ,
|
||||
mesh = "player.b3d" ,
|
||||
animation_speed = 24 ,
|
||||
@ -40,24 +11,6 @@ api.player = {
|
||||
"player.png" ,
|
||||
"blank_skin.png",
|
||||
},
|
||||
|
||||
animations = {
|
||||
stand = { x = 5 , y = 5 },
|
||||
lay = { x = 162, y = 162 },
|
||||
walk = { x = 168, y = 187 },
|
||||
mine = { x = 189, y = 198 },
|
||||
walk_mine = { x = 200, y = 219 },
|
||||
sit = { x = 81 , y = 160 },
|
||||
sneak = { x = 60 , y = 60 },
|
||||
sneak_mine_stand = { x = 20 , y = 30 },
|
||||
sneak_walk = { x = 60 , y = 80 },
|
||||
sneak_mine_walk = { x = 40 , y = 59 },
|
||||
swim = { x = 221, y = 241 },
|
||||
swim_still = { x = 226, y = 226 },
|
||||
die = { x = 242, y = 253 },
|
||||
|
||||
},
|
||||
|
||||
current_animation = "stand",
|
||||
swimming = false,
|
||||
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
|
||||
@ -68,285 +21,207 @@ api.player = {
|
||||
wield_item = nil ,
|
||||
}
|
||||
|
||||
-- allows other mods to register models
|
||||
player_pointer.register_model = function(name, def)
|
||||
models[name] = def
|
||||
end
|
||||
|
||||
-- creates default data for players
|
||||
api.create_data = function(player)
|
||||
api.name = player:get_player_name()
|
||||
if not player_pool[api.name] then
|
||||
player_pool[api.name] = {}
|
||||
end
|
||||
|
||||
for key,data in api.pairs(api.player) do
|
||||
player_pool[api.name][key] = data
|
||||
end
|
||||
end
|
||||
|
||||
-- creates volitile data for the game to use
|
||||
api.set_data = function(player,data)
|
||||
api.name = player:get_player_name()
|
||||
if not player_pool[api.name] then
|
||||
player_pool[api.name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in api.pairs(data) do
|
||||
player_pool[api.name][index] = i_data
|
||||
end
|
||||
end
|
||||
|
||||
-- allows other mods to modify the player
|
||||
player_pointer.set_data = function(player,data)
|
||||
api.name = player:get_player_name()
|
||||
if not player_pool[api.name] then
|
||||
player_pool[api.name] = {}
|
||||
end
|
||||
|
||||
for index,i_data in api.pairs(data) do
|
||||
player_pool[api.name][index] = i_data
|
||||
end
|
||||
|
||||
player:set_properties(data)
|
||||
end
|
||||
|
||||
-- removes data
|
||||
api.terminate = function(player)
|
||||
api.name = player:get_player_name()
|
||||
if player_pool[name] then
|
||||
player_pool[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- indexes and returns data
|
||||
api.get_data = function(player,requested_data)
|
||||
api.name = player:get_player_name()
|
||||
if player_pool[api.name] then
|
||||
local data_list = {}
|
||||
local count = 0
|
||||
for index,i_data in api.pairs(requested_data) do
|
||||
if player_pool[api.name][i_data] then
|
||||
data_list[i_data] = player_pool[api.name][i_data]
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > 0 then
|
||||
return(data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
end
|
||||
|
||||
|
||||
-- set player wield item
|
||||
api.update_wield_item = function(player)
|
||||
api.name = player:get_player_name()
|
||||
|
||||
api.item = api.get_data(player,{"wield_item"})
|
||||
if api.item then
|
||||
api.item = api.item.wield_item
|
||||
end
|
||||
local name
|
||||
local temp_pool
|
||||
local item
|
||||
local object
|
||||
local entity
|
||||
local object_string
|
||||
local update_wield_item = function(player)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
api.item_string = player:get_wielded_item():get_name()
|
||||
object = temp_pool.wield_item
|
||||
|
||||
if not api.item or (api.item and not api.item:get_luaentity()) then
|
||||
item = player:get_wielded_item():get_name()
|
||||
|
||||
if not object or (object and not object:get_luaentity()) then
|
||||
|
||||
api.object = minetest.add_entity(player:get_pos(),"player_api:item")
|
||||
object = minetest.add_entity(player:get_pos(),"player_api:item")
|
||||
|
||||
api.entity = api.object:get_luaentity()
|
||||
entity = object:get_luaentity()
|
||||
|
||||
if api.entity then
|
||||
if entity then
|
||||
|
||||
api.entity:set_item(api.item_string)
|
||||
entity.set_item(entity,item)
|
||||
|
||||
api.entity.wielder = api.name
|
||||
entity.wielder = name
|
||||
|
||||
api.object:set_attach(player, "Right_Hand", vector.new(0,0,0), vector.new(0,0,0))
|
||||
object:set_attach(player, "Right_Hand", vector.new(0,0,0), vector.new(0,0,0))
|
||||
|
||||
api.set_data(player,{
|
||||
wield_item = api.object
|
||||
})
|
||||
temp_pool.wield_item = object
|
||||
end
|
||||
return
|
||||
|
||||
return -- catch it
|
||||
end
|
||||
|
||||
api.entity = api.item:get_luaentity()
|
||||
|
||||
api.object_string = api.entity.itemstring
|
||||
|
||||
if api.entity and api.object_string ~= api.item_string then
|
||||
api.entity.itemstring = player_wield_item
|
||||
api.entity:set_item(player_wield_item)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- easier way to index animation
|
||||
api.get_animation = function(player)
|
||||
api.data_index = api.get_data(player,{"current_animation"})
|
||||
if api.data_index and api.data_index.current_animation then
|
||||
return(api.data_index.current_animation)
|
||||
else
|
||||
return(nil)
|
||||
entity = object:get_luaentity()
|
||||
object_string = entity.itemstring
|
||||
|
||||
if object_string ~= item then
|
||||
entity.itemstring = item
|
||||
entity.set_item(entity,item)
|
||||
end
|
||||
end
|
||||
|
||||
-- easy way to allocate new players
|
||||
api.set_all_properties = function(player)
|
||||
api.player_data = api.get_data(player,{
|
||||
"visual",
|
||||
"mesh",
|
||||
"textures",
|
||||
"collisionbox",
|
||||
"eye_height",
|
||||
"stepheight",
|
||||
"visual_size"
|
||||
})
|
||||
player:set_properties(api.player_data)
|
||||
local data
|
||||
local name
|
||||
local temp_pool
|
||||
|
||||
local set_all_properties = function(player)
|
||||
name = player:get_player_name()
|
||||
pool[name] = {}
|
||||
temp_pool = pool[name]
|
||||
data = {}
|
||||
|
||||
temp_pool.visual = player_constant.visual
|
||||
temp_pool.mesh = player_constant.mesh
|
||||
temp_pool.textures = player_constant.textures
|
||||
temp_pool.collisionbox = player_constant.collisionbox
|
||||
temp_pool.eye_height = player_constant.eye_height
|
||||
temp_pool.stepheight = player_constant.stepheight
|
||||
temp_pool.visual_size = player_constant.visual_size
|
||||
|
||||
player:set_properties(temp_pool)
|
||||
end
|
||||
|
||||
-- easy way to set textures
|
||||
api.set_textures = function(player, textures)
|
||||
api.set_data(player,{
|
||||
texture = textures,
|
||||
})
|
||||
local set_textures = function(player, textures)
|
||||
player:set_properties({textures = textures})
|
||||
end
|
||||
|
||||
-- easy way for other mods to set textures
|
||||
player_pointer.set_textures = function(player,textures)
|
||||
api.set_textures(player,textures)
|
||||
end
|
||||
|
||||
local animation_list = {
|
||||
stand = { x = 5 , y = 5 },
|
||||
lay = { x = 162, y = 162 },
|
||||
walk = { x = 168, y = 187 },
|
||||
mine = { x = 189, y = 198 },
|
||||
walk_mine = { x = 200, y = 219 },
|
||||
sit = { x = 81 , y = 160 },
|
||||
sneak = { x = 60 , y = 60 },
|
||||
sneak_mine_stand = { x = 20 , y = 30 },
|
||||
sneak_walk = { x = 60 , y = 80 },
|
||||
sneak_mine_walk = { x = 40 , y = 59 },
|
||||
swim = { x = 221, y = 241 },
|
||||
swim_still = { x = 226, y = 226 },
|
||||
die = { x = 242, y = 253 },
|
||||
}
|
||||
|
||||
-- easy way to set animation
|
||||
api.set_animation = function(player, animation_name, speed, loop)
|
||||
api.current_animation = api.get_data(player,{"current_animation"})
|
||||
if api.current_animation then
|
||||
api.current_animation = api.current_animation.current_animation
|
||||
end
|
||||
local name
|
||||
local temp_pool
|
||||
local current_animation
|
||||
|
||||
if api.current_animation == animation_name then
|
||||
local set_animation = function(player, animation_name, speed, loop)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
current_animation = temp_pool.animation
|
||||
|
||||
if current_animation == animation_name then
|
||||
return
|
||||
end
|
||||
|
||||
api.animations = api.get_data(player,{"animations"})
|
||||
if api.animations then
|
||||
api.animations = api.animations.animations
|
||||
end
|
||||
|
||||
api.animations = api.animations[animation_name]
|
||||
|
||||
player:set_animation(api.animations, speed, 0, loop)
|
||||
|
||||
api.set_data(player,{
|
||||
current_animation = animation_name
|
||||
})
|
||||
end
|
||||
|
||||
-- allows other mods to set player animation
|
||||
player_pointer.set_animation = function(player,animation_name,speed)
|
||||
api.set_animation(player,animation_name,speed)
|
||||
temp_pool.animation = animation_name
|
||||
player:set_animation(animation_list[animation_name], speed, 0, loop)
|
||||
end
|
||||
|
||||
-- allows mods to force update animation
|
||||
player_pointer.force_update = function(player)
|
||||
api.set_data(player,{
|
||||
force_update = true
|
||||
})
|
||||
local name
|
||||
force_update_animation = function(player)
|
||||
name = player:get_player_name()
|
||||
pool[name].force_update = true
|
||||
end
|
||||
|
||||
-- force updates the player
|
||||
api.create_force_update = function(player)
|
||||
api.set_data(player,{
|
||||
force_update = true
|
||||
})
|
||||
local name
|
||||
local create_force_update = function(player)
|
||||
name = player:get_player_name()
|
||||
pool[name].force_update = true
|
||||
end
|
||||
|
||||
|
||||
-- toggles nametag visibility
|
||||
api.show_nametag = function(player,boolean)
|
||||
local opacity
|
||||
local show_nametag = function(player,boolean)
|
||||
if boolean then
|
||||
api.opacity = 255
|
||||
opacity = 255
|
||||
else
|
||||
api.opacity = 0
|
||||
opacity = 0
|
||||
end
|
||||
|
||||
player:set_nametag_attributes({
|
||||
color = {
|
||||
r = 255,
|
||||
b = 255,
|
||||
a = api.opacity,
|
||||
a = opacity,
|
||||
g = 255
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- remove all player data
|
||||
local name
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
api.terminate(player)
|
||||
name = player:get_player_name()
|
||||
pool[name] = nil
|
||||
end)
|
||||
|
||||
|
||||
-- converts yaw to degrees
|
||||
api.degrees = function(yaw)
|
||||
return(yaw*180.0/api.pi)
|
||||
local degrees = function(yaw)
|
||||
return(yaw*180.0/math.pi)
|
||||
end
|
||||
|
||||
-- controls head bone
|
||||
api.pitch_look = function(player,sneak)
|
||||
api.state = movement_pointer.get_data(player,{"swimming"})
|
||||
if api.state then
|
||||
api.state = api.state.swimming
|
||||
local state
|
||||
local swimming
|
||||
local pitch
|
||||
local pitch_look = function(player,sneak)
|
||||
state = get_player_state(player)
|
||||
swimming = is_player_swimming(player)
|
||||
pitch = degrees(player:get_look_vertical()) * -1
|
||||
if swimming then
|
||||
pitch = pitch + 90
|
||||
elseif sneak then
|
||||
pitch = pitch + 15
|
||||
end
|
||||
|
||||
api.pitch = api.degrees(player:get_look_vertical()) * -1
|
||||
if api.swimming then
|
||||
api.pitch = api.pitch + 90
|
||||
elseif sneak then
|
||||
api.pitch = api.pitch + 15
|
||||
end
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(api.pitch,0,0))
|
||||
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,0,0))
|
||||
end
|
||||
|
||||
-- checks if the player has done anything with their keyboard/mouse
|
||||
api.control_check = function(player,control_table)
|
||||
api.old_controls = api.get_data(player,{"old_controls"})
|
||||
if api.old_controls then
|
||||
api.old_controls = api.old_controls.old_controls
|
||||
end
|
||||
local name
|
||||
local temp_pool
|
||||
local old_control
|
||||
|
||||
api.force_update = api.get_data(player,{"force_update"})
|
||||
if api.force_update then
|
||||
api.force_update = api.force_update.force_update
|
||||
end
|
||||
local control_check = function(player,control_table)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
if api.force_update then
|
||||
api.set_data(player,{
|
||||
old_controls = control_table,
|
||||
force_update = nil ,
|
||||
})
|
||||
if not temp_pool.old_controls then
|
||||
temp_pool.old_controls = control_table
|
||||
return(true)
|
||||
end
|
||||
|
||||
for i,k in api.pairs(api.old_controls) do
|
||||
if temp_pool.force_update then
|
||||
temp_pool.old_controls = control_table
|
||||
return(true)
|
||||
end
|
||||
|
||||
for i,k in pairs(temp_pool.old_controls) do
|
||||
if control_table[i] ~= k then
|
||||
api.set_data(player,{
|
||||
old_controls = control_table
|
||||
})
|
||||
temp_pool.old_controls = control_table
|
||||
return(true)
|
||||
end
|
||||
end
|
||||
api.set_data(player,{
|
||||
old_controls = control_table
|
||||
})
|
||||
|
||||
temp_pool.old_controls = control_table
|
||||
return(false)
|
||||
end
|
||||
|
||||
-- movement to animation translations
|
||||
api.translation_table = {
|
||||
local translation_table = {
|
||||
["walk"] = {
|
||||
["keys"] = { -- required keys
|
||||
up = true,
|
||||
@ -409,66 +284,73 @@ api.translation_table = {
|
||||
}
|
||||
|
||||
-- translate input and combine with state
|
||||
api.control_translation = function(player,control)
|
||||
api.state = movement_pointer.get_data(player,{"state","swimming"})
|
||||
local name
|
||||
local temp_pool
|
||||
local state
|
||||
local swimming
|
||||
local mouse
|
||||
|
||||
if api.state then
|
||||
api.swimming = api.state.swimming
|
||||
api.state = api.state.state
|
||||
end
|
||||
local control_translation = function(player,control)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
api.mouse = (control.LMB or control.RMB)
|
||||
state = get_player_state(player)
|
||||
swimming = is_player_swimming(player)
|
||||
|
||||
if api.swimming then
|
||||
for k,i in api.pairs(control) do
|
||||
if i and api.translation_table.swim.keys[k] then
|
||||
api.translated = api.translation_table.swim.states[true]
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
mouse = (control.LMB or control.RMB)
|
||||
|
||||
if swimming then
|
||||
for k,i in pairs(control) do
|
||||
if i and translation_table.swim.keys[k] then
|
||||
translated = translation_table.swim.states[true]
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
api.translated = api.translation_table.swim.states[false]
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
translated = translation_table.swim.states[false]
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
return
|
||||
else
|
||||
if control.sneak then
|
||||
for k,i in api.pairs(control) do
|
||||
if i and api.translation_table.sneak.keys[k] then
|
||||
api.translated = api.translation_table.sneak.states[true][api.mouse]
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
for k,i in pairs(control) do
|
||||
if i and translation_table.sneak.keys[k] then
|
||||
translated = translation_table.sneak.states[true][mouse]
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
api.translated = api.translation_table.sneak.states[false][api.mouse]
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
translated = translation_table.sneak.states[false][mouse]
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
return
|
||||
else
|
||||
for k,i in api.pairs(control) do
|
||||
if i and api.translation_table.walk.keys[k] then
|
||||
api.translated = api.translation_table.walk.states[api.mouse][api.state]
|
||||
if api.translated then
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
for k,i in pairs(control) do
|
||||
if i and translation_table.walk.keys[k] then
|
||||
translated = translation_table.walk.states[mouse][state]
|
||||
if translated then
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
api.translated = api.translation_table.stand[api.mouse]
|
||||
api.set_animation(player, api.translated.animation, api.translated.speed)
|
||||
translated = translation_table.stand[mouse]
|
||||
set_animation(player, translated.animation, translated.speed)
|
||||
end
|
||||
end
|
||||
|
||||
-- translates player movement to animation
|
||||
api.do_animations = function(player)
|
||||
api.control_table = player:get_player_control()
|
||||
api.update = api.control_check(player,api.control_table)
|
||||
api.pitch_look(player,api.control_table.sneak)
|
||||
api.update_wield_item(player)
|
||||
if api.update and player:get_hp() > 0 then
|
||||
api.control_translation(player,api.control_table)
|
||||
local control_table
|
||||
local update
|
||||
local do_animations = function(player)
|
||||
control_table = player:get_player_control()
|
||||
update = control_check(player,control_table)
|
||||
pitch_look(player,control_table.sneak)
|
||||
update_wield_item(player)
|
||||
if update and player:get_hp() > 0 then
|
||||
control_translation(player,control_table)
|
||||
elseif player:get_hp() <= 0 then
|
||||
api.set_animation(player,"die",40,false)
|
||||
set_animation(player,"die",40,false)
|
||||
end
|
||||
end
|
||||
|
||||
@ -476,18 +358,17 @@ end
|
||||
|
||||
-- Update appearance when the player joins
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
api.create_data(player)
|
||||
api.set_all_properties(player)
|
||||
set_all_properties(player)
|
||||
end)
|
||||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
api.create_force_update(player)
|
||||
create_force_update(player)
|
||||
end)
|
||||
|
||||
-- inject into global loop
|
||||
minetest.register_globalstep(function()
|
||||
for _,player in api.ipairs(api.get_connected()) do
|
||||
api.do_animations(player)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
do_animations(player)
|
||||
end
|
||||
end)
|
||||
|
||||
|
1
mods/player_mechanics/depends.txt
Normal file
1
mods/player_mechanics/depends.txt
Normal file
@ -0,0 +1 @@
|
||||
armor
|
@ -1,101 +1,51 @@
|
||||
local minetest,math,vector,ipairs,tonumber = minetest,math,vector,ipairs,tonumber
|
||||
|
||||
local movement_class = {} -- controls all data of the movement
|
||||
local player_movement_data = {} -- used to calculate player movement
|
||||
local player_state_channels = {} -- holds every player's channel
|
||||
movement_pointer = {} -- allows other mods to index local data
|
||||
movement_class.input_data = nil
|
||||
movement_class.hunger = nil
|
||||
movement_class.data = nil
|
||||
movement_class.data_list = nil
|
||||
movement_class.count = nil
|
||||
movement_class.name = nil
|
||||
movement_class.env_data = nil
|
||||
movement_class.channel_decyphered = nil
|
||||
movement_class.in_water = nil
|
||||
movement_class.get_group = minetest.get_item_group
|
||||
movement_class.get_connected = minetest.get_connected_players
|
||||
movement_class.ipairs = ipairs
|
||||
movement_class.get_by_name = minetest.get_player_by_name
|
||||
|
||||
-- creates volitile data for the game to use
|
||||
movement_class.create_movement_variables = function(player)
|
||||
movement_class.name = player:get_player_name()
|
||||
if not player_movement_data[movement_class.name] then
|
||||
player_movement_data[movement_class.name] = {
|
||||
state = 0 ,
|
||||
old_state = 0 ,
|
||||
was_in_water = false,
|
||||
swimming = false,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- sets data for the game to use
|
||||
movement_class.set_data = function(player,data)
|
||||
movement_class.name = player:get_player_name()
|
||||
if player_movement_data[movement_class.name] then
|
||||
for index,i_data in pairs(data) do
|
||||
if player_movement_data[movement_class.name][index] ~= nil then
|
||||
player_movement_data[movement_class.name][index] = i_data
|
||||
end
|
||||
end
|
||||
else
|
||||
movement_class.create_movement_variables(player)
|
||||
end
|
||||
end
|
||||
|
||||
-- retrieves data for the game to use
|
||||
movement_class.get_data = function(player)
|
||||
movement_class.name = player:get_player_name()
|
||||
if player_movement_data[movement_class.name] then
|
||||
return({
|
||||
state = player_movement_data[movement_class.name].state ,
|
||||
old_state = player_movement_data[movement_class.name].old_state ,
|
||||
was_in_water = player_movement_data[movement_class.name].was_in_water,
|
||||
swimming = player_movement_data[movement_class.name].swimming ,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- removes movement data
|
||||
movement_class.terminate = function(player)
|
||||
movement_class.name = player:get_player_name()
|
||||
if player_movement_data[movement_class.name] then
|
||||
player_movement_data[movement_class.name] = nil
|
||||
end
|
||||
end
|
||||
local state_channels = {} -- holds every player's channel
|
||||
local pool = {}
|
||||
|
||||
-- creates specific channels for players
|
||||
local name
|
||||
local temp_pool
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
movement_class.name = player:get_player_name()
|
||||
player_state_channels[movement_class.name] = minetest.mod_channel_join(movement_class.name..":player_movement_state")
|
||||
name = player:get_player_name()
|
||||
|
||||
state_channels[name] = minetest.mod_channel_join(name..":player_movement_state")
|
||||
player:set_physics_override({
|
||||
jump = 1.25,
|
||||
gravity= 1.25
|
||||
})
|
||||
movement_class.create_movement_variables(player)
|
||||
|
||||
pool[name] = {}
|
||||
temp_pool = pool[name]
|
||||
temp_pool.state = 0
|
||||
temp_pool.old_state = 0
|
||||
temp_pool.was_in_water = false
|
||||
temp_pool.swimming = false
|
||||
end)
|
||||
|
||||
-- resets the player's state on death
|
||||
local name
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
movement_class.set_data(player,{
|
||||
state = 0 ,
|
||||
was_in_water = false,
|
||||
})
|
||||
movement_class.send_running_cancellation(player,false)
|
||||
name = player:get_player_name()
|
||||
pool[name].state = 0
|
||||
pool[name].was_in_water = false
|
||||
send_running_cancellation(player,false)
|
||||
end)
|
||||
|
||||
|
||||
-- delete data on player leaving
|
||||
local name
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
movement_class.terminate(player)
|
||||
name = minetest.get_player_name()
|
||||
|
||||
pool[name] = nil
|
||||
end)
|
||||
|
||||
-- tells the client to stop sending running/bunnyhop data
|
||||
movement_class.send_running_cancellation = function(player,sneaking)
|
||||
movement_class.name = player:get_player_name()
|
||||
player_state_channels[movement_class.name]:send_all(
|
||||
local name
|
||||
send_running_cancellation = function(player,sneaking)
|
||||
name = player:get_player_name()
|
||||
state_channels[name]:send_all(
|
||||
minetest.serialize({
|
||||
stop_running=true,
|
||||
state=sneaking
|
||||
@ -104,154 +54,139 @@ movement_class.send_running_cancellation = function(player,sneaking)
|
||||
end
|
||||
|
||||
-- intercept incoming data messages
|
||||
local channel_decyphered
|
||||
local state
|
||||
minetest.register_on_modchannel_message(function(channel_name, sender, message)
|
||||
movement_class.channel_decyphered = channel_name:gsub(sender,"")
|
||||
if sender ~= "" and movement_class.channel_decyphered == ":player_movement_state" then
|
||||
movement_class.data = tonumber(message)
|
||||
if type(movement_class.data) == "number" then
|
||||
movement_class.set_data(movement_class.get_by_name(sender),{
|
||||
state = movement_class.data
|
||||
})
|
||||
channel_decyphered = channel_name:gsub(sender,"")
|
||||
if sender ~= "" and channel_decyphered == ":player_movement_state" then
|
||||
state = tonumber(message)
|
||||
if type(state) == "number" then
|
||||
pool[sender].state = state
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- allows other mods to set data for the game to use
|
||||
movement_pointer.set_data = function(player,data)
|
||||
movement_class.name = player:get_player_name()
|
||||
if player_movement_data[movement_class.name] then
|
||||
for index,i_data in pairs(data) do
|
||||
if player_movement_data[movement_class.name][index] ~= nil then
|
||||
player_movement_data[movement_class.name][index] = i_data
|
||||
end
|
||||
end
|
||||
else
|
||||
movement_class.create_movement_variables(player)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- allows other mods to retrieve data for the game to use
|
||||
movement_pointer.get_data = function(player,requested_data)
|
||||
movement_class.name = player:get_player_name()
|
||||
if player_movement_data[movement_class.name] then
|
||||
movement_class.data_list = {}
|
||||
movement_class.count = 0
|
||||
for index,i_data in pairs(requested_data) do
|
||||
if player_movement_data[movement_class.name][i_data] ~= nil then
|
||||
movement_class.data_list[i_data] = player_movement_data[movement_class.name][i_data]
|
||||
movement_class.count = movement_class.count + 1
|
||||
end
|
||||
end
|
||||
if movement_class.count > 0 then
|
||||
return(movement_class.data_list)
|
||||
else
|
||||
return(nil)
|
||||
end
|
||||
end
|
||||
return(nil)
|
||||
local name
|
||||
get_player_state = function(player)
|
||||
name = player:get_player_name()
|
||||
return(pool[name].state)
|
||||
end
|
||||
local name
|
||||
is_player_swimming = function(player)
|
||||
name = player:get_player_name()
|
||||
return(pool[name].swimming)
|
||||
end
|
||||
|
||||
|
||||
-- controls player states
|
||||
movement_class.control_state = function(player)
|
||||
movement_class.hunger = hunger_pointer.get_data(player,{"hunger"}).hunger
|
||||
movement_class.data = movement_class.get_data(player)
|
||||
local hunger
|
||||
local name
|
||||
local temp_pool
|
||||
local head
|
||||
local legs
|
||||
local in_water
|
||||
local control_state = function(player)
|
||||
hunger = get_player_hunger(player)
|
||||
name = player:get_player_name()
|
||||
temp_pool = pool[name]
|
||||
|
||||
-- water movement data
|
||||
movement_class.env_data = environment_pointer.get_data(player,{"legs","head"})
|
||||
movement_class.in_water = {at_all=false,head=false,legs=false}
|
||||
if movement_class.env_data then
|
||||
movement_class.in_water.legs = movement_class.get_group(movement_class.env_data.legs,"water") > 0
|
||||
movement_class.in_water.head = movement_class.get_group(movement_class.env_data.head,"water") > 0
|
||||
if movement_class.in_water.legs or movement_class.in_water.head then
|
||||
movement_class.in_water.at_all = true
|
||||
movement_class.set_data(player,{swimming=true})
|
||||
else
|
||||
movement_class.set_data(player,{swimming=false})
|
||||
end
|
||||
head = minetest.get_item_group(get_player_head_env(player),"water") > 0
|
||||
legs = minetest.get_item_group(get_player_legs_env(player),"water") > 0
|
||||
|
||||
--check if in water
|
||||
if legs or head then
|
||||
in_water = true
|
||||
temp_pool.swimming = true
|
||||
else
|
||||
in_water = false
|
||||
temp_pool.swimming = false
|
||||
end
|
||||
|
||||
if (movement_class.in_water.at_all ~= movement_class.data.was_in_water) or
|
||||
(movement_class.data.state ~= movement_class.data.old_state) or
|
||||
((movement_class.data.state == 1 or movement_class.data.state == 2) and movement_class.hunger and movement_class.hunger <= 6) then
|
||||
if (in_water ~= temp_pool.was_in_water) or
|
||||
(temp_pool.state ~= temp_pool.old_state) or
|
||||
((temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6) then
|
||||
|
||||
|
||||
if not movement_class.in_water.at_all and movement_class.data.was_in_water then
|
||||
if not in_water and temp_pool.was_in_water then
|
||||
player:set_physics_override({
|
||||
sneak = true,
|
||||
})
|
||||
player_pointer.force_update(player)
|
||||
|
||||
force_update_animation(player)
|
||||
|
||||
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
player_pointer.set_data(player,{
|
||||
player:set_properties({
|
||||
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
|
||||
})
|
||||
elseif movement_class.in_water.at_all and not movement_class.data.was_in_water then
|
||||
elseif in_water and not temp_pool.was_in_water then
|
||||
|
||||
player:set_physics_override({
|
||||
sneak = false,
|
||||
})
|
||||
|
||||
player_pointer.force_update(player)
|
||||
force_update_animation(player)
|
||||
|
||||
player:set_eye_offset({x=0,y=-6,z=0},{x=0,y=-6,z=5.9})
|
||||
player_pointer.set_data(player,{
|
||||
player:set_properties({
|
||||
collisionbox = {-0.3, 0.5, -0.3, 0.3, 1.2, 0.3},
|
||||
})
|
||||
end
|
||||
|
||||
-- running/swimming fov modifier
|
||||
if movement_class.hunger and movement_class.hunger > 6 and (movement_class.data.state == 1 or movement_class.data.state == 2) then
|
||||
if hunger > 6 and (temp_pool.state == 1 or temp_pool.state == 2) then
|
||||
player:set_fov(1.25, true, 0.15)
|
||||
if movement_class.data.state == 2 then
|
||||
|
||||
if temp_pool.state == 2 then
|
||||
player:set_physics_override({speed=1.75})
|
||||
elseif movement_class.data.state == 1 then
|
||||
elseif temp_pool.state == 1 then
|
||||
player:set_physics_override({speed=1.5})
|
||||
end
|
||||
elseif (not movement_class.in_water.at_all and movement_class.data.state ~= 1 and movement_class.data.state ~= 2 and
|
||||
(movement_class.data.old_state == 1 or movement_class.data.old_state == 2)) or
|
||||
(movement_class.in_water.at_all and movement_class.data.state ~= 1 and movement_class.data.state ~= 2 and movement_class.data.state ~= 3 and
|
||||
(movement_class.data.old_state == 1 or movement_class.data.old_state == 2 or movement_class.data.old_state == 3))then
|
||||
|
||||
elseif (not in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and
|
||||
(temp_pool.old_state == 1 or temp_pool.old_state == 2)) or
|
||||
(in_water and temp_pool.state ~= 1 and temp_pool.state ~= 2 and temp_pool.state ~= 3 and
|
||||
(temp_pool.old_state == 1 or temp_pool.old_state == 2 or temp_pool.old_state == 3))then
|
||||
|
||||
player:set_fov(1, true,0.15)
|
||||
player:set_physics_override({speed=1})
|
||||
|
||||
movement_class.send_running_cancellation(player,movement_class.data.state==3) --preserve network data
|
||||
send_running_cancellation(player,temp_pool.state==3) --preserve network data
|
||||
|
||||
elseif (movement_class.data.state == 1 or movement_class.data.state == 2) and (movement_class.hunger and movement_class.hunger <= 6) then
|
||||
elseif (temp_pool.state == 1 or temp_pool.state == 2) and hunger <= 6 then
|
||||
player:set_fov(1, true,0.15)
|
||||
player:set_physics_override({speed=1})
|
||||
movement_class.send_running_cancellation(player,false) --preserve network data
|
||||
send_running_cancellation(player,false) --preserve network data
|
||||
end
|
||||
|
||||
--sneaking
|
||||
if movement_class.data.state == 3 and movement_class.in_water.at_all then
|
||||
movement_class.send_running_cancellation(player,false)
|
||||
elseif not movement_class.in_water.at_all and movement_class.data.state == 3 and movement_class.data.old_state ~= 3 then
|
||||
if temp_pool.state == 3 and in_water then
|
||||
send_running_cancellation(player,false)
|
||||
elseif not in_water and temp_pool.state == 3 and temp_pool.old_state ~= 3 then
|
||||
player:set_eye_offset({x=0,y=-1,z=0},{x=0,y=-1,z=0})
|
||||
elseif not movement_class.in_water.at_all and movement_class.data.old_state == 3 and movement_class.data.state ~= 3 then
|
||||
elseif not in_water and temp_pool.old_state == 3 and temp_pool.state ~= 3 then
|
||||
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
end
|
||||
|
||||
movement_class.set_data(player,{
|
||||
old_state = movement_class.data.state,
|
||||
was_in_water = movement_class.in_water.at_all
|
||||
})
|
||||
temp_pool.old_state = state
|
||||
temp_pool.was_in_water = in_water
|
||||
|
||||
-- water movement
|
||||
elseif movement_class.in_water.at_all then
|
||||
if not movement_class.data.was_in_water then
|
||||
elseif in_water then
|
||||
if not temp_pool.was_in_water then
|
||||
player:set_physics_override({
|
||||
sneak = false ,
|
||||
})
|
||||
player:set_velocity(vector.new(0,0,0))
|
||||
end
|
||||
|
||||
movement_class.set_data(player,{
|
||||
old_state = movement_class.data.state,
|
||||
was_in_water = movement_class.in_water.at_all
|
||||
})
|
||||
temp_pool.old_state = temp_pool.old_state
|
||||
temp_pool.was_in_water = in_water
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for _,player in movement_class.ipairs(movement_class.get_connected()) do
|
||||
movement_class.control_state(player)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
control_state(player)
|
||||
end
|
||||
end)
|
Loading…
x
Reference in New Issue
Block a user