local S = minetest.get_translator("lzr_editor") minetest.register_chatcommand("editor", { privs = { server = true }, description = S("Start or exit level editor"), params = S("[ enter | exit ]"), func = function(name, param) if param == "" or param == "enter" then local state = lzr_gamestate.get_state() if state == lzr_gamestate.EDITOR then return false, S("Already in level editor!") elseif state == lzr_gamestate.LEVEL or state == lzr_gamestate.LEVEL_COMPLETE then lzr_gamestate.set_state(lzr_gamestate.EDITOR) return true else lzr_levels.start_level(1) lzr_gamestate.set_state(lzr_gamestate.EDITOR) return true end elseif param == "exit" then local state = lzr_gamestate.get_state() if state ~= lzr_gamestate.EDITOR then return false, S("Not in level editor!") else lzr_gamestate.set_state(lzr_gamestate.LEVEL) return true end end return false end, }) minetest.register_chatcommand("editor_size", { privs = { server = true }, description = S("Set level size for editor (warning: clears level contents!)"), params = ",,", func = function(name, param) if lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then return false, S("Not in editor mode!") end local size = minetest.string_to_pos(param) if not size then return false end if size.x > lzr_globals.PLAYFIELD_SIZE.x-1 or size.y > lzr_globals.PLAYFIELD_SIZE.y-1 or size.z > lzr_globals.PLAYFIELD_SIZE.z-1 then return false, S("Too large!") end if size.x < 1 or size.y < 4 or size.z < 1 then return false, S("Too small!") end lzr_levels.clear_playfield(size) lzr_levels.build_room({pos=lzr_globals.LEVEL_POS, size=size}) return true end, }) -- Dummy save and load functions (only 1 level name supported for now) minetest.register_chatcommand("editor_save", { privs = { server = true }, description = S("Save current level"), params = "", func = function(name, param) -- TODO: Don't save the lasers if lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then return false, S("Not in editor mode!") end local num = tonumber(param) if not num then num = 1 end num = math.max(1, math.floor(num)) local level_name = "level_custom_"..num minetest.mkdir(minetest.get_worldpath().."/levels") local filename = minetest.get_worldpath().."/levels/"..level_name..".mts" local size = vector.subtract(lzr_levels.get_level_size(), vector.new(1, 1, 1)) local ok = minetest.create_schematic(lzr_globals.LEVEL_POS, vector.add(lzr_globals.LEVEL_POS, size), {}, filename, {}) if ok then minetest.log("action", "[lzr_editor] Level written to "..filename) return true, S("Level saved to @1.", filename) else minetest.log("error", "[lzr_editor] Failed to write level to "..filename) return false, S("Error writing level file!") end end, }) -- Returns true if the given file exists, false otherwise. -- * path: Path to file (without file name) -- * filename: File name of file (without path) local file_exists = function(path, filename) local levels = minetest.get_dir_list(path, false) for l=1, #levels do if levels[l] == filename then return true end end return false end minetest.register_chatcommand("editor_load", { privs = { server = true }, description = S("Load level"), params = "", func = function(name, param) if lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then return false, S("Not in editor mode!") end local num = tonumber(param) if not num then num = 1 end num = math.max(1, math.floor(num)) local level_name = "level_custom_"..num local ok = file_exists(minetest.get_worldpath().."/levels", level_name..".mts") if not ok then return false, S("Level file does not exist!") end local filename = minetest.get_worldpath().."/levels/"..level_name..".mts" local schem = minetest.read_schematic(filename, {write_yslice_prob="none"}) if schem then lzr_levels.prepare_and_build_custom_level(schem) minetest.log("action", "[lzr_editor] Level loaded from "..filename) return true, S("Level loaded.") else minetest.log("error", "[lzr_editor] Failed to read level from "..filename) return false, S("Error reading level file!") end end, }) -- Unlimited node placement in editor mode minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) if placer and placer:is_player() then return lzr_gamestate.get_state() == lzr_gamestate.EDITOR end end) -- Don't pick node up if the item is already in the inventory local old_handle_node_drops = minetest.handle_node_drops function minetest.handle_node_drops(pos, drops, digger) if not digger or not digger:is_player() or lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then return old_handle_node_drops(pos, drops, digger) end local inv = digger:get_inventory() if inv then for _, item in ipairs(drops) do if not inv:contains_item("main", item, true) then inv:add_item("main", item) end end end end lzr_gamestate.register_on_enter_state(function(state) if state == lzr_gamestate.EDITOR then local player = minetest.get_player_by_name("singleplayer") lzr_player.set_editor_inventory(player) lzr_gui.set_editor_gui(player) lzr_ambience.set_ambience("none") end end)