1 local minetest,vector,hud_manager = minetest,vector,hud_manager
3 local mod_storage = minetest.get_mod_storage()
5 local drowning_class = {}
7 drowning_class.get_group = minetest.get_item_group
9 local player_drowning = {}
11 drowning_class.tick = nil
13 drowning_class.breath = nil
15 drowning_pointer = {} -- allows other mods to access data
17 -- creates volitile data for the game to use
18 drowning_class.set_data = function(player,data)
19 local name = player:get_player_name()
20 if not player_drowning[name] then
21 player_drowning[name] = {}
24 for index,i_data in pairs(data) do
25 player_drowning[name][index] = i_data
30 if data.breath > 20 then
31 if hud_manager.hud_exists(player,"breath_bg") then
32 hud_manager.remove_hud(player,"breath_bg")
34 if hud_manager.hud_exists(player,"breath") then
35 hud_manager.remove_hud(player,"breath")
38 if not hud_manager.hud_exists(player,"breath_bg") then
39 hud_manager.add_hud(player,"breath_bg",{
40 hud_elem_type = "statbar",
41 position = {x = 0.5, y = 1},
42 text = "bubble_bg.png",
45 size = {x = 24, y = 24},
46 offset = {x = 24*10, y= -(48 + 52 + 39)},
49 if not hud_manager.hud_exists(player,"breath") then
50 hud_manager.add_hud(player,"breath",{
51 hud_elem_type = "statbar",
52 position = {x = 0.5, y = 1},
56 size = {x = 24, y = 24},
57 offset = {x = 24*10, y= -(48 + 52 + 39)},
61 hud_manager.change_hud({
71 -- indexes drowning data and returns it
72 drowning_class.get_data = function(player,requested_data)
73 local name = player:get_player_name()
74 if player_drowning[name] then
77 for index,i_data in pairs(requested_data) do
78 if player_drowning[name][i_data] then
79 data_list[i_data] = player_drowning[name][i_data]
93 drowning_class.terminate = function(player)
94 local name = player:get_player_name()
95 if player_drowning[name] then
96 player_drowning[name] = nil
100 -- loads data from mod storage
101 drowning_class.load_data = function(player)
102 local name = player:get_player_name()
103 if mod_storage:get_int(name.."d_save") > 0 then
105 breath = mod_storage:get_float(name.."breath" ),
106 breath_ticker = mod_storage:get_float(name.."breath_ticker"),
107 drowning = mod_storage:get_float(name.."drowning" ),
118 -- saves data to be utilized on next login
119 drowning_class.save_data = function(player)
121 if type(player) ~= "string" and player:is_player() then
122 name = player:get_player_name()
123 elseif type(player) == "string" then
126 if player_drowning[name] then
127 for index,integer in pairs(player_drowning[name]) do
128 mod_storage:set_float(name..index,integer)
132 mod_storage:set_int(name.."d_save", 1)
134 player_drowning[name] = nil
137 -- is used for shutdowns to save all data
138 drowning_class.save_all = function()
139 for name,data in pairs(player_drowning) do
140 drowning_class.save_data(name)
145 -- creates volitile data for the game to use
146 drowning_pointer.set_data = function(player,data)
147 local name = player:get_player_name()
148 if not player_drowning[name] then
149 player_drowning[name] = {}
152 for index,i_data in pairs(data) do
153 player_drowning[name][index] = i_data
157 hud_manager.change_hud({
166 -- indexes drowning data and returns it
167 drowning_pointer.get_data = function(player,requested_data)
168 local name = player:get_player_name()
169 if player_drowning[name] then
172 for index,i_data in pairs(requested_data) do
173 if player_drowning[name][i_data] then
174 data_list[i_data] = player_drowning[name][i_data]
188 -- remove stock health bar
189 minetest.hud_replace_builtin("breath",{
190 hud_elem_type = "statbar",
191 position = {x = 0, y = 0},
192 text = "nothing.png",
195 size = {x = 0, y = 0},
196 offset = {x = 0, y= 0},
199 minetest.register_on_joinplayer(function(player)
200 local data = drowning_class.load_data(player)
201 drowning_class.set_data(player,data)
203 player:hud_set_flags({breathbar=false})
206 -- saves specific users data for when they relog
207 minetest.register_on_leaveplayer(function(player)
208 drowning_class.save_data(player)
209 drowning_class.terminate(player)
212 -- save all data to mod storage on shutdown
213 minetest.register_on_shutdown(function()
214 drowning_class.save_all()
217 -- reset the player's data
218 minetest.register_on_respawnplayer(function(player)
219 drowning_class.set_data(player,{
226 --handle the breath bar
227 drowning_class.handle_breath = function(dtime)
228 for _,player in ipairs(minetest.get_connected_players()) do
229 player:set_breath(50000)
230 local name = player:get_player_name()
232 local data = environment_pointer.get_data(player,{"head"})
238 if drowning_class.get_group(data, "drowning") > 0 then
240 drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
242 drowning_class.breath = drowning_class.get_data(player,{"breath"})
244 if drowning_class.breath then
245 drowning_class.breath = drowning_class.breath.breath
248 if drowning_class.ticker then
249 drowning_class.ticker = drowning_class.ticker.breath_ticker
252 drowning_class.ticker = drowning_class.ticker + dtime
254 if drowning_class.breath > 0 and drowning_class.ticker >= 1.3 then
256 drowning_class.breath = drowning_class.breath - 2
258 drowning_class.set_data(player,{breath = drowning_class.breath})
260 drowning_class.set_data(player,{drowning = 0})
262 elseif drowning_class.breath <= 0 and drowning_class.ticker >= 1.3 then
264 drowning_class.set_data(player,{drowning=1})
266 local hp = player:get_hp()
270 player:add_player_velocity(vector.new(0,-15,0))
274 if drowning_class.ticker >= 1.3 then
275 drowning_class.ticker = 0
278 drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
282 drowning_class.breath = drowning_class.get_data(player,{"breath"})
284 drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
286 if drowning_class.ticker then
287 drowning_class.ticker = drowning_class.ticker.breath_ticker
290 if drowning_class.breath then
291 drowning_class.breath = drowning_class.breath.breath
294 drowning_class.ticker = drowning_class.ticker + dtime
296 if drowning_class.breath < 21 and drowning_class.ticker >= 0.25 then
298 drowning_class.breath = drowning_class.breath + 2
300 drowning_class.set_data(player,{
301 breath = drowning_class.breath,
305 elseif drowning_class.breath < 21 then
306 drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
308 drowning_class.set_data(player,{breath_ticker = 0})
314 -- inject into main loop
315 minetest.register_globalstep(function(dtime)
316 drowning_class.handle_breath(dtime)