]> git.lizzy.rs Git - Crafter.git/blob - mods/drowning/init.lua
Remove engine drowning from water
[Crafter.git] / mods / drowning / init.lua
1 local minetest,vector,hud_manager = minetest,vector,hud_manager
2
3 local mod_storage        = minetest.get_mod_storage()
4
5 local drowning_class     = {}
6
7 drowning_class.get_group = minetest.get_item_group
8
9 local player_drowning    = {}
10
11 drowning_class.tick      = nil
12
13 drowning_class.breath    = nil
14
15 drowning_pointer         = {} -- allows other mods to access data
16
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] = {}
22         end
23
24         for index,i_data in pairs(data) do
25                 player_drowning[name][index] = i_data
26         end
27
28         if data.breath then
29
30                 if data.breath > 20 then
31                         if hud_manager.hud_exists(player,"breath_bg") then
32                                 hud_manager.remove_hud(player,"breath_bg")
33                         end
34                         if hud_manager.hud_exists(player,"breath") then
35                                 hud_manager.remove_hud(player,"breath")
36                         end
37                 else
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",
43                                         number = 20,
44                                         direction = 1,
45                                         size = {x = 24, y = 24},
46                                         offset = {x = 24*10, y= -(48 + 52 + 39)},
47                                 })
48                         end
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},
53                                         text = "bubble.png",
54                                         number = data.breath,
55                                         direction = 1,
56                                         size = {x = 24, y = 24},
57                                         offset = {x = 24*10, y= -(48 + 52 + 39)},
58                                 })
59                         end
60
61                         hud_manager.change_hud({
62                                 player    =  player ,
63                                 hud_name  = "breath",
64                                 element   = "number",
65                                 data      =  data.breath
66                         })
67                 end
68         end
69 end
70
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
75                 local data_list = {}
76                 local count     = 0
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]
80                                 count = count + 1
81                         end
82                 end
83                 if count > 0 then
84                         return(data_list)
85                 else
86                         return(nil)
87                 end
88         end
89         return(nil)
90 end
91
92 -- removes 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
97         end
98 end
99
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
104                 return({
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"     ),
108                           })
109         else
110                 return({
111                                 breath        = 20,
112                                 breath_ticker = 0 ,
113                                 drowning      = 0 ,
114                           })
115         end
116 end
117
118 -- saves data to be utilized on next login
119 drowning_class.save_data = function(player)
120         local name
121         if type(player) ~= "string" and player:is_player() then
122                 name = player:get_player_name()
123         elseif type(player) == "string" then
124                 name = player
125         end
126         if player_drowning[name] then
127                 for index,integer in pairs(player_drowning[name]) do
128                         mod_storage:set_float(name..index,integer)
129                 end
130         end
131
132         mod_storage:set_int(name.."d_save", 1)
133
134         player_drowning[name] = nil
135 end
136
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)
141         end
142 end
143
144
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] = {}
150         end
151
152         for index,i_data in pairs(data) do
153                 player_drowning[name][index] = i_data
154         end
155
156         if data.breath then
157                 hud_manager.change_hud({
158                         player    =  player ,
159                         hud_name  = "breath",
160                         element   = "number",
161                         data      =  data.breath
162                 })
163         end
164 end
165
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
170                 local data_list = {}
171                 local count     = 0
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]
175                                 count = count + 1
176                         end
177                 end
178                 if count > 0 then
179                         return(data_list)
180                 else
181                         return(nil)
182                 end
183         end
184         return(nil)
185 end
186
187
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",
193         number = 0,
194         direction = 0,
195         size = {x = 0, y = 0},
196         offset = {x = 0, y= 0},
197 })
198 minetest.register_on_joinplayer(function(player)
199         local data = drowning_class.load_data(player)
200         drowning_class.set_data(player,data)
201
202         player:hud_set_flags({breathbar=false})
203 end)
204
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)
209 end)
210
211 -- save all data to mod storage on shutdown
212 minetest.register_on_shutdown(function()
213         drowning_class.save_all()
214 end)
215
216 -- reset the player's data
217 minetest.register_on_respawnplayer(function(player)
218         drowning_class.set_data(player,{
219                 breath        = 20,
220                 breath_ticker = 0 ,
221                 drowning      = 0 ,
222         })
223 end)
224
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()
229
230                 local data = environment_pointer.get_data(player,{"head"})
231                 
232                 if data then
233                         data = data.head
234                 end
235
236                 if drowning_class.get_group(data, "drowning") > 0 then
237                         
238                         drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
239
240                         drowning_class.breath = drowning_class.get_data(player,{"breath"})
241                                 
242                         if drowning_class.breath then
243                                 drowning_class.breath = drowning_class.breath.breath
244                         end
245
246                         if drowning_class.ticker then
247                                 drowning_class.ticker = drowning_class.ticker.breath_ticker
248                         end
249
250                         drowning_class.ticker = drowning_class.ticker + dtime
251                         
252                         if drowning_class.breath > 0 and drowning_class.ticker >= 1.3 then
253
254                                 drowning_class.breath = drowning_class.breath - 2
255
256                                 drowning_class.set_data(player,{breath = drowning_class.breath})
257                                 
258                                 drowning_class.set_data(player,{drowning = 0})
259
260                         elseif drowning_class.breath <= 0 and drowning_class.ticker >= 1.3 then
261                                                                         
262                                 drowning_class.set_data(player,{drowning=1})
263
264                                 local hp =  player:get_hp()
265
266                                 if hp > 0 then
267                                         player:set_hp(hp-2)
268                                         player:add_player_velocity(vector.new(0,-15,0))
269                                 end
270                         end
271
272                         if drowning_class.ticker >= 1.3 then
273                                 drowning_class.ticker = 0
274                         end
275
276                         drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
277                         
278                 else
279
280                         drowning_class.breath = drowning_class.get_data(player,{"breath"})
281                         
282                         drowning_class.ticker = drowning_class.get_data(player,{"breath_ticker"})
283
284                         if drowning_class.ticker then
285                                 drowning_class.ticker = drowning_class.ticker.breath_ticker
286                         end
287
288                         if drowning_class.breath then
289                                 drowning_class.breath = drowning_class.breath.breath
290                         end
291
292                         drowning_class.ticker = drowning_class.ticker + dtime           
293
294                         if drowning_class.breath < 21 and drowning_class.ticker >= 0.25 then
295                                 
296                                 drowning_class.breath = drowning_class.breath + 2
297                                 
298                                 drowning_class.set_data(player,{
299                                         breath        = drowning_class.breath,
300                                         drowning      = 0,
301                                         breath_ticker = 0,
302                                 })
303                         elseif drowning_class.breath < 21 then
304                                 drowning_class.set_data(player,{breath_ticker = drowning_class.ticker})
305                         else
306                                 drowning_class.set_data(player,{breath_ticker = 0})
307                         end
308                 end
309         end
310 end
311
312 -- inject into main loop
313 minetest.register_globalstep(function(dtime)
314         drowning_class.handle_breath(dtime)
315 end)