map_maker: Refactor GUI into separate file

This commit is contained in:
ANAND 2019-12-18 09:09:53 +05:30
parent bd3b1c1a2d
commit 0e784b2c69
3 changed files with 350 additions and 310 deletions

View file

@ -0,0 +1,151 @@
function map_maker.show_gui(name)
local context = map_maker.get_context()
local mapauthor = context.mapauthor or name
local formspec = {
"size[9,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;", context.center.x, "]",
"field[1.4,1;1,1;posy;Y;", context.center.y, "]",
"field[2.4,1;1,1;posz;Z;", context.center.z, "]",
"field[0.4,2;1.5,1;posr;R;", context.center.r, "]",
"field[1.9,2;1.5,1;posh;H;", context.center.h, "]",
"button[4.3,0.7;1.75,1;set_center;Player Pos]",
"button[6.05,0.7;1.5,1;towe;To WE]",
"button[7.55,0.7;1.5,1;fromwe;From WE]",
"button[4.3,1.7;4.75,1;emerge;Emerge Area]",
"box[0,2.65;8.85,0.05;#111111BB]",
"label[0,2.8;2. Place Barriers]",
"label[0.1,3.3;This may take a few minutes.]",
"field[0.4,4.3;1,1;barrier_r;R;", context.barrier_r, "]",
"dropdown[1.15,4.05;1,1;barrier_rot;X=0,Z=0;",
context.barrier_rot == "x" and 1 or 2, "]",
"button[2.3,4;2,1;place_barriers;Place Barriers]",
"box[4.4,2.8;0.05,2.2;#111111BB]",
"label[4.8,2.8;3. Place Flags]",
"label[4.8,3.3;", minetest.formspec_escape(map_maker.get_flag_status()), "]",
"button[4.8,4;3.5,1;giveme;Giveme Flags]",
"box[0,5.06;8.85,0.05;#111111BB]",
"label[0,5.15;4. Meta Data]",
"field[0.4,6.2;8.5,1;title;Title;",
minetest.formspec_escape(context.maptitle), "]",
"field[0.4,7.3;8.5,1;initial;Stuff to give on (re)spawn, comma-separated itemstrings;",
minetest.formspec_escape(context.mapinitial), "]",
"field[0.4,8.4;4.25,1;name;File Name;",
minetest.formspec_escape(context.mapname), "]",
"field[4.625,8.4;4.25,1;author;Author;",
minetest.formspec_escape(mapauthor), "]",
"button_exit[1.3,9;3,1;close;Close]",
"button_exit[4.3,9;3,1;export;Export]",
}
formspec = table.concat(formspec, "")
minetest.show_formspec(name, "ctf_map:tool", formspec)
end
function map_maker.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
function map_maker.emerge_progress(ctx)
map_maker.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
local name = player:get_player_name()
if fields.posx or fields.posy or fields.posz or fields.posh or fields.posr then
map_maker.set_center(name, {
x = tonumber(fields.posx),
y = tonumber(fields.posy),
z = tonumber(fields.posz),
h = tonumber(fields.posh),
r = tonumber(fields.posr)
})
end
if fields.barrier_r then
map_maker.set_meta("barrier_r", tonumber(fields.barrier_r))
end
if fields.title then
map_maker.set_meta("maptitle", fields.title)
end
if fields.author then
map_maker.set_meta("mapauthor", fields.author)
end
if fields.name then
map_maker.set_meta("mapname", fields.name)
end
if fields.initial then
map_maker.set_meta("mapinitial", fields.initial)
end
if fields.barrier_rot then
map_maker.set_meta("barrier_rot", fields.barrier_rot == "X=0" and "x" or "z")
end
if fields.set_center then
map_maker.set_center(name)
end
if fields.giveme then
player:get_inventory():add_item("main", "ctf_map:flag 2")
end
if fields.emerge then
map_maker.emerge(name)
end
if fields.place_barriers then
map_maker.place_barriers(name)
end
if fields.towe then
map_maker.we_select(name)
end
if fields.fromwe then
map_maker.we_import(name)
end
if fields.export then
map_maker.export(name)
end
if not fields.quit then
map_maker.show_gui(name)
end
end)
minetest.register_chatcommand("gui", {
func = function(name)
map_maker.show_gui(name)
return true
end
})

View file

@ -1,5 +1,8 @@
-- Dofile the scripts only if ctf doesn't exist -- Dofile the scripts only if ctf doesn't exist
if not minetest.global_exists("ctf") then if not minetest.global_exists("ctf") then
map_maker = {}
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. "/" local modpath = minetest.get_modpath(minetest.get_current_modname()) .. "/"
dofile(modpath .. "gui.lua")
dofile(modpath .. "map_maker.lua") dofile(modpath .. "map_maker.lua")
end end

View file

@ -12,7 +12,7 @@ local defaults = {
} }
-- Reload mapmaker context from mod_storage if it exists -- Reload mapmaker context from mod_storage if it exists
local config = { local context = {
mapname = storage:get_string("mapname"), mapname = storage:get_string("mapname"),
maptitle = storage:get_string("maptitle"), maptitle = storage:get_string("maptitle"),
mapauthor = storage:get_string("mapauthor"), mapauthor = storage:get_string("mapauthor"),
@ -24,27 +24,27 @@ local config = {
barriers_placed = storage:get_int("barriers_placed") == 1 barriers_placed = storage:get_int("barriers_placed") == 1
} }
if config.mapname == "" then if context.mapname == "" then
config.mapname = defaults.mapname context.mapname = defaults.mapname
end end
if config.mapauthor == "" then if context.mapauthor == "" then
config.mapauthor = defaults.mapauthor context.mapauthor = defaults.mapauthor
end end
if config.maptitle == "" then if context.maptitle == "" then
config.maptitle = defaults.maptitle context.maptitle = defaults.maptitle
end end
if config.barrier_r == 0 then if context.barrier_r == 0 then
config.barrier_r = defaults.barrier_r context.barrier_r = defaults.barrier_r
end end
if config.center == "" then if context.center == "" then
config.center = defaults.center context.center = defaults.center
else else
config.center = minetest.parse_json(storage:get_string("center")) context.center = minetest.parse_json(storage:get_string("center"))
end end
if config.flags == "" then if context.flags == "" then
config.flags = defaults.flags context.flags = defaults.flags
else else
config.flags = minetest.parse_json(storage:get_string("flags")) context.flags = minetest.parse_json(storage:get_string("flags"))
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -73,16 +73,20 @@ assert(minetest.get_modpath("worldedit") and
minetest.get_modpath("worldedit_commands"), minetest.get_modpath("worldedit_commands"),
"worldedit and worldedit_commands are required!") "worldedit and worldedit_commands are required!")
local function check_step() -- Register special pickaxe to break indestructible nodes
for _, pos in pairs(config.flags) do minetest.register_tool("map_maker:adminpick", {
if minetest.get_node(pos).name ~= "ctf_map:flag" then description = "Admin pickaxe used to break indestructible nodes.",
minetest.set_node(pos, { name = "ctf_map:flag" }) inventory_image = "map_maker_adminpick.png",
end range = 16,
end tool_capabilities = {
full_punch_interval = 1.0,
minetest.after(1, check_step) max_drop_level = 3,
end groupcaps = {
minetest.after(1, check_step) immortal = {times = {[1] = 0.5}, uses = 0, maxlevel = 3}
},
damage_groups = {fleshy = 10000}
}
})
minetest.register_node(":ctf_map:flag", { minetest.register_node(":ctf_map:flag", {
description = "Flag", description = "Flag",
@ -106,29 +110,58 @@ minetest.register_node(":ctf_map:flag", {
}, },
groups = {oddly_breakable_by_hand=1,snappy=3}, groups = {oddly_breakable_by_hand=1,snappy=3},
after_place_node = function(pos) after_place_node = function(pos)
table.insert(config.flags, vector.new(pos)) table.insert(context.flags, vector.new(pos))
storage:set_string("flags", minetest.write_json(config.flags)) storage:set_string("flags", minetest.write_json(context.flags))
end, end,
on_destruct = function(pos) on_destruct = function(pos)
for i, v in pairs(config.flags) do for i, v in pairs(context.flags) do
if vector.equals(pos, v) then if vector.equals(pos, v) then
config.flags[i] = nil context.flags[i] = nil
return return
end end
end end
end, end,
}) })
local function check_step()
for _, pos in pairs(context.flags) do
if minetest.get_node(pos).name ~= "ctf_map:flag" then
minetest.set_node(pos, { name = "ctf_map:flag" })
end
end
minetest.after(1, check_step)
end
minetest.after(1, check_step)
local function get_flags()
local negative = nil
local positive = nil
for _, pos in pairs(context.flags) do
pos = vector.subtract(pos, context.center)
if context.barrier_rot == 0 and pos.x < 0 or pos.z < 0 then
negative = pos
end
if context.barrier_rot == 0 and pos.x > 0 or pos.z > 0 then
positive = pos
end
end
return negative, positive
end
local function to_2pos() local function to_2pos()
return { return {
x = config.center.x - config.center.r, x = context.center.x - context.center.r,
y = config.center.y - config.center.h / 2, y = context.center.y - context.center.h / 2,
z = config.center.z - config.center.r, z = context.center.z - context.center.r,
}, { }, {
x = config.center.x + config.center.r, x = context.center.x + context.center.r,
y = config.center.y + config.center.h / 2, y = context.center.y + context.center.h / 2,
z = config.center.z + config.center.r, z = context.center.z + context.center.r,
} }
end end
local function max(a, b) local function max(a, b)
@ -139,7 +172,24 @@ local function max(a, b)
end end
end end
local function we_select(name) --------------------------------------------------------------------------------
-- API --
--------------------------------------------------------------------------------
function map_maker.get_context()
return context
end
function map_maker.emerge(name)
local pos1, pos2 = to_2pos()
map_maker.show_progress_formspec(name, "Emerging area...")
ctf_map.emerge_with_callbacks(name, pos1, pos2, function()
map_maker.show_gui(name)
end, map_maker.emerge_progress)
return true
end
function map_maker.we_select(name)
local pos1, pos2 = to_2pos() local pos1, pos2 = to_2pos()
worldedit.pos1[name] = pos1 worldedit.pos1[name] = pos1
worldedit.mark_pos1(name) worldedit.mark_pos1(name)
@ -149,305 +199,141 @@ local function we_select(name)
worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos2)) worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos2))
end end
local function we_import(name) function map_maker.we_import(name)
local pos1 = worldedit.pos1[name] local pos1 = worldedit.pos1[name]
local pos2 = worldedit.pos2[name] local pos2 = worldedit.pos2[name]
if pos1 and pos2 then if pos1 and pos2 then
local size = vector.subtract(pos2, pos1) local size = vector.subtract(pos2, pos1)
local r = max(size.x, size.z) / 2 local r = max(size.x, size.z) / 2
config.center = vector.divide(vector.add(pos1, pos2), 2) context.center = vector.divide(vector.add(pos1, pos2), 2)
config.center.r = r context.center.r = r
config.center.h = size.y context.center.h = size.y
storage:set_string("center", minetest.write_json(config.center)) storage:set_string("center", minetest.write_json(context.center))
end end
end end
local function get_flags() function map_maker.set_meta(k, v)
local negative = nil if v ~= context[k] then
local positive = nil context[k] = v
for _, pos in pairs(config.flags) do
pos = vector.subtract(pos, config.center)
if config.barrier_rot == 0 and pos.x < 0 or pos.z < 0 then if type(v) == "number" then
negative = pos storage:set_int(k, v)
end else
storage:set_string(k, v)
if config.barrier_rot == 0 and pos.x > 0 or pos.z > 0 then
positive = pos
end end
end end
return negative, positive
end end
local function get_flag_status() function map_maker.set_center(name, center)
if #config.flags > 2 then if center then
return "Too many flags! (" .. #config.flags .. "/2)" for k, v in pairs(center) do
elseif #config.flags < 2 then context.center[k] = v
return "Place more flags (" .. #config.flags .. "/2)" end
else
local r = context.center.r
local h = context.center.h
local pos = minetest.get_player_by_name(name):get_pos()
context.center = vector.floor(pos)
context.center.r = r
context.center.h = h
end
storage:set_string("center", minetest.write_json(context.center))
end
function map_maker.get_flag_status()
if #context.flags > 2 then
return "Too many flags! (" .. #context.flags .. "/2)"
elseif #context.flags < 2 then
return "Place more flags (" .. #context.flags .. "/2)"
else else
local negative, positive = get_flags() local negative, positive = get_flags()
if positive and negative then if positive and negative then
return "Flags placed (" .. #config.flags .. "/2)" return "Flags placed (" .. #context.flags .. "/2)"
else else
return "Place one flag on each side of the barrier." return "Place one flag on each side of the barrier."
end end
end end
end end
local function show_gui(name) function map_maker.place_barriers(name)
if not config.mapauthor then local pos1, pos2 = to_2pos()
config.mapauthor = name map_maker.show_progress_formspec(name, "Emerging area...")
storage:set_string("mapauthor", config.mapauthor) ctf_map.emerge_with_callbacks(name, pos1, pos2, function()
end map_maker.show_progress_formspec(name,
"Placing center barrier, this may take a while...")
local formspec = {
"size[9,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;", config.center.x, "]",
"field[1.4,1;1,1;posy;Y;", config.center.y, "]",
"field[2.4,1;1,1;posz;Z;", config.center.z, "]",
"field[0.4,2;1.5,1;posr;R;", config.center.r, "]",
"field[1.9,2;1.5,1;posh;H;", config.center.h, "]",
"button[4.3,0.7;1.75,1;set_center;Player Pos]",
"button[6.05,0.7;1.5,1;towe;To WE]",
"button[7.55,0.7;1.5,1;fromwe;From WE]",
"button[4.3,1.7;4.75,1;emerge;Emerge Area]",
"box[0,2.65;8.85,0.05;#111111BB]",
"label[0,2.8;2. Place Barriers]",
"label[0.1,3.3;This may take a few minutes.]",
"field[0.4,4.3;1,1;barrier_r;R;", config.barrier_r, "]",
"dropdown[1.15,4.05;1,1;barrier_rot;X=0,Z=0;",
config.barrier_rot == "x" and 1 or 2, "]",
"button[2.3,4;2,1;place_barrier;Place Barriers]",
"box[4.4,2.8;0.05,2.2;#111111BB]",
"label[4.8,2.8;3. Place Flags]",
"label[4.8,3.3;", minetest.formspec_escape(get_flag_status()), "]",
"button[4.8,4;3.5,1;giveme;Giveme Flags]",
"box[0,5.06;8.85,0.05;#111111BB]",
"label[0,5.15;4. Meta Data]",
"field[0.4,6.2;8.5,1;title;Title;",
minetest.formspec_escape(config.maptitle), "]",
"field[0.4,7.3;8.5,1;initial;Stuff to give on (re)spawn, comma-separated itemstrings;",
minetest.formspec_escape(config.mapinitial), "]",
"field[0.4,8.4;4.25,1;name;File Name;",
minetest.formspec_escape(config.mapname), "]",
"field[4.625,8.4;4.25,1;author;Author;",
minetest.formspec_escape(config.mapauthor), "]",
"button_exit[1.3,9;3,1;close;Close]",
"button_exit[4.3,9;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
config.center.x = tonumber(fields.posx)
config.center.y = tonumber(fields.posy)
config.center.z = tonumber(fields.posz)
config.center.r = tonumber(fields.posr)
config.center.h = tonumber(fields.posh)
storage:set_string("center", minetest.write_json(config.center))
end
fields.barrier_r = tonumber(fields.barrier_r)
if fields.barrier_r and fields.barrier_r ~= config.barrier_r then
config.barrier_r = fields.barrier_r
storage:set_int("barrier_r", config.barrier_r)
end
if fields.title and fields.title ~= config.maptitle then
config.maptitle = fields.title
storage:set_string("maptitle", config.maptitle)
end
if fields.author and fields.author ~= config.mapauthor then
config.mapauthor = fields.author
storage:set_string("mapauthor", config.mapauthor)
end
if fields.name and fields.name ~= config.mapname then
config.mapname = fields.name
storage:set_string("mapname", config.mapname)
end
if fields.initial and fields.initial ~= config.mapinitial then
config.mapinitial = fields.initial
storage:set_string("mapinitial", config.mapinitial)
end
if fields.barrier_rot and fields.barrier_rot ~= "" then
config.barrier_rot = fields.barrier_rot == "X=0" and "x" or "z"
storage:set_string("barrier_rot", config.barrier_rot)
end
if fields.set_center then
local r = config.center.r
local h = config.center.h
config.center = vector.floor(player:get_pos())
config.center.r = r
config.center.h = h
storage:set_string("center", minetest.write_json(config.center))
end
if fields.giveme then
player:get_inventory():add_item("main", "ctf_map:flag 2")
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(config.center, config.barrier_r,
config.center.h, (config.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(config.center, config.barrier_r, config.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
if #config.flags ~= 2 then
minetest.chat_send_all("You need to place two flags!")
return
end
we_select(player_name)
show_progress_formspec(player_name, "Exporting...")
local path = minetest.get_worldpath() .. "/schems/" .. config.mapname .. "/"
minetest.mkdir(path)
-- Reset mod_storage
storage:set_string("center", "")
storage:set_string("maptitle", "")
storage:set_string("mapauthor", "")
storage:set_string("mapname", "")
storage:set_string("mapinitial", "")
storage:set_string("barrier_rot", "")
storage:set_string("barrier_r", "")
-- Write to .conf
local meta = Settings(path .. "map.conf")
meta:set("name", config.maptitle)
meta:set("author", config.mapauthor)
if config.mapinitial ~= "" then
meta:set("initial_stuff", config.mapinitial)
end
meta:set("rotation", config.barrier_rot)
meta:set("r", config.center.r)
meta:set("h", config.center.h)
for _, flags in pairs(config.flags) do
local pos = vector.subtract(flags, config.center)
if config.barrier_rot == 0 then
local old = vector.new(pos)
pos.x = old.z
pos.z = -old.x
end
local idx = pos.z > 0 and 1 or 2
meta:set("team." .. idx, pos.z > 0 and "red" or "blue")
meta:set("team." .. idx .. ".color", pos.z > 0 and "red" or "blue")
meta:set("team." .. idx .. ".pos", minetest.pos_to_string(pos))
end
meta:write()
minetest.after(0.1, function() minetest.after(0.1, function()
local filepath = path .. "map.mts" ctf_map.place_middle_barrier(context.center, context.barrier_r,
if minetest.create_schematic(worldedit.pos1[player_name], context.center.h, (context.barrier_rot == 0) and "x" or "z")
worldedit.pos2[player_name], worldedit.prob_list[player_name],
filepath) then map_maker.show_progress_formspec(name,
minetest.chat_send_all("Exported " .. config.mapname .. " to " .. path) "Placing outer barriers, this may take a while...")
minetest.close_formspec(player_name, "") minetest.after(0.1, function()
else ctf_map.place_outer_barrier(context.center, context.barrier_r, context.center.h)
minetest.chat_send_all("Failed!") map_maker.show_gui(name)
show_gui(player_name) end)
end
end) end)
end, map_maker.emerge_progress)
return true
end
function map_maker.export(name)
if #context.flags ~= 2 then
minetest.chat_send_all("You need to place two flags!")
return return
end end
if not fields.quit then map_maker.we_select(name)
show_gui(player_name) map_maker.show_progress_formspec(name, "Exporting...")
end
end)
minetest.register_chatcommand("gui", { local path = minetest.get_worldpath() .. "/schems/" .. context.mapname .. "/"
func = function(name) minetest.mkdir(path)
show_gui(name)
return true
end
})
-- Register special pickaxe to break indestructible nodes -- Reset mod_storage
minetest.register_tool("map_maker:adminpick", { storage:set_string("center", "")
description = "Admin pickaxe used to break indestructible nodes.", storage:set_string("maptitle", "")
inventory_image = "map_maker_adminpick.png", storage:set_string("mapauthor", "")
range = 16, storage:set_string("mapname", "")
tool_capabilities = { storage:set_string("mapinitial", "")
full_punch_interval = 1.0, storage:set_string("barrier_rot", "")
max_drop_level = 3, storage:set_string("barrier_r", "")
groupcaps = {
immortal = {times = {[1] = 0.5}, uses = 0, maxlevel = 3} -- Write to .conf
}, local meta = Settings(path .. "map.conf")
damage_groups = {fleshy = 10000} meta:set("name", context.maptitle)
} meta:set("author", context.mapauthor)
}) if context.mapinitial ~= "" then
meta:set("initial_stuff", context.mapinitial)
end
meta:set("rotation", context.barrier_rot)
meta:set("r", context.center.r)
meta:set("h", context.center.h)
for _, flags in pairs(context.flags) do
local pos = vector.subtract(flags, context.center)
if context.barrier_rot == 0 then
local old = vector.new(pos)
pos.x = old.z
pos.z = -old.x
end
local idx = pos.z > 0 and 1 or 2
meta:set("team." .. idx, pos.z > 0 and "red" or "blue")
meta:set("team." .. idx .. ".color", pos.z > 0 and "red" or "blue")
meta:set("team." .. idx .. ".pos", minetest.pos_to_string(pos))
end
meta:write()
minetest.after(0.1, function()
local filepath = path .. "map.mts"
if minetest.create_schematic(worldedit.pos1[name], worldedit.pos2[name],
worldedit.prob_list[name], filepath) then
minetest.chat_send_all("Exported " .. context.mapname .. " to " .. path)
minetest.close_formspec(name, "")
else
minetest.chat_send_all("Failed!")
map_maker.show_gui(name)
end
end)
return
end