1 local minetest,math,vector,table = minetest,math,vector,table
7 get_player_head_env = function(player)
8 name = player:get_player_name()
9 return(pool[name].head)
12 get_player_legs_env = function(player)
13 name = player:get_player_name()
14 return(pool[name].legs)
18 player_under_check = function(player)
19 name = player:get_player_name()
20 return(pool[name].under)
24 player_swim_check = function(player)
25 name = player:get_player_name()
26 return(minetest.get_nodedef(pool[name].swim_check, "walkable") == false)
30 player_swim_under_check = function(player)
31 name = player:get_player_name()
32 return(minetest.get_nodedef(pool[name].under, "walkable") == false)
35 -- create blank list for player environment data
38 minetest.register_on_joinplayer(function(player)
39 name = player:get_player_name()
41 temp_pool = pool[name]
46 temp_pool.swim_check = ""
47 temp_pool.touch_hurt_ticker = 0
48 temp_pool.hurt_inside_ticker = 0
51 -- destroy player environment data
53 minetest.register_on_leaveplayer(function(player)
54 name = player:get_player_name()
60 -- handle damage when touching node
61 -- this is lua collision detection
62 -- damages players 4 times a second
66 local handle_touch_hurting = function(player,damage,dtime)
67 name = player:get_player_name()
68 temp_pool = pool[name]
69 tick = temp_pool.touch_hurt_ticker
73 player:set_hp(player:get_hp()-damage)
76 temp_pool.touch_hurt_ticker = tick
90 local hurt_collide = function(player,dtime)
91 name = player:get_player_name()
92 if player:get_hp() <= 0 then
95 -- used for finding a damage node from the center of the player
96 -- rudementary collision detection
97 pos = player:get_pos()
98 pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
110 _,damage_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:touch_hurt"})
112 for node_data,is_next_to in pairs(damage_nodes) do
113 if damage_nodes[node_data] > 0 then
114 table.insert(real_nodes,node_data)
118 -- find the highest damage node
119 if table.getn(real_nodes) > 0 then
120 for _,node in ipairs(real_nodes) do
121 damage_amount = minetest.get_item_group(node, "touch_hurt")
122 if damage_amount > hurt then
126 handle_touch_hurting(player,damage_amount,dtime)
128 pool[name].touch_hurt_ticker = 0
134 -- handle damage when inside node
135 -- this is lua collision detection
137 -- damages players 4 times a second
141 local handle_hurt_inside = function(player,damage,dtime)
142 name = player:get_player_name()
143 temp_pool = pool[name]
144 tick = temp_pool.hurt_inside_ticker
148 player:set_hp(player:get_hp()-damage)
151 temp_pool.hurt_inside_ticker = tick
164 local hurt_inside = function(player,dtime)
165 name = player:get_player_name()
166 if player:get_hp() <= 0 then
169 -- used for finding a damage node from the center of the player
170 -- rudementary collision detection
171 pos = player:get_pos()
172 pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
184 _,damage_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:hurt_inside"})
186 for node_data,is_next_to in pairs(damage_nodes) do
187 if damage_nodes[node_data] > 0 then
188 table.insert(real_nodes,node_data)
192 -- find the highest damage node
193 if table.getn(real_nodes) > 0 then
194 for _,node in ipairs(real_nodes) do
195 damage_amount = minetest.get_item_group(node, "hurt_inside")
196 if damage_amount > hurt then
200 handle_hurt_inside(player,damage_amount,dtime)
202 pool[name].hurt_inside_ticker = 0
209 -- this handles lighting a player on fire
219 local start_fire = function(player)
220 name = player:get_player_name()
221 if player:get_hp() <= 0 then
225 pos = player:get_pos()
227 if weather_type == 2 then
228 head_pos = table.copy(pos)
229 head_pos.y = head_pos.y + player:get_properties().collisionbox[5]
230 light = minetest.get_node_light(head_pos, 0.5)
231 if light and light == 15 then
236 -- used for finding a damage node from the center of the player
237 -- rudementary collision detection
238 pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
250 _,damage_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:fire"})
252 for node_data,is_next_to in pairs(damage_nodes) do
253 if damage_nodes[node_data] > 0 then
254 table.insert(real_nodes,node_data)
258 if table.getn(real_nodes) > 0 then
263 -- this handles extinguishing a fire
273 local extinguish = function(player)
274 name = player:get_player_name()
275 if player:get_hp() <= 0 then
278 pos = player:get_pos()
279 if weather_type == 2 then
280 head_pos = table.copy(pos)
281 head_pos.y = head_pos.y + player:get_properties().collisionbox[5]
282 light = minetest.get_node_light(head_pos, 0.5)
283 if light and light == 15 then
288 -- used for finding a damage node from the center of the player
289 -- rudementary collision detection
290 pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
302 _,relief_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:extinguish"})
304 for node_data,is_next_to in pairs(relief_nodes) do
305 if relief_nodes[node_data] > 0 then
306 table.insert(real_nodes,node_data)
310 if table.getn(real_nodes) > 0 then
315 -- handle player suffocating inside solid node
316 environment_class.handle_player_suffocation = function(player,dtime)
317 if player:get_hp() <= 0 then
321 local data = environment_class.get_data(player,{"head"})
325 if minetest.get_nodedef(data, "drawtype") == "normal" then
326 environment_class.handle_suffocation_hurt(player,1,dtime)
328 environment_class.set_data(player,{suffocation_ticker = 0})
333 -- damages players 4 times a second
334 environment_class.handle_suffocation_hurt = function(player,damage,dtime)
335 environment_class.tick = environment_class.get_data(player,{"suffocation_ticker"})
336 if environment_class.tick then
337 environment_class.tick = environment_class.tick.suffocation_ticker
339 if not environment_class.tick then
340 environment_class.set_data(player,{suffocation_ticker = 0.25})
341 player:set_hp(player:get_hp()-damage)
343 environment_class.tick = environment_class.tick - dtime
344 if environment_class.tick <= 0 then
345 player:set_hp(player:get_hp()-damage)
346 environment_class.set_data(player,{suffocation_ticker = 0.25})
348 environment_class.set_data(player,{suffocation_ticker = environment_class.tick})
355 -- environment indexing
357 -- creates data at specific points of the player
362 local index_players_surroundings = function(dtime)
363 for _,player in ipairs(minetest.get_connected_players()) do
365 name = player:get_player_name()
366 temp_pool = pool[name]
368 pos = player:get_pos()
369 swimming = is_player_swimming(player)
372 --this is where the legs would be
373 temp_pool.under = minetest.get_node(pos).name
375 --legs and head are in the same position
377 temp_pool.legs = minetest.get_node(pos).name
378 temp_pool.head = minetest.get_node(pos).name
381 temp_pool.swim_check = minetest.get_node(pos).name
384 temp_pool.under = minetest.get_node(pos).name
387 temp_pool.legs = minetest.get_node(pos).name
389 pos.y = pos.y + 0.940
390 temp_pool.head = minetest.get_node(pos).name
393 hurt_collide(player,dtime)
395 hurt_inside(player,dtime)
399 if is_player_on_fire(player) then
402 --handle_player_suffocation(player,dtime)
406 -- insert all indexing data into main loop
407 minetest.register_globalstep(function(dtime)
408 index_players_surroundings(dtime)
411 -- a custom helper function
412 minetest.get_nodedef = function(nodename, fieldname)
413 if not minetest.registered_nodes[nodename] then
416 return minetest.registered_nodes[nodename][fieldname]
419 -- a custom helper function
420 minetest.get_itemdef = function(itemname, fieldname)
421 if not minetest.registered_items[itemname] then
424 return minetest.registered_items[itemname][fieldname]