From 0df8facb4d0ff0cf514e410a513eaa645977e373 Mon Sep 17 00:00:00 2001 From: oilboi <47129783+oilboi@users.noreply.github.com> Date: Sun, 14 Jun 2020 20:15:35 -0400 Subject: [PATCH] Rewrite --- mods/drowning/init.lua | 388 ++++++----------- mods/hunger/init.lua | 421 +++++++------------ mods/new_functions/init.lua | 380 +++++------------ mods/player_api/init.lua | 465 ++++++++------------- mods/player_mechanics/depends.txt | 1 + mods/player_mechanics/player_mechanics.lua | 271 +++++------- 6 files changed, 682 insertions(+), 1244 deletions(-) create mode 100644 mods/player_mechanics/depends.txt diff --git a/mods/drowning/init.lua b/mods/drowning/init.lua index 6e5cbe1..89d551d 100644 --- a/mods/drowning/init.lua +++ b/mods/drowning/init.lua @@ -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) \ No newline at end of file diff --git a/mods/hunger/init.lua b/mods/hunger/init.lua index ad4846e..1a64f2e 100644 --- a/mods/hunger/init.lua +++ b/mods/hunger/init.lua @@ -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 }) diff --git a/mods/new_functions/init.lua b/mods/new_functions/init.lua index 4fefc58..5facb9e 100644 --- a/mods/new_functions/init.lua +++ b/mods/new_functions/init.lua @@ -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 diff --git a/mods/player_api/init.lua b/mods/player_api/init.lua index dc2665b..661738d 100644 --- a/mods/player_api/init.lua +++ b/mods/player_api/init.lua @@ -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) diff --git a/mods/player_mechanics/depends.txt b/mods/player_mechanics/depends.txt new file mode 100644 index 0000000..ea4d69d --- /dev/null +++ b/mods/player_mechanics/depends.txt @@ -0,0 +1 @@ +armor \ No newline at end of file diff --git a/mods/player_mechanics/player_mechanics.lua b/mods/player_mechanics/player_mechanics.lua index 6b0d7af..7a84bc7 100644 --- a/mods/player_mechanics/player_mechanics.lua +++ b/mods/player_mechanics/player_mechanics.lua @@ -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) \ No newline at end of file