Skip to content

Commit

Permalink
Merge branch 'MT-CTF:master' into destructify-and-indestructify
Browse files Browse the repository at this point in the history
  • Loading branch information
src4026 authored Jul 6, 2024
2 parents 5616e2b + ed5bf21 commit 9598d7f
Show file tree
Hide file tree
Showing 19 changed files with 420 additions and 256 deletions.
64 changes: 40 additions & 24 deletions mods/apis/hud_events/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@ local HUD_COLORS = {
dark = 0x212529,
}

local hud_queues = {}
local hud_queues = {
-- {}, channel 1
-- {}, channel 2
-- ...
}
local quick_event_timer = {}

minetest.register_on_leaveplayer(function(player)
local pname = player:get_player_name()

if hud_queues[pname] then
hud_queues[pname].t:cancel()
hud_queues[pname] = nil
for channel=1, #hud_queues do
if hud_queues[channel][pname] then
hud_queues[channel][pname].t:cancel()
hud_queues[channel][pname] = nil
end
end

if quick_event_timer[pname] then
Expand All @@ -41,7 +47,7 @@ local function show_quick_hud_event(player, huddef)
hud:add(player, "hud_event_quick", {
hud_elem_type = "text",
position = {x = 0.5, y = 0.5},
offset = {x = 0, y = 45},
offset = {x = 0, y = 20},
alignment = {x = "center", y = "down"},
text = huddef.text,
color = huddef.color,
Expand All @@ -56,46 +62,49 @@ local function show_quick_hud_event(player, huddef)
quick_event_timer[pname] = minetest.after(HUD_SHOW_QUICK_TIME, function()
if not player:is_player() then return end

hud:remove(player, "hud_event_quick")
if hud:exists(player, "hud_event_quick") then
hud:remove(player, "hud_event_quick")
end
end)
end

local function handle_hud_events(player)
local function handle_hud_events(player, channel)
local pname = player:get_player_name()

local huddef = table.remove(hud_queues[pname].e, 1)
local huddef = table.remove(hud_queues[channel][pname].e, 1)
local event_name = "hud_event_"..tostring(channel)

if not hud:exists(player, "hud_event") then
hud:add(player, "hud_event", {
if not hud:exists(player, event_name) then
hud:add(player, event_name, {
hud_elem_type = "text",
position = {x = 0.5, y = 0.5},
offset = {x = 0, y = 20},
offset = {x = 0, y = 45 + (channel - 1) * 25},
alignment = {x = "center", y = "down"},
text = huddef.text,
color = huddef.color,
})
else
hud:change(player, "hud_event", {
hud:change(player, event_name, {
text = huddef.text,
color = huddef.color
})
end

hud_queues[pname].t = minetest.after(HUD_SHOW_TIME, function()
hud_queues[channel][pname].t = minetest.after(HUD_SHOW_TIME, function()
player = minetest.get_player_by_name(pname)

if player then
hud:change(player, "hud_event", {text = ""})
hud:change(player, event_name, {text = ""})

hud_queues[pname].t = minetest.after(HUD_SHOW_NEXT_TIME, function()
hud_queues[channel][pname].t = minetest.after(HUD_SHOW_NEXT_TIME, function()
player = minetest.get_player_by_name(pname)

if player then
if #hud_queues[pname].e >= 1 then
handle_hud_events(player)
if #hud_queues[channel][pname].e >= 1 then
handle_hud_events(player, channel)
else
hud:remove(player, "hud_event")
hud_queues[pname] = nil
hud:remove(player, event_name)
hud_queues[channel][pname] = nil
end
end
end)
Expand All @@ -108,6 +117,7 @@ end
text = "This is a hud event",
color = "info",
quick = true,
channel = an integer or nil
})
]]
function hud_events.new(player, def)
Expand All @@ -118,6 +128,8 @@ function hud_events.new(player, def)
def = {text = def}
end

def.channel = def.channel or 1

if def.color then
if type(def.color) == "string" then
def.color = HUD_COLORS[def.color]
Expand All @@ -129,13 +141,17 @@ function hud_events.new(player, def)
if not def.quick then
local pname = player:get_player_name()

if not hud_queues[pname] then
hud_queues[pname] = {e = {}}
while not hud_queues[def.channel] do
table.insert(hud_queues, {})
end

if not hud_queues[def.channel][pname] then
hud_queues[def.channel][pname] = {e = {}}
end
table.insert(hud_queues[pname].e, {text = def.text, color = def.color})
table.insert(hud_queues[def.channel][pname].e, {text = def.text, color = def.color, channel = def.channel})

if not hud_queues[pname].t then
handle_hud_events(player)
if not hud_queues[def.channel][pname].t then
handle_hud_events(player, def.channel)
end
else
show_quick_hud_event(player, def)
Expand Down
5 changes: 5 additions & 0 deletions mods/ctf/ctf_combat/ctf_healing/bandage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ function ctf_healing.register_bandage(name, def)
text = uname .. " healed you!",
color = 0xC1FF44,
})
hud_events.new(uname, {
quick = true,
text = "You healed "..pname.."!",
color = 0xC1FF44,
})
elseif type(result) == "string" then
hud_events.new(uname, {
quick = true,
Expand Down
69 changes: 35 additions & 34 deletions mods/ctf/ctf_map/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -194,56 +194,57 @@ minetest.register_chatcommand("ctf_barrier", {
"use /ctf_barrier remove_buildtime to remove unwanted parts"))
end

local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(pos1, pos2)
local a = VoxelArea:new{
MinEdge = emin,
MaxEdge = emax
}
local data = vm:get_data()

for x = pos1.x, pos2.x do
for y = pos1.y, pos2.y do
for z = pos1.z, pos2.z do
local vi = a:index(x, y, z)
if params == "place_buildtime" then
local current_pos = {x = x, y = y, z = z}
local current_node = minetest.get_node_or_nil(current_pos)
if current_node then
if current_node.name == "air" then
minetest.set_node(current_pos, {name = "ctf_map:ind_glass_red"})
elseif current_node.name == "default:stone" then
minetest.set_node(current_pos, {name = "ctf_map:ind_stone_red"})
elseif current_node.name == "default:water_source" then
minetest.set_node(current_pos, {name = "ctf_map:ind_water"})
elseif current_node.name == "default:lava_source" then
minetest.set_node(current_pos, {name = "ctf_map:ind_lava"})
end
if data[vi] == minetest.get_content_id("air") then
data[vi] = minetest.get_content_id("ctf_map:ind_glass_red")
elseif data[vi] == minetest.get_content_id("default:stone") then
data[vi] = minetest.get_content_id("ctf_map:ind_stone_red")
elseif data[vi] == minetest.get_content_id("default:water_source") then
data[vi] = minetest.get_content_id("ctf_map:ind_water")
elseif data[vi] == minetest.get_content_id("default:lava_source") then
data[vi] = minetest.get_content_id("ctf_map:ind_lava")
end
elseif params == "remove_buildtime" then
local current_pos = {x = x, y = y, z = z}
local current_node = minetest.get_node_or_nil(current_pos)
if current_node then
if current_node.name == "ctf_map:ind_glass_red" then
minetest.set_node(current_pos, {name = "air"})
elseif current_node.name == "ctf_map:ind_stone_red" then
minetest.set_node(current_pos, {name = "default:stone"})
elseif current_node.name == "ctf_map:ind_water" then
minetest.set_node(current_pos, {name = "default:water_source"})
elseif current_node.name == "ctf_map:ind_lava" then
minetest.set_node(current_pos, {name = "default:lava_source"})
end
if data[vi] == minetest.get_content_id("ctf_map:ind_glass_red") then
data[vi] = minetest.get_content_id("air")
elseif data[vi] == minetest.get_content_id("ctf_map:ind_stone_red") then
data[vi] = minetest.get_content_id("default:stone")
elseif data[vi] == minetest.get_content_id("ctf_map:ind_water") then
data[vi] = minetest.get_content_id("default:water_source")
elseif data[vi] == minetest.get_content_id("ctf_map:ind_lava") then
data[vi] = minetest.get_content_id("default:lava_source")
end
elseif params == "place_outer" then
local current_pos = {x = x, y = y, z = z}
if x == pos1.x or x == pos2.x or y == pos1.y
or z == pos1.z or z == pos2.z then
local current_node = minetest.get_node_or_nil(current_pos)
if current_node then
if current_node.name == "air" or
current_node.name == "ctf_map:ignore" or
current_node.name == "ignore" then
minetest.set_node(current_pos, {name = "ctf_map:ind_glass"})
else
minetest.set_node(current_pos, {name = "ctf_map:stone"})
end
if data[vi] == minetest.get_content_id("air") or
data[vi] == minetest.get_content_id("ignore") or
data[vi] == minetest.get_content_id("ctf_map:ignore") then
data[vi] = minetest.get_content_id("ctf_map:ind_glass")
else
data[vi] = minetest.get_content_id("ctf_map:stone")
end
end
end
end
end
end

vm:set_data(data)
vm:write_to_map(true)

local message =
(params == "place_buildtime" and "Build-time barrier placed") or
(params == "remove_buildtime" and "Build-time barrier removed") or
Expand Down
49 changes: 25 additions & 24 deletions mods/ctf/ctf_map/map_functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,52 +98,53 @@ function ctf_map.remove_barrier(mapmeta, callback)
minetest.after(0.1, function()
local vm2 = VoxelManip(pos1, pos2)
vm2:update_liquids()

callback()
end)
else
minetest.log("action", "Clearing barriers using barriers.data")

local i = 0
for _, barrier_area in pairs(mapmeta.barrier_data) do
minetest.after(i, function()
local vm = VoxelManip()
vm:read_from_map(barrier_area.pos1, barrier_area.pos2)
if mapmeta.barrier_data then
local vm = VoxelManip()
vm:read_from_map(barrier_area.pos1, barrier_area.pos2)

local data = vm:get_data()
local data = vm:get_data()

if #data ~= barrier_area.max then
-- minetest.log(dump(mapmeta.barrier_data)) -- Used for debugging issues
minetest.log("error", "Potential issue with barriers.data. Aborting... | " ..
"Debug: "..dump(#data)..", "..dump(barrier_area.max))
if #data ~= barrier_area.max then
-- minetest.log(dump(mapmeta.barrier_data)) -- Used for debugging issues
minetest.log("error", "Potential issue with barriers.data. Aborting... | " ..
"Debug: "..dump(#data)..", "..dump(barrier_area.max))

mapmeta.barrier_data = nil
ctf_map.remove_barrier(mapmeta, callback)
return
end
mapmeta.barrier_data = nil
ctf_map.remove_barrier(mapmeta, callback)
end

for idx in pairs(data) do
data[idx] = barrier_area.reps[idx] or ID_IGNORE
end
for idx in pairs(data) do
data[idx] = barrier_area.reps[idx] or ID_IGNORE
end

vm:set_data(data)
vm:write_to_map(false)
vm:set_data(data)
vm:write_to_map(false)
end
end)

i = i + 0.05
end

minetest.after(i - 0.05, function()
local vm = VoxelManip(mapmeta.pos1, mapmeta.pos2)
vm:update_liquids()
if mapmeta.barrier_data then
local vm = VoxelManip(mapmeta.pos1, mapmeta.pos2)
vm:update_liquids()

mapmeta.barrier_data = nil -- Contains a large amount of data, free it up now that it's not needed
mapmeta.barrier_data = nil -- Contains a large amount of data, free it up now that it's not needed

callback()
callback()
end
end)

return
end

callback()
end


Expand Down
20 changes: 20 additions & 0 deletions mods/ctf/ctf_map/nodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,26 @@ local function make_immortal(def)
def.description = def.description and ("Indestructible " .. def.description)
end

minetest.register_on_player_hpchange(function(player, hp_change, reason)
local pos = player:get_pos()
local def = minetest.registered_nodes[reason.node]

if reason.type == 'node_damage' and def.groups.immortal and def.drawtype == "normal" and def.walkable ~= false then
for _, flagteam in ipairs(ctf_teams.current_team_list) do
if flagteam ~= ctf_teams.get(player) and ctf_map.current_map.teams[flagteam] then
local fdist = vector.distance(pos, ctf_map.current_map.teams[flagteam].flag_pos)
if fdist <= 6 then
return hp_change
end
end
end

return 0
end

return hp_change
end, true)

local queue = {}
for name, def in pairs(minetest.registered_nodes) do
local mod, nodename = name:match"(..-):(.+)"
Expand Down
12 changes: 9 additions & 3 deletions mods/ctf/ctf_modebase/build_timer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function ctf_modebase.build_timer.start(build_time)
local time = build_time or ctf_modebase:get_current_mode().build_timer or DEFAULT_BUILD_TIME

if time > 0 then
if timer then timer:cancel() end
timer = timer_func(time)
end
end
Expand All @@ -61,8 +62,11 @@ function ctf_modebase.build_timer.finish()

if ctf_map.current_map then
ctf_map.remove_barrier(ctf_map.current_map, function()
timer:cancel()
timer = nil
if timer then
timer:cancel()
timer = nil
end

hud:remove_all()
local text = "Build time is over!"
minetest.chat_send_all(text)
Expand Down Expand Up @@ -99,7 +103,9 @@ minetest.is_protected = function(pos, pname, ...)

local pteam = ctf_teams.get(pname)

if pteam and not ctf_core.pos_inside(pos, ctf_teams.get_team_territory(pteam)) then
if pteam and ctf_teams.get_team_territory(pteam) and
not ctf_core.pos_inside(pos, ctf_teams.get_team_territory(pteam))
then
hud_events.new(pname, {
quick = true,
text = "You can't interact outside of your team territory during build time!",
Expand Down
Loading

0 comments on commit 9598d7f

Please sign in to comment.