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},
198 minetest.register_on_joinplayer(function(player)
199 local data = drowning_class.load_data(player)
200 drowning_class.set_data(player,data)
202 player:hud_set_flags({breathbar=false})
205 -- saves specific users data for when they relog
206 minetest.register_on_leaveplayer(function(player)
207 drowning_class.save_data(player)
208 drowning_class.terminate(player)
211 -- save all data to mod storage on shutdown
212 minetest.register_on_shutdown(function()
213 drowning_class.save_all()
216 -- reset the player's data
217 minetest.register_on_respawnplayer(function(player)
218 drowning_class.set_data(player,{
225 --handle the breath bar
226 drowning_class.handle_breath = function(dtime)
227 for _,player in ipairs(minetest.get_connected_players()) do
228 local name = player:get_player_name()
230 local data = environment_pointer.get_data(player,{"head"})
236 if drowning_class.get_group(data, "drowning") > 0 then
238 drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
240 drowning_class.breath = drowning_class.get_data(player,{"breath"})
242 if drowning_class.breath then
243 drowning_class.breath = drowning_class.breath.breath
246 if drowning_class.ticker then
247 drowning_class.ticker = drowning_class.ticker.breath_ticker
250 drowning_class.ticker = drowning_class.ticker + dtime
252 if drowning_class.breath > 0 and drowning_class.ticker >= 1.3 then
254 drowning_class.breath = drowning_class.breath - 2
256 drowning_class.set_data(player,{breath = drowning_class.breath})
258 drowning_class.set_data(player,{drowning = 0})
260 elseif drowning_class.breath <= 0 and drowning_class.ticker >= 1.3 then
262 drowning_class.set_data(player,{drowning=1})
264 local hp = player:get_hp()
268 player:add_player_velocity(vector.new(0,-15,0))
272 if drowning_class.ticker >= 1.3 then
273 drowning_class.ticker = 0
276 drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
280 drowning_class.breath = drowning_class.get_data(player,{"breath"})
282 drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
284 if drowning_class.ticker then
285 drowning_class.ticker = drowning_class.ticker.breath_ticker
288 if drowning_class.breath then
289 drowning_class.breath = drowning_class.breath.breath
292 drowning_class.ticker = drowning_class.ticker + dtime
294 if drowning_class.breath < 21 and drowning_class.ticker >= 0.25 then
296 drowning_class.breath = drowning_class.breath + 2
298 drowning_class.set_data(player,{
299 breath = drowning_class.breath,
303 elseif drowning_class.breath < 21 then
304 drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
306 drowning_class.set_data(player,{breath_ticker = 0})
312 -- inject into main loop
313 minetest.register_globalstep(function(dtime)
314 drowning_class.handle_breath(dtime)