tntrun-cd2025/auto.lua

201 lines
5.4 KiB
Lua

local S = minetest.get_translator("tntrun")
-- Clear all TNT within the arena region.
-- No-op if arena region is not set.
function tntrun.clear_tnt(arena)
local positions = {}
local pos1 = arena.pos1
local pos2 = arena.pos2
if not pos1 or not pos2 then
return false
end
pos1, pos2 = tntrun.sort_positions(pos1, pos2)
minetest.load_area(pos1, pos2)
for x = pos1.x, pos2.x do
for y = pos1.y, pos2.y do
for z = pos1.z, pos2.z do
local pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
if node.name == "tntrun:tnt" then
table.insert(positions, pos)
end
end
end
end
minetest.bulk_set_node(positions, {name="air"})
minetest.fix_light(arena.pos1, arena.pos2)
return true
end
-- Place the TNT layers
function tntrun.place_tnt(arena)
local positions = {}
for k = 1, #arena.tnt_area_pos_1 do
local pos1 = arena.tnt_area_pos_1[k]
local pos2 = arena.tnt_area_pos_2[k]
minetest.load_area(pos1, pos2)
pos1, pos2 = tntrun.sort_positions(pos1, pos2)
for x = pos1.x, pos2.x do
for y = pos1.y, pos2.y do
for z = pos1.z, pos2.z do
local pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
-- Only air is replaced to allow to more control
-- of the map designer
if node.name == "air" then
table.insert(positions, pos)
end
end
end
end
end
minetest.bulk_set_node(positions, {name="tntrun:tnt"})
end
-- Remove all falling TNT entities in the arena.
-- The arena region must be set for this to work.
local function remove_falling_tnt_entities(arena)
if not arena.pos1 or not arena.pos2 then
return
end
local pos1, pos2 = tntrun.sort_positions(arena.pos1, arena.pos2)
local objs = minetest.get_objects_in_area(pos1, pos2)
for o=1, #objs do
local obj = objs[o]
local ent = obj:get_luaentity()
if ent and ent .name == "tntrun:tnt_falling" then
obj:remove()
end
end
end
arena_lib.on_load("tntrun", function(arena)
remove_falling_tnt_entities(arena)
tntrun.place_tnt(arena)
for pl_name, _ in pairs(arena.players) do
local message = S('How it works:')
minetest.chat_send_player(pl_name,message)
message = minetest.colorize('#f47e1b', S('Punch TNTs to make them fall down'))
minetest.chat_send_player(pl_name,message)
message = minetest.colorize('#e6482e', S('But beware: TNTs will also fall down when you walk onto it. Keep moving!'))
minetest.chat_send_player(pl_name,message)
arena.players[pl_name].lives = arena.lives
end
local countdown
countdown = function(seconds_left)
if seconds_left <= 0 then
arena_lib.HUD_send_msg_all("title", arena, S("Run!"), 1, {name="tntrun_round_start", gain=0.4}, 0x00FF00)
local item = ItemStack("tntrun:torch")
for pl_name, _ in pairs(arena.players) do
local player = minetest.get_player_by_name(pl_name)
player:get_inventory():set_stack("main", 1, item)
end
else
arena_lib.HUD_send_msg_all("title", arena, tostring(seconds_left), 1, {name="tntrun_countdown", gain=1.0}, 0xFFFF00)
minetest.after(1, countdown, seconds_left - 1)
end
end
countdown(3)
end)
arena_lib.on_end("tntrun", function(arena)
remove_falling_tnt_entities(arena)
tntrun.place_tnt(arena)
end)
arena_lib.on_time_tick("tntrun", function(arena)
-- Kill players who have fallen below the elimination height
-- Get players at the critical height
local to_eliminate = {}
for p_name in pairs(arena.players) do
local player = minetest.get_player_by_name(p_name)
local y = player:get_pos().y
if y <= arena.eliminate_height then
table.insert(to_eliminate, {player_name = p_name , y = y})
end
end
-- Sort players by height (lowest player first)
table.sort(to_eliminate, function(e1, e2)
return e1.y < e2.y
end)
-- Eliminate players, starting with the lowest player first,
-- as a tiebreaker in case multiple players
-- get eliminated in the same tick.
for e=1, #to_eliminate do
local elim = to_eliminate[e]
arena_lib.remove_player_from_arena(elim.player_name, 1)
end
end)
arena_lib.on_death('tntrun', function(arena, p_name, reason)
arena_lib.remove_player_from_arena(p_name, 1)
end)
arena_lib.on_eliminate('tntrun', function(arena, p_name)
-- Play elimination sound when player eliminated
-- and lose sound to the player who got
-- eliminated
minetest.sound_play('tntrun_lose', {
to_player = p_name,
gain = 2.0,
}, true)
local count = 0
local sound = 'tntrun_elim'
for p_name,data in pairs(arena.players) do
count = count + 1
end
if count == 1 then
-- No elimination sound for the last
-- player; they'll get the win sound
-- in celebration
return
end
local player = minetest.get_player_by_name(p_name)
for p_name, _ in pairs(arena.players) do
minetest.sound_play(sound, {
to_player = p_name,
gain = 2.0,
}, true)
end
end)
-- Play win sound to winners
arena_lib.on_celebration('tntrun', function(arena, winners)
local winners_list = {}
if type(winners) == "string" then
winners_list = {winners}
elseif type(winners) == "table" then
winners_list = winners
elseif winners == nil then
return
else
minetest.log("error", "[tntrun] winners in on_celebration is neither a string, table or nil")
return winners
end
for w=1, #winners_list do
local p_name = winners_list[w]
minetest.sound_play('tntrun_win', {
to_player = p_name,
gain = 1.0,
}, true)
end
return winners
end)
minetest.register_on_joinplayer(function(player)
local inv = player:get_inventory()
local stack = ItemStack("tntrun:torch")
local taken = inv:remove_item("main", stack)
end)