91 lines
3.4 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Periodically check the player position if it is in the valid range.
-- For example, if the player "fell out" of the level.
--
-- If the player is out of range, then:
-- * In the menu ship: Teleport back to ship spawn
-- * In a level: Fail level, teleport back to ship and taunt player
-- * Any other game state: Do nothing
--
-- Additionally, it is checked whether the player head is stuck
-- in a solid node.
--
-- Having the fly or noclip privs bypasses all resets.
local S = minetest.get_translator("lzr_fallout")
local CRUSH_TIMER = 3
local FALLOUT_TIMER = 2
local SHIP_FALLOUT_Y = lzr_globals.MENU_SHIP_POS.y + lzr_globals.MENU_SHIP_FALLOUT_Y_OFFSET
local timer = 0
local crush_timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < FALLOUT_TIMER then
return
end
timer = 0
local players = minetest.get_connected_players()
local state = lzr_gamestate.get_state()
for p=1, #players do
local player = players[p]
local privs = minetest.get_player_privs(player:get_player_name())
if not (privs["fly"] or privs["noclip"]) then
local pos = player:get_pos()
if state == lzr_gamestate.MENU then
if pos.y < SHIP_FALLOUT_Y then
local spawn = vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_SPAWN_OFFSET)
player:set_pos(spawn)
end
crush_timer = 0
elseif state == lzr_gamestate.LEVEL then
-- Below allowed minimum Y
if pos.y < lzr_globals.LEVEL_FALLOUT_Y then
lzr_messages.show_message(player, S("You are sleeping with the fishes!"), 6.0, 0xFF0000)
lzr_levels.leave_level()
crush_timer = 0
return
else
-- Outside of level bounds in other directions
local minpos = lzr_globals.LEVEL_POS
local maxpos = vector.add(lzr_globals.LEVEL_POS, lzr_levels.get_level_size())
if pos.x < minpos.x -0.5 or pos.x > maxpos.x + 0.5 or pos.z < minpos.z -0.5 or pos.z > maxpos.z + 0.5 or pos.y > maxpos.y + 0.5 then
lzr_messages.show_message(player, S("Where yer thinks yar goin, landlubber?"), 6.0, 0xFF0000)
lzr_levels.leave_level()
crush_timer = 0
return
else
-- Player head got stuck in solid node for a few seconds
local node2 = minetest.get_node(vector.offset(pos, 0, 1, 0))
local def2 = minetest.registered_nodes[node2.name]
if def2 and def2.walkable and minetest.get_item_group(node2.name, "slab") == 0 and minetest.get_item_group(node2.name, "stair") == 0 and minetest.get_item_group(node2.name, "takable") == 0 then
-- Stuck in solid skull: No further delay
if minetest.get_item_group(node2.name, "skull") ~= 0 then
lzr_messages.show_message(player, S("You were skull-crushed!"), 6.0, 0xFF0000)
lzr_levels.leave_level()
crush_timer = 0
return
end
-- Stuck in other solid node: After a short time
-- Only full-size nodes count
if (not def2.collision_box and not def2.node_box) or (def2.collision_box and def2.collision_box.type == "regular") or (not def2.collision_box and def2.node_box and def2.node_box.type == "regular") then
crush_timer = crush_timer + FALLOUT_TIMER + dtime
if crush_timer > CRUSH_TIMER then
lzr_messages.show_message(player, S("You were between a rock and a hard place."), 6.0, 0xFF0000)
lzr_levels.leave_level()
crush_timer = 0
return
end
end
else
crush_timer = 0
end
end
end
else
crush_timer = 0
end
end
end
end)