diff --git a/mods/ctf_match/matches.lua b/mods/ctf_match/matches.lua index 1ae6230..93419a7 100644 --- a/mods/ctf_match/matches.lua +++ b/mods/ctf_match/matches.lua @@ -14,6 +14,14 @@ function ctf_match.register_on_new_match(func) table.insert(ctf_match.registered_on_new_match, func) end +ctf_match.registered_on_winner = {} +function ctf_match.register_on_winner(func) + if ctf._mt_loaded then + error("You can't register callbacks at game time!") + end + table.insert(ctf_match.registered_on_winner, func) +end + -- Load next match. May be overrided function ctf_match.next() @@ -38,6 +46,9 @@ function ctf_match.check_for_winner() -- There is a winner! 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 if ctf.setting("match") then ctf_match.next() end diff --git a/mods/ctf_match/vote.lua b/mods/ctf_match/vote.lua index 1f5427d..972713e 100644 --- a/mods/ctf_match/vote.lua +++ b/mods/ctf_match/vote.lua @@ -1,10 +1,18 @@ +ctf_match.registered_on_skip_map = {} +function ctf_match.register_on_skip_map(func) + if ctf._mt_loaded then + error("You can't register callbacks at game time!") + end + table.insert(ctf_match.registered_on_skip_map, func) +end + minetest.register_chatcommand("vote_next", { privs = { interact = true }, func = function(name, param) vote.new_vote(name, { - description = "Skip to next map", + description = "Skip to next match", help = "/yes, /no or /abstain", duration = 60, perc_needed = 0.5, @@ -12,10 +20,15 @@ minetest.register_chatcommand("vote_next", { on_result = function(self, result, results) if result == "yes" then + minetest.chat_send_all("Vote to skip match passed, " .. + #results.yes .. " to " .. #results.no) + for i = 1, #ctf_match.registered_on_skip_map do + ctf_match.registered_on_skip_map[i]() + end ctf_match.next() else - minetest.chat_send_all("Vote to skip map failed, " .. - #results.yes .. " to " .. #results.no) + minetest.chat_send_all("Vote to skip match failed, " .. + #results.no .. " to " .. #results.yes) end end, diff --git a/mods/ctf_pvp_engine b/mods/ctf_pvp_engine index dff4eee..d273457 160000 --- a/mods/ctf_pvp_engine +++ b/mods/ctf_pvp_engine @@ -1 +1 @@ -Subproject commit dff4eee6c7d672e3f818b115d4bcd764c8c62881 +Subproject commit d273457d9928b306c4e18c211d465637ed85f20b diff --git a/mods/ctf_stats/depends.txt b/mods/ctf_stats/depends.txt new file mode 100644 index 0000000..a77278b --- /dev/null +++ b/mods/ctf_stats/depends.txt @@ -0,0 +1,2 @@ +ctf +ctf_match diff --git a/mods/ctf_stats/init.lua b/mods/ctf_stats/init.lua new file mode 100644 index 0000000..c1ee857 --- /dev/null +++ b/mods/ctf_stats/init.lua @@ -0,0 +1,130 @@ +ctf_stats = {} + +function ctf_stats.load() + print("load") + local file = io.open(minetest.get_worldpath().."/ctf_stats.txt", "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + ctf_stats.matches = table.matches + ctf_stats.current = table.current + ctf_stats.players = table.players + return + end + end + + ctf_stats.matches = { + blue_wins = 0, + red_wins = 0, + skipped = 0 + } + + ctf_stats.current = { + red = {}, + blue = {} + } + + ctf_stats.players = {} +end + +ctf.register_on_save(function() + local file = io.open(minetest.get_worldpath().."/ctf_stats.txt", "w") + if file then + file:write(minetest.serialize({ + matches = ctf_stats.matches, + current = ctf_stats.current, + players = ctf_stats.players + })) + file:close() + else + ctf.error("io", "CTF file failed to save!") + end + + return nil +end) + +function ctf_stats.player(name) + print("get " .. name) + local tplayer = ctf.player(name) + local player = ctf_stats.players[name] + if not player then + player = { + red_wins = 0, + blue_wins = 0, + kills = 0, + deaths = 0, + attempts = 0 + } + ctf_stats.players[name] = player + end + + local mplayer = ctf_stats.current.red[name] or + ctf_stats.current.blue[name] + + return player, mplayer +end + +ctf.register_on_join_team(function(name, tname) + print("join team") + + ctf_stats.current[tname][name] = { + kills = 0, + deaths = 0, + attempts = 0 + } +end) + +ctf_match.register_on_skip_map(function() + print("skip map") + + ctf_stats.matches.skipped = ctf_stats.matches.skipped + 1 +end) + +ctf_match.register_on_winner(function(winner) + print("win " .. winner) + + ctf_stats.matches[winner .. "_wins"] = ctf_stats.matches[winner .. "_wins"] + 1 +end) + +ctf_match.register_on_new_match(function() + print("new match") + + -- TODO: create and show match report + + print(dump(ctf_stats.matches)) + print(dump(ctf_stats.current)) + print(dump(ctf_stats.players)) + + ctf_stats.current = { + red = {}, + blue = {} + } + minetest.after(3, function() + print(dump(ctf_stats.current)) + end) +end) + +ctf_flag.register_on_pick_up(function(name, flag) + print("pick up") + local main, match = ctf_stats.player(name) + main.attempts = main.attempts + 1 + match.attempts = match.attempts + 1 +end) + +ctf_flag.register_on_precapture(function(name, flag) + print("capture") + local tplayer = ctf.player(name) + local main, match = ctf_stats.player(name) + main[tplayer.team .. "_wins"] = main[tplayer.team .. "_wins"] + 1 + + return true +end) + +minetest.register_on_dieplayer(function(player) + print("die") + local main, match = ctf_stats.player(player:get_player_name()) + main.deaths = main.deaths + 1 + match.deaths = match.deaths + 1 +end) + +ctf_stats.load() diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 5dbdee8..d7b9676 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -332,15 +332,6 @@ minetest.register_craft({ } }) -minetest.register_craft({ - output = 'default:furnace', - recipe = { - {'group:stone', 'group:stone', 'group:stone'}, - {'group:stone', '', 'group:stone'}, - {'group:stone', 'group:stone', 'group:stone'}, - } -}) - minetest.register_craft({ type = "shapeless", output = "default:bronze_ingot", diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua deleted file mode 100644 index 6d89aae..0000000 --- a/mods/default/furnace.lua +++ /dev/null @@ -1,291 +0,0 @@ - --- --- Formspecs --- - -local function active_formspec(fuel_percent, item_percent) - local formspec = - "size[8,8.5]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[current_name;src;2.75,0.5;1,1;]".. - "list[current_name;fuel;2.75,2.5;1,1;]".. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - "list[current_name;dst;4.75,0.96;2,2;]".. - "list[current_player;main;0,4.25;8,1;]".. - "list[current_player;main;0,5.5;8,3;8]".. - "listring[current_name;dst]".. - "listring[current_player;main]".. - "listring[current_name;src]".. - "listring[current_player;main]".. - default.get_hotbar_bg(0, 4.25) - return formspec -end - -local inactive_formspec = - "size[8,8.5]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[current_name;src;2.75,0.5;1,1;]".. - "list[current_name;fuel;2.75,2.5;1,1;]".. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. - "list[current_name;dst;4.75,0.96;2,2;]".. - "list[current_player;main;0,4.25;8,1;]".. - "list[current_player;main;0,5.5;8,3;8]".. - "listring[current_name;dst]".. - "listring[current_player;main]".. - "listring[current_name;src]".. - "listring[current_player;main]".. - default.get_hotbar_bg(0, 4.25) - --- --- Node callback functions that are the same for active and inactive furnace --- - -local function can_dig(pos, player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") -end - -local function allow_metadata_inventory_put(pos, listname, index, stack, player) - if minetest.is_protected(pos, player:get_player_name()) then - return 0 - end - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - if listname == "fuel" then - if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then - if inv:is_empty("src") then - meta:set_string("infotext", "Furnace is empty") - end - return stack:get_count() - else - return 0 - end - elseif listname == "src" then - return stack:get_count() - elseif listname == "dst" then - return 0 - end -end - -local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local stack = inv:get_stack(from_list, from_index) - return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) -end - -local function allow_metadata_inventory_take(pos, listname, index, stack, player) - if minetest.is_protected(pos, player:get_player_name()) then - return 0 - end - return stack:get_count() -end - --- --- Node definitions --- - -minetest.register_node("default:furnace", { - description = "Furnace", - tiles = { - "default_furnace_top.png", "default_furnace_bottom.png", - "default_furnace_side.png", "default_furnace_side.png", - "default_furnace_side.png", "default_furnace_front.png" - }, - paramtype2 = "facedir", - groups = {cracky=2}, - legacy_facedir_simple = true, - is_ground_content = false, - sounds = default.node_sound_stone_defaults(), - - can_dig = can_dig, - - allow_metadata_inventory_put = allow_metadata_inventory_put, - allow_metadata_inventory_move = allow_metadata_inventory_move, - allow_metadata_inventory_take = allow_metadata_inventory_take, -}) - -minetest.register_node("default:furnace_active", { - description = "Furnace", - tiles = { - "default_furnace_top.png", "default_furnace_bottom.png", - "default_furnace_side.png", "default_furnace_side.png", - "default_furnace_side.png", - { - image = "default_furnace_front_active.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 1.5 - }, - } - }, - paramtype2 = "facedir", - light_source = 8, - drop = "default:furnace", - groups = {cracky=2, not_in_creative_inventory=1}, - legacy_facedir_simple = true, - is_ground_content = false, - sounds = default.node_sound_stone_defaults(), - - can_dig = can_dig, - - allow_metadata_inventory_put = allow_metadata_inventory_put, - allow_metadata_inventory_move = allow_metadata_inventory_move, - allow_metadata_inventory_take = allow_metadata_inventory_take, -}) - --- --- ABM --- - -local function swap_node(pos, name) - local node = minetest.get_node(pos) - if node.name == name then - return - end - node.name = name - minetest.swap_node(pos, node) -end - -minetest.register_abm({ - nodenames = {"default:furnace", "default:furnace_active"}, - interval = 1.0, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - -- - -- Inizialize metadata - -- - local meta = minetest.get_meta(pos) - local fuel_time = meta:get_float("fuel_time") or 0 - local src_time = meta:get_float("src_time") or 0 - local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 - - -- - -- Inizialize inventory - -- - local inv = meta:get_inventory() - for listname, size in pairs({ - src = 1, - fuel = 1, - dst = 4, - }) do - if inv:get_size(listname) ~= size then - inv:set_size(listname, size) - end - end - local srclist = inv:get_list("src") - local fuellist = inv:get_list("fuel") - local dstlist = inv:get_list("dst") - - -- - -- Cooking - -- - - -- Check if we have cookable content - local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) - local cookable = true - - if cooked.time == 0 then - cookable = false - end - - -- Check if we have enough fuel to burn - if fuel_time < fuel_totaltime then - -- The furnace is currently active and has enough fuel - fuel_time = fuel_time + 1 - - -- If there is a cookable item then check if it is ready yet - if cookable then - src_time = src_time + 1 - if src_time >= cooked.time then - -- Place result in dst list if possible - if inv:room_for_item("dst", cooked.item) then - inv:add_item("dst", cooked.item) - inv:set_stack("src", 1, aftercooked.items[1]) - src_time = 0 - end - end - end - else - -- Furnace ran out of fuel - if cookable then - -- We need to get new fuel - local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) - - if fuel.time == 0 then - -- No valid fuel in fuel list - fuel_totaltime = 0 - fuel_time = 0 - src_time = 0 - else - -- Take fuel from fuel list - inv:set_stack("fuel", 1, afterfuel.items[1]) - - fuel_totaltime = fuel.time - fuel_time = 0 - - end - else - -- We don't need to get new fuel since there is no cookable item - fuel_totaltime = 0 - fuel_time = 0 - src_time = 0 - end - end - - -- - -- Update formspec, infotext and node - -- - local formspec = inactive_formspec - local item_state = "" - local item_percent = 0 - if cookable then - item_percent = math.floor(src_time / cooked.time * 100) - item_state = item_percent .. "%" - else - if srclist[1]:is_empty() then - item_state = "Empty" - else - item_state = "Not cookable" - end - end - - local fuel_state = "Empty" - local active = "inactive " - if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then - active = "active " - local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) - fuel_state = fuel_percent .. "%" - formspec = active_formspec(fuel_percent, item_percent) - swap_node(pos, "default:furnace_active") - else - if not fuellist[1]:is_empty() then - fuel_state = "0%" - end - swap_node(pos, "default:furnace") - end - - local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")" - - -- - -- Set meta values - -- - meta:set_float("fuel_totaltime", fuel_totaltime) - meta:set_float("fuel_time", fuel_time) - meta:set_float("src_time", src_time) - meta:set_string("formspec", formspec) - meta:set_string("infotext", infotext) - end, -}) diff --git a/mods/default/init.lua b/mods/default/init.lua index 6f1b148..4fd6a34 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -37,7 +37,6 @@ default.gui_survival_form = "size[8,8.5]".. -- Load files dofile(minetest.get_modpath("default").."/functions.lua") dofile(minetest.get_modpath("default").."/nodes.lua") -dofile(minetest.get_modpath("default").."/furnace.lua") dofile(minetest.get_modpath("default").."/tools.lua") dofile(minetest.get_modpath("default").."/craftitems.lua") dofile(minetest.get_modpath("default").."/crafting.lua")