-- Awaiting core support. local function __genOrderedIndex( t ) local orderedIndex = {} for key in pairs(t) do table.insert( orderedIndex, key ) end table.sort( orderedIndex ) return orderedIndex end local function orderedNext(t, state) -- Equivalent of the next function, but returns the keys in the alphabetic -- order. We use a temporary ordered key table that is stored in the -- table being iterated. local key = nil if state == nil then t.__orderedIndex = __genOrderedIndex( t ) key = t.__orderedIndex[1] else for i = 1,table.getn(t.__orderedIndex) do if t.__orderedIndex[i] == state then key = t.__orderedIndex[i+1] end end end if key then return key, t[key] end -- no more value to return, cleanup t.__orderedIndex = nil return end function orderedPairs(t) -- Equivalent of the pairs() function on tables. Allows to iterate -- in order return orderedNext, t, nil end -- Registered ctf.registered_on_load = {} function ctf.register_on_load(func) if ctf._mt_loaded then error("You can't register callbacks at game time!") end table.insert(ctf.registered_on_load, func) if ctf._loaddata then func(ctf._loaddata) end end ctf.registered_on_init = {} function ctf.register_on_init(func) if ctf._mt_loaded then error("You can't register callbacks at game time!") end table.insert(ctf.registered_on_init, func) if ctf._inited then func() end end ctf.registered_on_new_team = {} function ctf.register_on_new_team(func) if ctf._mt_loaded then error("You can't register callbacks at game time!") end table.insert(ctf.registered_on_new_team, func) end ctf.registered_on_territory_query = {} function ctf.register_on_territory_query(func) if ctf._mt_loaded then error("You can't register callbacks at game time!") end table.insert(ctf.registered_on_territory_query, func) end ctf.registered_on_new_game = {} function ctf.register_on_new_game(func) if ctf._mt_loaded then error("You can't register callbacks at game time!") end table.insert(ctf.registered_on_new_game, func) if ctf._new_game then func() end end function vector.distanceSQ(p1, p2) local x = p1.x - p2.x local y = p1.y - p2.y local z = p1.z - p2.z return x*x + y*y + z*z end -- Debug helpers function ctf.error(area, msg) minetest.log("error", "[CTF | " .. area .. "] " .. msg) end function ctf.log(area, msg) if area and area ~= "" then minetest.log("info", "[CTF | " .. area .. "] " .. msg) else minetest.log("info", "[CTF]" .. msg) end end function ctf.action(area, msg) if area and area ~= "" then minetest.log("action", "[CaptureTheFlag] (" .. area .. ") " .. msg) else minetest.log("action", "[CaptureTheFlag] " .. msg) end end function ctf.warning(area, msg) minetest.log("warning", "[CTF | " .. area .. "] " .. msg) end function ctf.init() ctf._inited = true ctf.log("init", "Initialising!") -- Set up structures ctf._defsettings = {} ctf.teams = {} ctf.players = {} -- See minetest.conf.example in the root of this subgame ctf.log("init", "Creating Default Settings") ctf._set("diplomacy", true) ctf._set("players_can_change_team", true) ctf._set("allocate_mode", 0) ctf._set("maximum_in_team", -1) ctf._set("default_diplo_state", "war") ctf._set("hud", true) ctf._set("autoalloc_on_joinplayer", true) ctf._set("friendly_fire", true) ctf._set("spawn_offset", "0,0,0") for i = 1, #ctf.registered_on_init do ctf.registered_on_init[i]() end ctf.load() end function ctf.reset() ctf.log("io", "Deleting CTF save data...") os.remove(minetest.get_worldpath().."/ctf.txt") ctf.player_last_team = {} ctf.init() end -- Set default setting value function ctf._set(setting, default) if ctf._defsettings[setting] then ctf.warning("settings", "Setting " .. dump(setting) .. " redeclared!") ctf.warning("settings", debug.traceback()) end ctf._defsettings[setting] = default if minetest.settings:get("ctf."..setting) then ctf.log("settings", "- " .. setting .. ": " .. minetest.settings:get("ctf."..setting)) elseif minetest.settings:get("ctf_"..setting) then ctf.log("settings", "- " .. setting .. ": " .. minetest.settings:get("ctf_"..setting)) ctf.warning("settings", "deprecated setting ctf_"..setting.. " used, use ctf."..setting.." instead.") end end function ctf.setting(name) local set = minetest.settings:get("ctf."..name) or minetest.settings:get("ctf_"..name) local dset = ctf._defsettings[name] if dset == nil then ctf.error("setting", "No such setting - " .. name) return nil end if set ~= nil then if type(dset) == "number" then return tonumber(set) elseif type(dset) == "boolean" then return minetest.is_yes(set) else return set end else return dset end end function ctf.load() ctf._new_game = true for i = 1, #ctf.registered_on_new_game do ctf.registered_on_new_game[i]() end end -- Disable knockback completely function minetest.calculate_knockback() return 0 end