diff --git a/mods/ctf_barrier/depends.txt b/mods/ctf_barrier/depends.txt deleted file mode 100644 index bce8197..0000000 --- a/mods/ctf_barrier/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -default -ctf -ctf_match diff --git a/mods/ctf_barrier/init.lua b/mods/ctf_barrier/init.lua deleted file mode 100644 index 7a45b5f..0000000 --- a/mods/ctf_barrier/init.lua +++ /dev/null @@ -1,236 +0,0 @@ -minetest.register_node("ctf_barrier:ind_glass", { - description = "You cheater you!", - drawtype = "glasslike_framed_optional", - tiles = {"default_glass.png", "default_glass_detail.png"}, - inventory_image = minetest.inventorycube("default_glass.png"), - paramtype = "light", - sunlight_propagates = true, - is_ground_content = false, - walkable = true, - buildable_to = false, - pointable = false, - groups = {immortal = 1}, - sounds = default.node_sound_glass_defaults() -}) - -minetest.register_node("ctf_barrier:ind_stone", { - description = "Cheater!", - groups = {immortal = 1}, - tiles = {"default_stone.png"}, - is_ground_content = false -}) - -minetest.register_node("ctf_barrier:ind_glass_red", { - description = "You cheater you!", - drawtype = "glasslike", - tiles = {"ctf_barrier_red.png"}, - inventory_image = minetest.inventorycube("default_glass.png"), - paramtype = "light", - sunlight_propagates = true, - is_ground_content = false, - walkable = true, - buildable_to = false, - use_texture_alpha = false, - alpha = 0, - pointable = false, - groups = {immortal = 1}, - sounds = default.node_sound_glass_defaults() -}) - -local c_stone = minetest.get_content_id("ctf_barrier:ind_stone") -local c_glass = minetest.get_content_id("ctf_barrier:ind_glass") -local c_glass_red = minetest.get_content_id("ctf_barrier:ind_glass_red") -local c_water = minetest.get_content_id("default:water_source") -local c_water_f = minetest.get_content_id("default:water_flowing") -local c_air = minetest.get_content_id("air") -local r = tonumber(minetest.setting_get("barrier")) -minetest.register_on_generated(function(minp, maxp, seed) - if not ((minp.x <= -r and maxp.x >= -r) - or (minp.x <= r and maxp.x >= r) - or (minp.y <= -r and maxp.x >= -r) - or (minp.y <= r and maxp.x >= r) - or (minp.z <= -r and maxp.z >= -r) - or (minp.z <= 0 and maxp.z >= 0) - or (minp.z <= r and maxp.z >= r and ctf_match.build_timer > 0)) then - return - end - - -- Set up voxel manip - local t1 = os.clock() - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local a = VoxelArea:new{ - MinEdge={x=emin.x, y=emin.y, z=emin.z}, - MaxEdge={x=emax.x, y=emax.y, z=emax.z}, - } - local data = vm:get_data() - - -- Left - if minp.x <= -r and maxp.x >= -r then - local x = -r - for z = minp.z, maxp.z do - for y = minp.y, maxp.y do - local vi = a:index(x, y, z) - - if data[vi] == c_air or data[vi] == c_glass then - data[vi] = c_glass - else - data[vi] = c_stone - end - end - end - end - - -- Right - if minp.x <= r and maxp.x >= r then - local x = r - for z = minp.z, maxp.z do - for y = minp.y, maxp.y do - local vi = a:index(x, y, z) - if data[vi] == c_air or data[vi] == c_glass then - data[vi] = c_glass - else - data[vi] = c_stone - end - end - end - end - - -- Front - if minp.z <= -r and maxp.z >= -r then - local z = -r - for x = minp.x, maxp.x do - for y = minp.y, maxp.y do - local vi = a:index(x, y, z) - if data[vi] == c_air or data[vi] == c_glass then - data[vi] = c_glass - else - data[vi] = c_stone - end - end - end - end - - -- Back - if minp.z <= r and maxp.z >= r then - local z = r - for x = minp.x, maxp.x do - for y = minp.y, maxp.y do - local vi = a:index(x, y, z) - if data[vi] == c_air or data[vi] == c_glass then - data[vi] = c_glass - else - data[vi] = c_stone - end - end - end - end - - -- Barrier - if minp.z <= 0 and maxp.z >= 0 and ctf_match.build_timer > 0 then - local z = 0 - local x1 = minp.x - if x1 < -r then x1 = -r end - local x2 = maxp.x - if x2 > r then x2 = r end - for x = x1, x2 do - for y = minp.y, maxp.y do - local vi = a:index(x, y, z) - local node = data[vi] - if node == c_air or node == c_glass_red or - node == c_water or node == c_water_f then - data[vi] = c_glass_red - end - end - end - end - - vm:set_data(data) - vm:write_to_map(data) -end) - -ctf_match.register_on_build_time_end(function() - local min = { - x = -r + 1, - y = -r, - z = -1 - } - local max = { - x = r - 1, - y = r, - z = 1 - } - - local vm = minetest.get_voxel_manip() - local emin, emax = vm:read_from_map(min, max) - local a = VoxelArea:new{ - MinEdge = emin, - MaxEdge = emax - } - local data = vm:get_data() - for x = min.x, max.x do - for y = min.y, max.y do - local vi = a:index(x, y, 0) - if data[vi] == c_glass_red then - data[vi] = c_air - end - end - end - - vm:set_data(data) - vm:write_to_map(data) - vm:update_map() -end) - ---[[minetest.register_abm({ - nodenames = {"ctf_barrier:ind_glass_red"}, - interval = 10.0, -- Run every 10 seconds - chance = 2, -- Select every 1 in 50 nodes - action = function(pos, node, active_object_count, active_object_count_wider) - if ctf_match.build_timer > 0 then - return - end - - minetest.set_node(pos, {name = "air"}) - end -})]] - -local old_is_protected = minetest.is_protected -function minetest.is_protected(pos, name) - if ctf_match.build_timer <= 0 then - return old_is_protected(pos, name) - end - - local tname = ctf.player(name).team - if tname and - (tname == "blue" and pos.z >= 0) or (tname == "red" and pos.z <= 0) then - minetest.chat_send_player(name, "Can't dig beyond the barrier!") - return true - else - return old_is_protected(pos, name) - end -end - -local function pos_check() - if ctf_match.build_timer <= 0 then - return - end - - for _, player in pairs(minetest.get_connected_players()) do - local name = player:get_player_name() - local tname = ctf.player(name).team - local pos = player:getpos() - if tname and - (tname == "blue" and pos.z >= 0) or (tname == "red" and pos.z <= 0) then - minetest.chat_send_player(name, "Match hasn't started yet!") - ctf.move_to_spawn(name) - end - end - - if ctf_match.build_timer > 0.2 then - minetest.after(0.2, pos_check) - end -end - -ctf_match.register_on_build_time_start(function() - minetest.after(0.2, pos_check) -end) diff --git a/mods/ctf_map/README.md b/mods/ctf_map/README.md new file mode 100644 index 0000000..5d630aa --- /dev/null +++ b/mods/ctf_map/README.md @@ -0,0 +1,11 @@ +# CTF Map + +## Creating a new map + +* Find an area you like. It should be around 220x220 in surface area, but this + can vary. Feel free to modify the area to your needs. +* Using worldedit, select the area and save it to a schematic. +* Create a new world with singlenode and the capturetheflag_mapedit subgame. +* Enter and run type /loads to load the WIP schematic. +* Type /pb to place barriers. +* Export as a schematic again. diff --git a/mods/ctf_map/barrier.lua b/mods/ctf_map/barrier.lua new file mode 100644 index 0000000..c3b07e7 --- /dev/null +++ b/mods/ctf_map/barrier.lua @@ -0,0 +1,224 @@ +local c_stone = minetest.get_content_id("ctf_map:ind_stone") +local c_glass = minetest.get_content_id("ctf_map:ind_glass") +local c_glass_red = minetest.get_content_id("ctf_map:ind_glass_red") +local c_map_ignore = minetest.get_content_id("ctf_map:ignore") +local c_water = minetest.get_content_id("default:water_source") +local c_water_f = minetest.get_content_id("default:water_flowing") +local c_air = minetest.get_content_id("air") + +function ctf_map.remove_middle_barrier() + minetest.log("error", "Removing middle barrier!") + + local r = ctf_map.map.r + local h = ctf_map.map.h + + local min = { + x = -r + 1, + y = -h / 2, + z = -1 + } + local max = { + x = r - 1, + y = h / 2, + z = 1 + } + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(min, max) + local a = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax + } + local data = vm:get_data() + for x = min.x, max.x do + for y = min.y, max.y do + local vi = a:index(x, y, 0) + if data[vi] == c_glass_red then + data[vi] = c_air + end + end + end + + vm:set_data(data) + vm:write_to_map(data) + vm:update_map() +end + +function ctf_map.place_middle_barrier(center, r, h, direction) + assert(direction == "x" or direction == "z") + + local min = { + x = -r + 1, + y = -h / 2 + 1, + z = -r + 1, + } + local max = { + x = r - 1, + y = h / 2 - 1, + z = r - 1, + } + + local other = "z" + if direction == "z" then + other = "x" + end + + min[direction] = -1 + max[direction] = 1 + min = vector.add(center, min) + max = vector.add(center, max) + + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(min, max) + local a = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax + } + + local data = vm:get_data() + for x = min[other], max[other] do + for y = min.y, max.y do + local vi + if other == "x" then + vi = a:index(x, y, center.z) + else + vi = a:index(center.x, y, x) + end + if data[vi] == c_air then + data[vi] = c_glass_red + end + end + end + + vm:set_data(data) + vm:write_to_map(data) + vm:update_map() +end + + +function ctf_map.place_outer_barrier(center, r, h) + local minp = vector.subtract(center, r) + local maxp = vector.add(center, r) + minp.y = center.y - h / 2 + maxp.y = center.y + h / 2 + + print("Loading data into LVM") + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local a = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax + } + local data = vm:get_data() + + print("Placing left wall") + + -- Left + local x = center.x - r + for z = minp.z, maxp.z do + for y = minp.y, maxp.y do + local vi = a:index(x, y, z) + if data[vi] == c_air or data[vi] == c_glass or data[vi] == c_map_ignore then + data[vi] = c_glass + else + data[vi] = c_stone + end + end + end + + print("Placing right wall") + + -- Right + local x = center.x + r + for z = minp.z, maxp.z do + for y = minp.y, maxp.y do + local vi = a:index(x, y, z) + if data[vi] == c_air or data[vi] == c_glass or data[vi] == c_map_ignore then + data[vi] = c_glass + else + data[vi] = c_stone + end + end + end + + print("Placing front wall") + + -- Front + local z = center.z - r + for x = minp.x, maxp.x do + for y = minp.y, maxp.y do + local vi = a:index(x, y, z) + if data[vi] == c_air or data[vi] == c_glass or data[vi] == c_map_ignore then + data[vi] = c_glass + else + data[vi] = c_stone + end + end + end + + print("Placing back wall") + + -- Back + local z = center.z + r + for x = minp.x, maxp.x do + for y = minp.y, maxp.y do + local vi = a:index(x, y, z) + if data[vi] == c_air or data[vi] == c_glass or data[vi] == c_map_ignore then + data[vi] = c_glass + else + data[vi] = c_stone + end + end + end + + print("Writing to engine!") + + vm:set_data(data) + vm:write_to_map(data) + vm:update_map() +end + +if minetest.get_modpath("ctf") then + local old_is_protected = minetest.is_protected + function minetest.is_protected(pos, name) + if ctf_match.build_timer <= 0 then + return old_is_protected(pos, name) + end + + local tname = ctf.player(name).team + if tname and + (tname == "blue" and pos.z >= 0) or (tname == "red" and pos.z <= 0) then + minetest.chat_send_player(name, "Can't dig beyond the barrier!") + return true + else + return old_is_protected(pos, name) + end + end + + local function pos_check() + if ctf_match.build_timer <= 0 then + return + end + + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local tname = ctf.player(name).team + local pos = player:get_pos() + if tname and + (tname == "blue" and pos.z >= 0) or (tname == "red" and pos.z <= 0) then + minetest.chat_send_player(name, "Match hasn't started yet!") + ctf.move_to_spawn(name) + end + end + + if ctf_match.build_timer > 0.2 then + minetest.after(0.2, pos_check) + end + end + + ctf_match.register_on_build_time_start(function() + minetest.after(0.2, pos_check) + end) +end diff --git a/mods/ctf_map/depends.txt b/mods/ctf_map/depends.txt new file mode 100644 index 0000000..83ff9dc --- /dev/null +++ b/mods/ctf_map/depends.txt @@ -0,0 +1,4 @@ +default +ctf? +ctf_match? +worldedit? diff --git a/mods/ctf_map/emerge.lua b/mods/ctf_map/emerge.lua new file mode 100644 index 0000000..2d45854 --- /dev/null +++ b/mods/ctf_map/emerge.lua @@ -0,0 +1,31 @@ + +local function emergeblocks_callback(pos, action, num_calls_remaining, ctx) + if ctx.total_blocks == 0 then + ctx.total_blocks = num_calls_remaining + 1 + ctx.current_blocks = 0 + end + ctx.current_blocks = ctx.current_blocks + 1 + + if ctx.current_blocks == ctx.total_blocks then + minetest.chat_send_player(ctx.name, + string.format("Finished emerging %d blocks in %.2fms.", + ctx.total_blocks, (os.clock() - ctx.start_time) * 1000)) + + ctx:callback() + else + ctx:progress() + end +end + +function ctf_map.emerge_with_callbacks(name, pos1, pos2, callback, progress) + local context = { + current_blocks = 0, + total_blocks = 0, + start_time = os.clock(), + name = name, + callback = callback, + progress = progress + } + + minetest.emerge_area(pos1, pos2, emergeblocks_callback, context) +end diff --git a/mods/ctf_map/init.lua b/mods/ctf_map/init.lua new file mode 100644 index 0000000..c1f03fe --- /dev/null +++ b/mods/ctf_map/init.lua @@ -0,0 +1,15 @@ +ctf_map = {} + +dofile(minetest.get_modpath("ctf_map") .. "/nodes.lua") +dofile(minetest.get_modpath("ctf_map") .. "/emerge.lua") +dofile(minetest.get_modpath("ctf_map") .. "/barrier.lua") + + +if minetest.get_modpath("ctf") then + dofile(minetest.get_modpath("ctf_map") .. "/schem_map.lua") + + assert(ctf_match) + ctf_match.register_on_build_time_end(ctf_map.remove_middle_barrier) +else + dofile(minetest.get_modpath("ctf_map") .. "/map_maker.lua") +end diff --git a/mods/ctf_map/map_maker.lua b/mods/ctf_map/map_maker.lua new file mode 100644 index 0000000..5d7b22a --- /dev/null +++ b/mods/ctf_map/map_maker.lua @@ -0,0 +1,208 @@ +minetest.register_on_joinplayer(function(player) + minetest.after(1, function(name) + minetest.chat_send_player(name, "*** CTF_MAP IS IN MAP MAKER MODE ***") + end, player:get_player_name()) +end) + +assert(minetest.get_modpath("worldedit") and + minetest.get_modpath("worldedit_commands"), + "worldedit and worldedit_commands are required!") + +local center = { x = 0, y = 0, z = 0, r = 115, h = 140 } +local function to_2pos() + return { + x = center.x - center.r, + y = center.y - center.h / 2, + z = center.z - center.r, + }, { + x = center.x + center.r, + y = center.y + center.h / 2, + z = center.z + center.r, + } +end + +local function max(a, b) + if a > b then + return a + else + return b + end +end + +local function we_select(name) + local pos1, pos2 = to_2pos() + worldedit.pos1[name] = pos1 + worldedit.mark_pos1(name) + worldedit.player_notify(name, "position 1 set to " .. minetest.pos_to_string(pos1)) + worldedit.pos2[name] = pos2 + worldedit.mark_pos2(name) + worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos2)) +end + +local function we_import(name) + local pos1 = worldedit.pos1[name] + local pos2 = worldedit.pos2[name] + if pos1 and pos2 then + local size = vector.subtract(pos2, pos1) + local r = max(size.x, size.z) / 2 + center = vector.divide(vector.add(pos1, pos2), 2) + center.r = r + center.h = size.y + end +end + + +local randint = math.random(100) +local barrier_r = 110 +local mapname = "ctf_" .. randint +local maptitle = "Untitled Map " .. randint +local mapauthor = nil +local center_barrier_rot = 1 +local function show_gui(name) + local author = mapauthor or name + local formspec = { + "size[8,9.5]", + "bgcolor[#080808BB;true]", + default.gui_bg, + default.gui_bg_img, + + "label[0,0;1. Select Area]", + "field[0.4,1;1,1;posx;X;", center.x, "]", + "field[1.4,1;1,1;posy;Y;", center.y, "]", + "field[2.4,1;1,1;posz;Z;", center.z, "]", + "field[0.4,2;1,1;posr;R;", center.r, "]", + "field[1.4,2;1,1;posh;H;", center.h, "]", + "button[4.3,0.7;1.5,1;set_center;Player Pos]", + "button[5.8,0.7;1.1,1;towe;To WE]", + "button[6.9,0.7;1.1,1;fromwe;From WE]", + "button[4.3,1.7;1.5,1;emerge;Emerge Area]", + + "label[0,3;2. Place Barriers]", + "label[0,3.5;This may take a few minutes.]", + "field[0.4,4.5;1,1;barrier_r;R;", barrier_r, "]", + "dropdown[1.15,4.25;1,1;center_barrier_rot;X=0,Z=0;", center_barrier_rot + 1, "]", + "button[2.3,4.2;2,1;place_barrier;Place Barriers]", + + "label[0,5.5;3. Meta Data]", + "field[0.4,6.5;7.5,1;title;Title;" , minetest.formspec_escape(maptitle), "]", + "field[0.4,7.8;3.75,1;name;File Name;" , minetest.formspec_escape(mapname), "]", + "field[4.15,7.8;3.75,1;author;Author;", minetest.formspec_escape(author), "]", + + "button_exit[0.8,8.8;3,1;close;Close]", + "button_exit[3.8,8.8;3,1;export;Export]", + } + + formspec = table.concat(formspec, "") + minetest.show_formspec(name, "ctf_map:tool", formspec) +end + +local function show_progress_formspec(name, text) + minetest.show_formspec(name, "ctf_map:progress", + "size[6,1]bgcolor[#080808BB;true]" .. + default.gui_bg .. + default.gui_bg_img .. "label[0,0;" .. + minetest.formspec_escape(text) .. "]") +end + +local function emerge_progress(ctx) + show_progress_formspec(ctx.name, string.format("Emerging Area - %d/%d blocks emerged (%.1f%%)", + ctx.current_blocks, ctx.total_blocks, + (ctx.current_blocks / ctx.total_blocks) * 100)) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "ctf_map:tool" then + return + end + + if fields.posx then + center.x = tonumber(fields.posx) + center.y = tonumber(fields.posy) + center.z = tonumber(fields.posz) + center.r = tonumber(fields.posr) + center.h = tonumber(fields.posh) + barrier_r = tonumber(fields.barrier_r) + end + + if fields.center_barrier_rot and fields.center_barrier_rot ~= "" then + center_barrier_rot = fields.center_barrier_rot == "X=0" and 0 or 1 + end + + if fields.set_center then + local r = center.r + local h = center.h + center = vector.floor(player:get_pos()) + center.r = r + center.h = h + end + + local player_name = player:get_player_name() + + if fields.emerge then + local pos1, pos2 = to_2pos() + show_progress_formspec(player_name, "Emerging area...") + ctf_map.emerge_with_callbacks(player_name, pos1, pos2, function() + show_gui(player_name) + end, emerge_progress) + return true + end + + if fields.place_barrier then + local pos1, pos2 = to_2pos() + show_progress_formspec(player_name, "Emerging area...") + ctf_map.emerge_with_callbacks(player_name, pos1, pos2, function() + show_progress_formspec(player_name, "Placing center barrier, this may take a while...") + + minetest.after(0.1, function() + ctf_map.place_middle_barrier(center, barrier_r, center.h, (center_barrier_rot == 0) and "x" or "z") + show_progress_formspec(player_name, "Placing outer barriers, this may take a while...") + minetest.after(0.1, function() + ctf_map.place_outer_barrier(center, barrier_r, center.h) + show_gui(player_name) + end) + end) + end, emerge_progress) + return true + end + + if fields.towe then + we_select(player_name) + end + + if fields.fromwe then + we_import(player_name) + end + + if fields.export then + we_select(player_name) + show_progress_formspec(player_name, "Exporting...") + + minetest.after(0.1, function() + local path = minetest.get_worldpath() .. "/schems" + minetest.mkdir(path) + + local filepath = path .. "/" .. mapname .. ".mts" + if minetest.create_schematic(worldedit.pos1[player_name], + worldedit.pos2[player_name], worldedit.prob_list[player_name], + filepath) then + minetest.chat_send_all("Exported to " .. filepath) + minetest.close_formspec(player_name, "") + else + minetest.chat_send_all("Failed!") + show_gui(player_name) + end + end) + return + end + + if not fields.quit then + show_gui(player_name) + end +end) + +minetest.register_chatcommand("gui", { + func = function(name) + show_gui(name) + return true + end +}) diff --git a/mods/ctf_map/maps/01_two_hills.conf b/mods/ctf_map/maps/01_two_hills.conf new file mode 100644 index 0000000..7452767 --- /dev/null +++ b/mods/ctf_map/maps/01_two_hills.conf @@ -0,0 +1,11 @@ +name = Two Hills and Two Lakes +author = rubenwardy +rotation = z +h = 140 +r = 115 +team.1 = red +team.1.color = red +team.1.pos = 7,27,93 +team.2 = blue +team.2.color = blue +team.2.pos = -22,28,-78 diff --git a/mods/ctf_map/maps/01_two_hills.mts b/mods/ctf_map/maps/01_two_hills.mts new file mode 100644 index 0000000..91c7885 Binary files /dev/null and b/mods/ctf_map/maps/01_two_hills.mts differ diff --git a/mods/ctf_map/maps/02_bridge.conf b/mods/ctf_map/maps/02_bridge.conf new file mode 100644 index 0000000..0e9850f --- /dev/null +++ b/mods/ctf_map/maps/02_bridge.conf @@ -0,0 +1,11 @@ +name = The Bridge +author = rubenwardy +rotation = x +r = 110 +h = 220 +team.1 = red +team.1.color = red +team.1.pos = -57,-60,94 +team.2 = blue +team.2.color = blue +team.2.pos = -74,-56,-70 diff --git a/mods/ctf_map/maps/02_bridge.mts b/mods/ctf_map/maps/02_bridge.mts new file mode 100644 index 0000000..e5b8da5 Binary files /dev/null and b/mods/ctf_map/maps/02_bridge.mts differ diff --git a/mods/ctf_map/nodes.lua b/mods/ctf_map/nodes.lua new file mode 100644 index 0000000..0c08475 --- /dev/null +++ b/mods/ctf_map/nodes.lua @@ -0,0 +1,52 @@ +minetest.register_node("ctf_map:ignore", { + description = "MyAir (you hacker you!)", + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + walkable = true, + pointable = false, + diggable = false, + buildable_to = false, + air_equivalent = true, + drop = "", + groups = {not_in_creative_inventory=1} +}) + +minetest.register_node("ctf_map:ind_glass", { + description = "You cheater you!", + drawtype = "glasslike_framed_optional", + tiles = {"default_glass.png", "default_glass_detail.png"}, + inventory_image = minetest.inventorycube("default_glass.png"), + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + walkable = true, + buildable_to = false, + pointable = false, + groups = {immortal = 1}, + sounds = default.node_sound_glass_defaults() +}) + +minetest.register_node("ctf_map:ind_stone", { + description = "Cheater!", + groups = {immortal = 1}, + tiles = {"default_stone.png"}, + is_ground_content = false +}) + +minetest.register_node("ctf_map:ind_glass_red", { + description = "You cheater you!", + drawtype = "glasslike", + tiles = {"ctf_map_red.png"}, + inventory_image = minetest.inventorycube("default_glass.png"), + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + walkable = true, + buildable_to = false, + use_texture_alpha = false, + alpha = 0, + pointable = false, + groups = {immortal = 1}, + sounds = default.node_sound_glass_defaults() +}) diff --git a/mods/ctf_map/schem_map.lua b/mods/ctf_map/schem_map.lua new file mode 100644 index 0000000..b8cee92 --- /dev/null +++ b/mods/ctf_map/schem_map.lua @@ -0,0 +1,78 @@ +assert(minetest.get_mapgen_setting("mg_name") == "singlenode", "singlenode mapgen is required.") + +minetest.register_alias("mapgen_singlenode", "ctf_map:ignore") + +function ctf_map.place_map(map) + local r = map.r + local h = map.h + minetest.emerge_area({ x = -r, y = -h / 2, z = -r }, { x = r, y = h / 2, z = r }) + + local res = minetest.place_schematic({ x = -r - 5, y = -h / 2, z = -r - 5 }, + minetest.get_modpath("ctf_map") .. "/maps/" .. map.schematic, map.rotation == "z" and "0" or "90") + + return res ~= nil +end + +ctf_map.map = nil + +function ctf_match.load_map_meta(name) + local meta = Settings(minetest.get_modpath("ctf_map") .. "/maps/" .. name .. ".conf") + local map = { + name = meta:get("name"), + author = meta:get("author"), + rotation = meta:get("rotation"), + schematic = name .. ".mts", + r = tonumber(meta:get("r")), + h = tonumber(meta:get("h")), + teams = {} + } + + local i = 1 + while meta:get("team." .. i) do + local tname = meta:get("team." .. i) + local tcolor = meta:get("team." .. i .. ".color") + local tpos = minetest.string_to_pos(meta:get("team." .. i .. ".pos")) + + map.teams[tname] = { + color = tcolor, + pos = tpos, + } + + i = i + 1 + end + + return map +end + +ctf_match.register_on_new_match(function() + ctf_map.map = ctf_match.load_map_meta("01_two_hills") + print(dump(ctf_map.map)) + ctf_map.place_map(ctf_map.map) +end) + +function ctf_match.create_teams() + local number = ctf.setting("match.teams") + + for key, value in pairs(ctf_map.map.teams) do + local name = key + local color = value.color + local flag = value.pos + + if name and color and flag then + print(" - creating " .. key) + ctf.team({ + name = name, + color = color, + add_team = true + }) + + ctf_flag.add(name, flag) + + minetest.after(0, function() + ctf_flag.assert_flag(flag) + end) + else + minetest.log("error", " - Failed to create " .. key) + end + end +end diff --git a/mods/ctf_barrier/textures/ctf_barrier_red.png b/mods/ctf_map/textures/ctf_map_red.png similarity index 100% rename from mods/ctf_barrier/textures/ctf_barrier_red.png rename to mods/ctf_map/textures/ctf_map_red.png diff --git a/mods/ctf_match/init.lua b/mods/ctf_match/init.lua index 4ac8c2f..681a224 100644 --- a/mods/ctf_match/init.lua +++ b/mods/ctf_match/init.lua @@ -7,7 +7,6 @@ end dofile(minetest.get_modpath("ctf_match") .. "/matches.lua") dofile(minetest.get_modpath("ctf_match") .. "/buildtime.lua") -dofile(minetest.get_modpath("ctf_match") .. "/reset.lua") dofile(minetest.get_modpath("ctf_match") .. "/chat.lua") dofile(minetest.get_modpath("ctf_match") .. "/vote.lua") diff --git a/mods/ctf_match/matches.lua b/mods/ctf_match/matches.lua index b83c143..28aba10 100644 --- a/mods/ctf_match/matches.lua +++ b/mods/ctf_match/matches.lua @@ -36,65 +36,7 @@ function ctf_match.next() end ctf.reset() - -- Note: ctf.reset calls register_on_new_game, below. -end --- Check for winner -local game_won = false -function ctf_match.check_for_winner() - local winner - for name, team in pairs(ctf.teams) do - if winner then - return - end - winner = name - end - - -- There is a winner! - if not game_won then - game_won = true - ctf.action("match", winner .. " won!") - minetest.chat_send_all("Team " .. winner .. " won!") - for i = 1, #ctf_match.registered_on_winner do - ctf_match.registered_on_winner[i](winner) - end - minetest.after(2, function() - game_won = false - if ctf.setting("match") then - ctf_match.next() - end - end) - end -end - -function ctf_match.create_teams() - local number = ctf.setting("match.teams") - - for i = 1, number do - print("Creating team #" .. i) - local name = ctf.setting("match.team." .. i) - local color = ctf.setting("match.team." .. i .. ".color") - local pos = ctf.setting("match.team." .. i .. ".pos") - local flag = minetest.string_to_pos(pos) - - if name and color and pos and flag then - print(" - Success in getting settings") - ctf.team({ - name = name, - color = color, - add_team = true - }) - - ctf_flag.add(name, flag) - - minetest.after(0, function() - ctf_flag.assert_flag(flag) - end) - end - end -end - -ctf.register_on_new_game(function() ctf_match.create_teams() for i, player in pairs(minetest.get_connected_players()) do @@ -125,7 +67,40 @@ ctf.register_on_new_game(function() if minetest.global_exists("chatplus") then chatplus.log("Next round!") end -end) +end + +-- Check for winner +local game_won = false +function ctf_match.check_for_winner() + local winner + for name, team in pairs(ctf.teams) do + if winner then + return + end + winner = name + end + + -- There is a winner! + if not game_won then + game_won = true + ctf.action("match", winner .. " won!") + minetest.chat_send_all("Team " .. winner .. " won!") + for i = 1, #ctf_match.registered_on_winner do + ctf_match.registered_on_winner[i](winner) + end + minetest.after(2, function() + game_won = false + if ctf.setting("match") then + ctf_match.next() + end + end) + end +end + +-- This is overriden by ctf_map +function ctf_match.create_teams() + error("Error! Unimplemented") +end ctf_flag.register_on_capture(function(attname, flag) if not ctf.setting("match.destroy_team") then diff --git a/mods/ctf_match/reset.lua b/mods/ctf_match/reset.lua deleted file mode 100644 index d244fe6..0000000 --- a/mods/ctf_match/reset.lua +++ /dev/null @@ -1,34 +0,0 @@ -ctf.register_on_init(function() - ctf._set("match.map_reset_limit", 0) -end) - -function ctf_match.next() - for i = 1, #ctf_match.registered_on_new_match do - ctf_match.registered_on_new_match[i]() - end - - local r = ctf.setting("match.map_reset_limit") - if r > 0 then - minetest.chat_send_all("Resetting the map, this may take a few moments...") - minetest.after(0.5, function() - minetest.delete_area(vector.new(-r, -r, -r), vector.new(r, r, r)) - - minetest.after(1, function() - minetest.clear_objects() - ctf.reset() - if vote then - vote.active = {} - vote.queue = {} - vote.update_all_hud() - end - end) - end) - else - ctf.reset() - if vote then - vote.active = {} - vote.queue = {} - vote.update_all_hud() - end - end -end