From 395e142fcae5c25805eec9dd16298496c53ed1a9 Mon Sep 17 00:00:00 2001 From: Hugues Ross Date: Tue, 23 Nov 2021 07:59:59 -0500 Subject: [PATCH] Remove hard-coding of table metrics and calculate spacing/sizes --- init.lua | 2 +- skin_api.lua | 74 ++++- table.lua | 790 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 536 insertions(+), 330 deletions(-) diff --git a/init.lua b/init.lua index edf86e9..cb4d81e 100644 --- a/init.lua +++ b/init.lua @@ -43,4 +43,4 @@ cartographer = { materials = materials, -- scanner.lua: Exposes functions for queuing and performing terrain scans scanner = scanner, -}; +} diff --git a/skin_api.lua b/skin_api.lua index b88e59e..90a3fe0 100644 --- a/skin_api.lua +++ b/skin_api.lua @@ -32,10 +32,14 @@ return { node_texture = "cartographer_simple_table.png", background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_simple_table_bg", radius = 16, }, inner_background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_simple_table_bg_2", radius = 4, }, @@ -47,21 +51,40 @@ return { hovered_texture = "cartographer_simple_table_button_hovered", pressed_texture = "cartographer_simple_table_button_pressed", radius = 8, + width = 2, + height = 0.5, }, slot = { texture = "cartographer_simple_table_slot", radius = 8, + width = 1, + height = 1, }, separator = { texture = "cartographer_simple_table_separator", radius = "9,1", }, + material_indicator = { + width = 1, + height = 0.25, + spacing = 0.25 + }, label = { + margin_x = 0, + margin_y = 0, font_color = "#694a3a", texture = "cartographer_simple_table_slot", radius = 8, }, + radio = { + width = 0.5, + height = 0.5, + margin_x = 0.25, + margin_y = 0.25, + }, tab = { + width = 1.5, + height = 0.55, font_color = "#694a3a", texture = "cartographer_simple_table_tab", selected_texture = "cartographer_simple_table_tab_selected", @@ -76,10 +99,14 @@ return { node_mesh = "cartographer_standard_table.obj", node_texture = "cartographer_standard_table.png", background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_standard_table_bg", radius = 16, }, inner_background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_standard_table_bg_2", radius = 4, }, @@ -91,21 +118,40 @@ return { hovered_texture = "cartographer_simple_table_button_hovered", pressed_texture = "cartographer_simple_table_button_pressed", radius = 8, + width = 2, + height = 0.5, }, slot = { texture = "cartographer_standard_table_slot", radius = 8, + width = 1, + height = 1, }, separator = { texture = "cartographer_standard_table_separator", radius = "9,1", }, + material_indicator = { + width = 1, + height = 0.25, + spacing = 0.25 + }, label = { + margin_x = 0, + margin_y = 0, font_color = "#694a3a", texture = "cartographer_standard_table_slot", radius = 8, }, + radio = { + width = 0.5, + height = 0.5, + margin_x = 0.25, + margin_y = 0.25, + }, tab = { + width = 1.5, + height = 0.55, font_color = "#694a3a", texture = "cartographer_standard_table_tab", selected_texture = "cartographer_standard_table_tab_selected", @@ -120,10 +166,14 @@ return { node_mesh = "cartographer_advanced_table.obj", node_texture = "cartographer_advanced_table.png", background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_advanced_table_bg", radius = 16, }, inner_background = { + margin_x = 0.125, + margin_y = 0.125, texture = "cartographer_advanced_table_bg_2", radius = 2, }, @@ -135,21 +185,40 @@ return { hovered_texture = "cartographer_advanced_table_button_hovered", pressed_texture = "cartographer_advanced_table_button_pressed", radius = 8, + width = 2, + height = 0.5, }, slot = { texture = "cartographer_advanced_table_slot", radius = 8, + width = 1, + height = 1, }, separator = { texture = "cartographer_advanced_table_separator", radius = "9,1", }, + material_indicator = { + width = 1, + height = 0.25, + spacing = 0.25 + }, label = { + margin_x = 0, + margin_y = 0, font_color = "#1f2533", texture = "cartographer_advanced_table_slot", radius = 8, }, + radio = { + width = 0.5, + height = 0.5, + margin_x = 0.25, + margin_y = 0.25, + }, tab = { + width = 1.75, + height = 0.75, font_color = "#1f2533", texture = "cartographer_advanced_table_tab", selected_texture = "cartographer_advanced_table_tab_selected", @@ -199,4 +268,7 @@ return { -- The texture of the height toggle button when inactive flat_button_texture = "cartographer_flat_button", -}; + + player_inv_columns = 8, + player_inv_rows = 4, +} diff --git a/table.lua b/table.lua index 692e9d8..558df85 100644 --- a/table.lua +++ b/table.lua @@ -6,12 +6,35 @@ -- materials: The material API -- map_item: The map item API -- settings: The mod settings -local gui, gui_skin, audio, maps, materials, map_item, settings = ...; +local gui, gui_skin, audio, maps, materials, map_item, settings = ... -local SCALE_SMALL = 1; -local SCALE_MEDIUM = 2; -local SCALE_LARGE = 4; -local SCALE_HUGE = 8; +local SCALE_SMALL = 1 +local SCALE_MEDIUM = 2 +local SCALE_LARGE = 4 +local SCALE_HUGE = 8 + +-- Constants providing previously-hardcoded values as defaults +local BUTTON_WIDTH = 1 +local BUTTON_HEIGHT = 0.25 +local OUTER_MARGIN_X = 0.125 +local OUTER_MARGIN_Y = 0.125 +local INDICATOR_WIDTH = 1 +local INDICATOR_HEIGHT = 0.25 +local INDICATOR_SPACING = 0.25 +local INNER_MARGIN_X = 0.125 +local INNER_MARGIN_Y = 0.125 +local SLOT_WIDTH = 1 +local SLOT_HEIGHT = 1 +local SLOT_COLUMN_MARGIN = 0.25 +local SLOT_ROW_MARGIN = 0.25 +local LABEL_MARGIN_X = 0.125 +local LABEL_MARGIN_Y = 0 +local RADIO_WIDTH = 0.5 +local RADIO_HEIGHT = 0.5 +local RADIO_MARGIN_X = 0.25 +local RADIO_MARGIN_Y = 0.25 +local TAB_WIDTH = 1.5 +local TAB_HEIGHT = 0.55 -- Get the material cost for the given map scale and detail level -- @@ -20,23 +43,23 @@ local SCALE_HUGE = 8; -- -- Returns a table with material costs local function get_material_cost(scale, detail) - local paper = scale * 4; - local pigment = detail * 5; + local paper = scale * 4 + local pigment = detail * 5 if scale == SCALE_SMALL then - pigment = pigment + 5; + pigment = pigment + 5 elseif scale == SCALE_MEDIUM then - pigment = pigment + 10; + pigment = pigment + 10 elseif scale == SCALE_LARGE then - pigment = pigment + 15; + pigment = pigment + 15 elseif scale == SCALE_HUGE then - pigment = pigment + 20; + pigment = pigment + 20 end return { paper = math.max(paper, 0), pigment = math.max(pigment, 0), - }; + } end -- Get the material cost of the craft settings from the given table metadata @@ -46,20 +69,20 @@ end -- Returns a table with the material costs, and a boolean indicating if the -- costs were positive or negative before clamping. local function get_craft_material_cost(meta) - local cost = get_material_cost(meta:get_int("scale") or SCALE_SMALL, meta:get_int("detail") or 0); - local stack = meta:get_inventory():get_stack("output", 1); - local is_positive = true; + local cost = get_material_cost(meta:get_int("scale") or SCALE_SMALL, meta:get_int("detail") or 0) + local stack = meta:get_inventory():get_stack("output", 1) + local is_positive = true if stack:get_name() == "cartographer:map" then - local smeta = stack:get_meta(); + local smeta = stack:get_meta() local sub_cost = get_material_cost(smeta:get_int("cartographer:scale") or SCALE_SMALL, - (smeta:get_int("cartographer:detail") or 1) - 1); - is_positive = cost.paper >= sub_cost.paper and cost.pigment >= sub_cost.pigment; - cost.paper = math.max(cost.paper - sub_cost.paper, 0); - cost.pigment = math.max(cost.pigment - sub_cost.pigment, 0); + (smeta:get_int("cartographer:detail") or 1) - 1) + is_positive = cost.paper >= sub_cost.paper and cost.pigment >= sub_cost.pigment + cost.paper = math.max(cost.paper - sub_cost.paper, 0) + cost.pigment = math.max(cost.pigment - sub_cost.pigment, 0) end - return cost, is_positive; + return cost, is_positive end -- Check if the given table metadata has enough materials to cover the given @@ -72,7 +95,7 @@ end local function can_afford(cost, meta) return cost.paper + cost.pigment > 0 and cost.paper <= meta:get_int("paper") - and cost.pigment <= meta:get_int("pigment"); + and cost.pigment <= meta:get_int("pigment") end -- Get the material cost of the copy settings from the given table metadata @@ -81,42 +104,43 @@ end -- -- Returns a table with the material costs local function get_copy_material_cost(meta) - local inv = meta:get_inventory(); - local in_stack = inv:get_stack("copy_input", 1); - local out_stack = inv:get_stack("copy_output", 1); + local inv = meta:get_inventory() + local in_stack = inv:get_stack("copy_input", 1) + local out_stack = inv:get_stack("copy_output", 1) if out_stack:is_empty() and in_stack:get_name() == "cartographer:map" then - local smeta = in_stack:get_meta(); - local scale = smeta:get_int("cartographer:scale") or SCALE_SMALL; - local detail = smeta:get_int("cartographer:detail") or 1; + local smeta = in_stack:get_meta() + local scale = smeta:get_int("cartographer:scale") or SCALE_SMALL + local detail = smeta:get_int("cartographer:detail") or 1 - return get_material_cost(scale, detail - 1); + return get_material_cost(scale, detail - 1) end return { paper = 0, pigment = 0, - }; + } end -local fs = {}; +local fs = {} -- Draw a 1px thick horizontal separator formspec element -- -- y: The y position of the separator +-- width: The wisth of the separator -- skin: A 9-slice background skin table -- -- Returns a formspec string -function fs.separator(y, skin) +function fs.separator(y, width, skin) return gui.bg9 { - x = 0.1, + x = 0, y = y, - w = 10.05, + w = width, h = 0.01, skin = skin, - }; + } end -- Draw all the essential formspec data (size, background, styles, tabs) @@ -129,6 +153,9 @@ end -- -- Returns a formspec string function fs.header(w, h, rank, tab, skin) + local tabs_x = (skin.background.margin_x or OUTER_MARGIN_X) + (skin.inner_background.margin_x or INNER_MARGIN_X) + local tabs_y = (skin.background.margin_y or OUTER_MARGIN_Y) - (skin.tab.height or TAB_HEIGHT) + local data = { gui.formspec { w = w, @@ -137,11 +164,11 @@ function fs.header(w, h, rank, tab, skin) bg = skin.background, }, gui.bg9 { - x = 0.125, - y = 0.125, + x = skin.background.margin_x or OUTER_MARGIN_X, + y = skin.background.margin_y or OUTER_MARGIN_Y, - w = w - 0.25, - h = h - 0.25, + w = w - (skin.background.margin_x or OUTER_MARGIN_X) * 2, + h = h - (skin.background.margin_y or OUTER_MARGIN_Y) * 2, skin = skin.inner_background, }, @@ -170,41 +197,41 @@ function fs.header(w, h, rank, tab, skin) }, gui.button { - x = 0.25, - y = -0.425, + x = tabs_x, + y = tabs_y, - w = 1.5, - h = 0.55, + w = skin.tab.width or TAB_WIDTH, + h = skin.tab.height or TAB_HEIGHT, id = "tab1", text = "Materials" }, gui.button { - x = 1.75, - y = -0.425, + x = tabs_x + (skin.tab.width or TAB_WIDTH), + y = tabs_y, - w = 1.5, - h = 0.55, + w = skin.tab.width or TAB_WIDTH, + h = skin.tab.height or TAB_HEIGHT, id = "tab2", text = "Create Map" }, - }; + } if rank >= 2 then table.insert(data, gui.button { - x = 3.25, - y = -0.425, + x = tabs_x + (skin.tab.width or TAB_WIDTH) * 2, + y = tabs_y, - w = 1.5, - h = 0.55, + w = skin.tab.width or TAB_WIDTH, + h = skin.tab.height or TAB_HEIGHT, id = "tab3", text = "Copy Map" - }); + }) end table.insert(data, gui.style_type { @@ -218,7 +245,7 @@ function fs.header(w, h, rank, tab, skin) textcolor = skin.button.font_color, }, - }); + }) table.insert(data, gui.style { selector = "disabled_button", properties = { @@ -228,9 +255,9 @@ function fs.header(w, h, rank, tab, skin) textcolor = skin.button.disabled_font_color, }, - }); + }) - return table.concat(data); + return table.concat(data) end -- Draw material counters from a table's metadata @@ -242,62 +269,65 @@ end -- -- Returns a formspec string function fs.materials(x, y, meta, skin) + local indicator_w = INDICATOR_WIDTH + local indicator_h = INDICATOR_HEIGHT + local indicator_spacing = INDICATOR_SPACING + if skin.material_indicator then + indicator_w = skin.material_indicator.width + indicator_h = skin.material_indicator.height + indicator_spacing = skin.material_indicator.spacing + end + local margin_x = skin.label.margin_x or LABEL_MARGIN_X + local margin_y = skin.label.margin_y or LABEL_MARGIN_Y + local inner_h = indicator_h - (margin_y * 2) + return gui.container { x = x, y = y, + w = indicator_w, + h = indicator_h, + bg = skin.label, - gui.bg9 { - x = 0, - y = 0.125, - - w = 1.0, - h = 0.25, - - skin = skin.label, - }, gui.image { - x = 0.125, - y = 0.125, + x = margin_x, + y = margin_y, - w = 0.25, - h = 0.25, + w = inner_h, + h = inner_h, image = skin.paper_texture .. ".png", }, gui.label { - x = 0.375, - y = 0.25, + x = margin_x + inner_h + margin_y, -- y because the previous element uses the inner height + y = margin_y + inner_h * 0.5, textcolor = skin.label.font_color, - text = string.format("x %d", meta:get_int("paper")), + text = string.format("× %d", meta:get_int("paper")), }, + } .. gui.container { + x = x + indicator_w + indicator_spacing, + y = y, + w = indicator_w, + h = indicator_h, + bg = skin.label, - gui.bg9 { - x = 1.25, - y = 0.125, - - w = 1.0, - h = 0.25, - - skin = skin.label, - }, gui.image { - x = 1.375, - y = 0.125, + x = margin_x, + y = margin_y, - w = 0.25, - h = 0.25, + w = inner_h, + h = inner_h, image = skin.pigment_texture .. ".png", }, gui.label { - x = 1.625, - y = 0.25, + x = margin_x + inner_h + margin_y, -- See previous label + y = margin_y + inner_h * 0.5, textcolor = skin.label.font_color, - text = string.format("x %d", meta:get_int("pigment")), + text = string.format("× %d", meta:get_int("pigment")), }, - }; + } end -- Draw a label with material costs from a table @@ -310,49 +340,56 @@ end -- -- Returns a formspec string function fs.cost(x, y, cost, skin) + local indicator_w = INDICATOR_WIDTH + local indicator_h = INDICATOR_HEIGHT + if skin.material_indicator then + indicator_w = skin.material_indicator.width + indicator_h = skin.material_indicator.height + end + local margin_x = skin.label.margin_x or LABEL_MARGIN_X + local margin_y = skin.label.margin_y or LABEL_MARGIN_Y + local inner_h = indicator_h - (margin_y * 2) local data = { gui.bg9 { x = x, - y = y - 0.125, - w = 1, - h = 0.5, + y = y, + w = indicator_w, + h = indicator_h * 2, skin = skin.label, }, } - local i = 0; + local i = 0 for name,value in pairs(cost) do - local texture = ""; + local texture = "" if name == "paper" then - texture = skin.paper_texture .. ".png"; + texture = skin.paper_texture .. ".png" elseif name == "pigment" then - texture = skin.pigment_texture .. ".png"; + texture = skin.pigment_texture .. ".png" end table.insert(data, gui.image { - x = x + 0.125, - y = y + (i * 0.25) - 0.125, - w = 0.25, - h = 0.25, + x = x + margin_x, + y = y + (i * inner_h), + w = inner_h, + h = inner_h, image = texture, - }); + }) table.insert(data, gui.label { - x = x + 0.375, - y = y + (i * 0.25); - w = 0.25, - h = 0.25, + x = x + margin_x + inner_h, + y = y + ((i + 0.5) * inner_h), textcolor = skin.label.font_color, - text = string.format("x %d", value); - }); + text = string.format("× %d", value), + }) - i = i + 1; + i = i + 1 end - return table.concat(data); + return table.concat(data) end -- Draw the material conversion tab UI @@ -364,8 +401,22 @@ end -- -- Returns a formspec string function fs.convert(x, y, pos, skin) - local meta = minetest.get_meta(pos); - local value = materials.get_stack_value(meta:get_inventory():get_stack("input", 1)); + local meta = minetest.get_meta(pos) + local value = materials.get_stack_value(meta:get_inventory():get_stack("input", 1)) + + local button_w = skin.button.width or BUTTON_WIDTH + local button_h = skin.button.height or BUTTON_HEIGHT + local indicator_w = INDICATOR_WIDTH + local indicator_h = INDICATOR_HEIGHT * 2 + local inv_w = skin.slot.width or SLOT_WIDTH + local inv_h = skin.slot.height or SLOT_HEIGHT + + local indicator_spacing = INDICATOR_SPACING + if skin.material_indicator then + indicator_w = skin.material_indicator.width + indicator_h = skin.material_indicator.height * 2 + indicator_spacing = skin.material_indicator.spacing + end return gui.container { x = x, @@ -374,8 +425,8 @@ function fs.convert(x, y, pos, skin) gui.inventory { x = 0, y = 0, - w = 1, - h = 1, + w = inv_w, + h = inv_h, location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z), id = "input", @@ -383,19 +434,19 @@ function fs.convert(x, y, pos, skin) tooltip = "Place items here to convert\nthem into mapmaking materials", }, + fs.cost(inv_w + indicator_spacing, (inv_h - indicator_h) * 0.5, value, skin), + gui.button { - x = 2.5, - y = 0.25, - w = 2, - h = 0.5, + x = inv_w + indicator_w + indicator_spacing * 2, + y = (inv_h - button_h) * 0.5, + w = button_w, + h = button_h, id = "convert", text = "Convert Materials", disabled = value.paper + value.pigment <= 0, }, - - fs.cost(1.25, 0.375, value, skin), - }; + } end -- Draw the map crafting tab UI @@ -410,35 +461,63 @@ end -- -- Returns a formspec string function fs.craft(x, y, pos, rank, meta, skin) - local cost, is_positive = get_craft_material_cost(meta); - local stack = meta:get_inventory():get_stack("output", 1); + local cost, is_positive = get_craft_material_cost(meta) + local stack = meta:get_inventory():get_stack("output", 1) + + local button_w = skin.button.width or BUTTON_WIDTH + local button_h = skin.button.height or BUTTON_HEIGHT + local indicator_w = INDICATOR_WIDTH + local indicator_h = INDICATOR_HEIGHT * 2 + local inv_w = skin.slot.width or SLOT_WIDTH + local inv_h = skin.slot.height or SLOT_HEIGHT + + local radio = skin.radio or { + width = RADIO_WIDTH, + height = RADIO_HEIGHT, + margin_x = RADIO_MARGIN_X, + margin_y = RADIO_MARGIN_Y, + } + + local indicator_spacing = INDICATOR_SPACING + if skin.material_indicator then + indicator_w = skin.material_indicator.width + indicator_h = skin.material_indicator.height * 2 + indicator_spacing = skin.material_indicator.spacing + end local data = { x = x, y = y, - gui.inventory { + gui.container { x = 0, - y = 1, - w = 1, - h = 1, + y = radio.height + radio.margin_y * 2, - location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z), - id = "output", - bg = skin.slot, - tooltip = "Place a map here to upgrade it,\nor leave empty to craft", - }, - gui.button { - x = 2.5, - y = 1.25, - w = 2, - h = 0.5, + gui.inventory { + x = 0, + y = 0, + w = inv_w, + h = inv_h, - id = "craft", - text = stack:get_name() == "cartographer:map" and "Upgrade Map" or "Craft Map", - disabled = not (is_positive and can_afford(cost, meta)), + location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z), + id = "output", + bg = skin.slot, + tooltip = "Place a map here to upgrade it,\nor leave empty to craft", + }, + + fs.cost(inv_w + indicator_spacing, (inv_h - indicator_h) * 0.5, cost, skin), + + gui.button { + x = inv_w + indicator_w + indicator_spacing * 2, + y = (inv_h - button_h) * 0.5, + w = button_w, + h = button_h, + + id = "craft", + text = stack:get_name() == "cartographer:map" and "Upgrade Map" or "Craft Map", + disabled = not (is_positive and can_afford(cost, meta)), + }, }, - fs.cost(1.25, 1.375, cost, skin), gui.style { selector = string.format("%dx,%d", meta:get_int("scale"), meta:get_int("detail") + 1), @@ -455,105 +534,120 @@ function fs.craft(x, y, pos, rank, meta, skin) text = "Detail Level", textcolor = skin.label.font_color, }, - }; - - if rank > 1 then - table.insert(data, gui.button { - x = 2.5, - y = 0.25, - w = 0.5, - h = 0.5, - - id = "1x", - text = "1x", - }); - table.insert(data, gui.button { - x = 3.0, - y = 0.25, - w = 0.5, - h = 0.5, - - id = "2x", - text = "2x", - }); - - if rank > 2 then - table.insert(data, gui.button { - x = 3.5, - y = 0.25, - w = 0.5, - h = 0.5, - - id = "4x", - text = "4x", - }); - table.insert(data, gui.button { - x = 4.0, - y = 0.25, - w = 0.5, - h = 0.5, - - id = "8x", - text = "8x", - }); - end - end + } table.insert(data, gui.button { x = 0, - y = 0.25, - w = 0.5, - h = 0.5, + y = radio.margin_y, + w = radio.width, + h = radio.height, id = "1", text = "1", - }); + }) table.insert(data, gui.button { - x = 0.5, - y = 0.25, - w = 0.5, - h = 0.5, + x = radio.width, + y = radio.margin_y, + w = radio.width, + h = radio.height, id = "2", text = "2", - }); + }) if rank > 1 then table.insert(data, gui.button { - x = 1.0, - y = 0.25, - w = 0.5, - h = 0.5, + x = radio.width * 2, + y = radio.margin_y, + w = radio.width, + h = radio.height, id = "3", text = "3", - }); + }) if rank > 2 then table.insert(data, gui.button { - x = 1.5, - y = 0.25, - w = 0.5, - h = 0.5, + x = radio.width * 3, + y = radio.margin_y, + w = radio.width, + h = radio.height, id = "4", text = "4", - }); + }) end end - return gui.container(data); + if rank > 1 then + table.insert(data, gui.button { + x = radio.margin_x + radio.width * 4, + y = radio.margin_y, + w = radio.width, + h = radio.height, + + id = "1x", + text = "1×", + }) + table.insert(data, gui.button { + x = radio.margin_x + radio.width * 5, + y = radio.margin_y, + w = radio.width, + h = radio.height, + + id = "2x", + text = "2×", + }) + + if rank > 2 then + table.insert(data, gui.button { + x = radio.margin_x + radio.width * 6, + y = radio.margin_y, + w = radio.width, + h = radio.height, + + id = "4x", + text = "4×", + }) + table.insert(data, gui.button { + x = radio.margin_x + radio.width * 7, + y = radio.margin_y, + w = radio.width, + h = radio.height, + + id = "8x", + text = "8×", + }) + end + end + + return gui.container(data) end -- Draw the map copying tab UI -- -- x: The x position of the interface -- y: The y position of the interface +-- width: The width to fill -- pos: The table position (for displaying the inventory) -- skin: A formspec skin table -- -- Returns a formspec string -function fs.copy(x, y, pos, skin) - local meta = minetest.get_meta(pos); - local costs = get_copy_material_cost(meta); +function fs.copy(x, y, width, pos, skin) + local meta = minetest.get_meta(pos) + local costs = get_copy_material_cost(meta) + + local button_w = skin.button.width or BUTTON_WIDTH + local button_h = skin.button.height or BUTTON_HEIGHT + local indicator_w = INDICATOR_WIDTH + local indicator_h = INDICATOR_HEIGHT * 2 + local inv_w = skin.slot.width or SLOT_WIDTH + local inv_h = skin.slot.height or SLOT_HEIGHT + + local indicator_spacing = INDICATOR_SPACING + if skin.material_indicator then + indicator_w = skin.material_indicator.width + indicator_h = skin.material_indicator.height * 2 + indicator_spacing = skin.material_indicator.spacing + end return gui.container { x = x, @@ -562,35 +656,35 @@ function fs.copy(x, y, pos, skin) gui.inventory { x = 0, y = 0, - w = 1, - h = 1, + w = inv_h, + h = inv_w, location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z), id = "copy_input", bg = skin.slot, }, gui.inventory { - x = 8.75, + x = width - inv_w, y = 0, - w = 1, - h = 1, + w = inv_w, + h = inv_h, location = string.format("nodemeta:%d,%d,%d", pos.x, pos.y, pos.z), id = "copy_output", bg = skin.slot, }, + fs.cost(inv_w + indicator_spacing, (inv_h - indicator_h) * 0.5, costs, skin), gui.button { - x = 2.5, - y = 0.25, - w = 2, - h = 0.5, + x = inv_w + indicator_w + indicator_spacing * 2, + y = (inv_h - button_h) * 0.5, + w = button_w, + h = button_h, id = "copy", text = "Copy Map", disabled = not can_afford(costs, meta), }, - fs.cost(1.25, 0.375, costs, skin), - }; + } end -- Draw the player's inventory @@ -604,16 +698,16 @@ function fs.inv(x, y, skin) return gui.inventory { x = x, y = y, - w = 8, - h = 4, + w = gui_skin.player_inv_columns, + h = gui_skin.player_inv_rows, location = "current_player", id = "main", bg = skin.slot, - }; + } end -local player_tables = {}; +local player_tables = {} -- Show the table formspec to the specified player -- The player must be recorded in player_tables in order to receive @@ -621,53 +715,93 @@ local player_tables = {}; -- -- player: The player's name local function table_formspec(player) - local data = player_tables[player]; - local pos = data.pos; + local data = player_tables[player] + local pos = data.pos if not pos then - return; + return end - local meta = minetest.get_meta(pos); + local meta = minetest.get_meta(pos) - local rank = 1; - local skin = gui_skin.table_skins.simple_table; - local name = minetest.get_node(pos).name; + local rank = 1 + local skin = gui_skin.table_skins.simple_table + local name = minetest.get_node(pos).name if name == "cartographer:standard_table" then - rank = 2; - skin = gui_skin.table_skins.standard_table; + rank = 2 + skin = gui_skin.table_skins.standard_table elseif name == "cartographer:advanced_table" then - rank = 3; - skin = gui_skin.table_skins.advanced_table; + rank = 3 + skin = gui_skin.table_skins.advanced_table + end + + local outer_x = (skin.background.margin_x or OUTER_MARGIN_X) + local outer_y = (skin.background.margin_y or OUTER_MARGIN_Y) + local inner_x = (skin.inner_background.margin_x or INNER_MARGIN_X) + local inner_y = (skin.inner_background.margin_y or INNER_MARGIN_Y) + + local inv_width = (skin.slot_w or SLOT_WIDTH) * gui_skin.player_inv_columns + + (SLOT_COLUMN_MARGIN * (gui_skin.player_inv_columns - 1)) + local inv_height = (skin.slot_h or SLOT_HEIGHT) * gui_skin.player_inv_rows + + (SLOT_ROW_MARGIN * (gui_skin.player_inv_rows - 1)) + local inner_width = inv_width + inner_x * 2 + local width = inner_width + outer_x * 2 + + local sep_height = INDICATOR_SPACING + local ind_h = INDICATOR_HEIGHT + INDICATOR_SPACING * 0.5 + if skin.material_indicator then + sep_height = skin.material_indicator.spacing + ind_h = skin.material_indicator.height + skin.material_indicator.spacing * 0.5 end if data.tab == 1 then + local convert_height = (skin.slot.height or SLOT_HEIGHT) + sep_height + local form_height = (outer_y * 2) + (inner_y * 2) + convert_height + ind_h + sep_height * 2 + inv_height minetest.show_formspec(player, "cartographer:table", - fs.header(10.25, 7.375, rank, data.tab, skin) .. - fs.materials(0.25, 0.1875, meta, skin) .. - fs.separator(0.6875, skin.separator) .. - fs.convert(0.25, 0.875, pos, skin) .. - fs.separator(2.125, skin.separator) .. - fs.inv(0.25, 2.375, skin) - ); + fs.header(width, form_height, rank, data.tab, skin) .. + gui.container { + x = outer_x, + y = outer_y + inner_y, + fs.materials(inner_x, 0, meta, skin), + fs.separator(ind_h, inner_width, skin.separator), + fs.convert(inner_x, ind_h + sep_height, pos, skin), + fs.separator(ind_h + sep_height + convert_height, inner_width, skin.separator), + fs.inv(inner_x, ind_h + sep_height * 2 + convert_height, skin), + }) elseif data.tab == 2 then + local radio_height = RADIO_HEIGHT + local radio_margin_y = RADIO_MARGIN_Y + if skin.radio then + radio_height = skin.radio.height + radio_margin_y = skin.radio.margin_y + end + local craft_height = radio_height + radio_margin_y * 2 + (skin.slot_height or SLOT_HEIGHT) + sep_height + local form_height = (outer_y * 2) + (inner_y * 2) + craft_height + ind_h + sep_height * 2 + inv_height minetest.show_formspec(player, "cartographer:table", - fs.header(10.25, 8.25, rank, data.tab, skin) .. - fs.materials(0.25, 0.1875, meta, skin) .. - fs.separator(0.6875, skin.separator) .. - fs.craft(0.25, 0.875, pos, rank, meta, skin) .. - fs.separator(3, skin.separator) .. - fs.inv(0.25, 3.25, skin) - ); + fs.header(width, form_height, rank, data.tab, skin) .. + gui.container { + x = outer_x, + y = outer_y + inner_y, + fs.materials(inner_x, 0, meta, skin), + fs.separator(ind_h, inner_width, skin.separator), + fs.craft(inner_x, ind_h + sep_height, pos, rank, meta, skin), + fs.separator(ind_h + craft_height + sep_height, inner_width, skin.separator), + fs.inv(inner_x, ind_h + craft_height + sep_height * 2, skin), + }) elseif data.tab == 3 then + local copy_height = (skin.slot.height or SLOT_HEIGHT) + sep_height + local form_height = (outer_y * 2) + (inner_y * 2) + copy_height + ind_h + sep_height * 2 + inv_height minetest.show_formspec(player, "cartographer:table", - fs.header(10.25, 7.375, rank, data.tab, skin) .. - fs.materials(0.25, 0.1875, meta, skin) .. - fs.separator(0.6875, skin.separator) .. - fs.copy(0.25, 0.875, pos, skin) .. - fs.separator(2.125, skin.separator) .. - fs.inv(0.25, 2.375, skin) - ); + fs.header(width, form_height, rank, data.tab, skin) .. + gui.container { + x = outer_x, + y = outer_y + inner_y, + fs.materials(inner_x, 0, meta, skin), + fs.separator(ind_h, inner_width, skin.separator), + fs.copy(inner_x, ind_h + sep_height, inv_width, pos, skin), + fs.separator(ind_h + copy_height + sep_height, inner_width, skin.separator), + fs.inv(inner_x, ind_h + copy_height + sep_height * 2, skin), + }) end end @@ -679,114 +813,114 @@ end -- fields: A table containing the input minetest.register_on_player_receive_fields(function(player, name, fields) if name == "cartographer:table" then - local meta = minetest.get_meta(player_tables[player:get_player_name()].pos); + local meta = minetest.get_meta(player_tables[player:get_player_name()].pos) - local rank = 1; - local node_name = minetest.get_node(player_tables[player:get_player_name()].pos).name; + local rank = 1 + local node_name = minetest.get_node(player_tables[player:get_player_name()].pos).name if node_name == "cartographer:standard_table" then - rank = 2; + rank = 2 elseif node_name == "cartographer:advanced_table" then - rank = 3; + rank = 3 end if fields["convert"] then - local inv = meta:get_inventory(); - local stack = inv:get_stack("input", 1); + local inv = meta:get_inventory() + local stack = inv:get_stack("input", 1) - local value = materials.get_stack_value(stack); + local value = materials.get_stack_value(stack) if value.paper + value.pigment > 0 then - meta:set_int("paper", meta:get_int("paper") + value.paper); - meta:set_int("pigment", meta:get_int("pigment") + value.pigment); - inv:set_stack("input", 1, ItemStack(nil)); + meta:set_int("paper", meta:get_int("paper") + value.paper) + meta:set_int("pigment", meta:get_int("pigment") + value.pigment) + inv:set_stack("input", 1, ItemStack(nil)) end elseif fields["craft"] then - local size = meta:get_int("size"); - local detail = meta:get_int("detail"); - local scale = meta:get_int("scale"); - local cost, is_positive = get_craft_material_cost(meta); + local size = meta:get_int("size") + local detail = meta:get_int("detail") + local scale = meta:get_int("scale") + local cost, is_positive = get_craft_material_cost(meta) if is_positive and can_afford(cost, meta) then - meta:set_int("paper", meta:get_int("paper") - cost.paper); - meta:set_int("pigment", meta:get_int("pigment") - cost.pigment); + meta:set_int("paper", meta:get_int("paper") - cost.paper) + meta:set_int("pigment", meta:get_int("pigment") - cost.pigment) - local inv = meta:get_inventory(); - local stack = inv:get_stack("output", 1); + local inv = meta:get_inventory() + local stack = inv:get_stack("output", 1) if stack:is_empty() then - inv:set_stack("output", 1, map_item.create(size, 1 + detail, scale)); + inv:set_stack("output", 1, map_item.create(size, 1 + detail, scale)) else - local smeta = stack:get_meta(); - smeta:set_int("cartographer:detail", 1 + detail); - map_item.resize(smeta, size); - map_item.rescale(smeta, scale); + local smeta = stack:get_meta() + smeta:set_int("cartographer:detail", 1 + detail) + map_item.resize(smeta, size) + map_item.rescale(smeta, scale) - local map = maps.get(smeta:get_int("cartographer:map_id")); + local map = maps.get(smeta:get_int("cartographer:map_id")) if map then - map.detail = 1 + detail; + map.detail = 1 + detail end - inv:set_stack("output", 1, stack); + inv:set_stack("output", 1, stack) end - audio.play_feedback("cartographer_write", player); + audio.play_feedback("cartographer_write", player) end elseif fields["copy"] and rank >= 2 then - local cost = get_copy_material_cost(meta); + local cost = get_copy_material_cost(meta) if can_afford(cost, meta) then - meta:set_int("paper", meta:get_int("paper") - cost.paper); - meta:set_int("pigment", meta:get_int("pigment") - cost.pigment); + meta:set_int("paper", meta:get_int("paper") - cost.paper) + meta:set_int("pigment", meta:get_int("pigment") - cost.pigment) - audio.play_feedback("cartographer_write", player); + audio.play_feedback("cartographer_write", player) - local inv = meta:get_inventory(); - inv:set_stack("copy_output", 1, map_item.copy(inv:get_stack("copy_input", 1))); + local inv = meta:get_inventory() + inv:set_stack("copy_output", 1, map_item.copy(inv:get_stack("copy_input", 1))) end elseif fields["1"] then - meta:set_int("detail", 0); + meta:set_int("detail", 0) elseif fields["2"] then - meta:set_int("detail", 1); + meta:set_int("detail", 1) elseif fields["3"] and rank > 1 then - meta:set_int("detail", 2); + meta:set_int("detail", 2) elseif fields["4"] and rank > 2 then - meta:set_int("detail", 3); + meta:set_int("detail", 3) elseif fields["1x"] and rank > 1 then - meta:set_int("scale", SCALE_SMALL); + meta:set_int("scale", SCALE_SMALL) elseif fields["2x"] and rank > 1 then - meta:set_int("scale", SCALE_MEDIUM); + meta:set_int("scale", SCALE_MEDIUM) elseif fields["4x"] and rank > 2 then - meta:set_int("scale", SCALE_LARGE); + meta:set_int("scale", SCALE_LARGE) elseif fields["8x"] and rank > 2 then - meta:set_int("scale", SCALE_HUGE); + meta:set_int("scale", SCALE_HUGE) elseif fields["tab1"] then - player_tables[player:get_player_name()].tab = 1; - audio.play_feedback("cartographer_turn_page", player); + player_tables[player:get_player_name()].tab = 1 + audio.play_feedback("cartographer_turn_page", player) elseif fields["tab2"] then - player_tables[player:get_player_name()].tab = 2; - audio.play_feedback("cartographer_turn_page", player); + player_tables[player:get_player_name()].tab = 2 + audio.play_feedback("cartographer_turn_page", player) elseif fields["tab3"] and rank >= 2 then - player_tables[player:get_player_name()].tab = 3; - audio.play_feedback("cartographer_turn_page", player); + player_tables[player:get_player_name()].tab = 3 + audio.play_feedback("cartographer_turn_page", player) end if not fields["quit"] then - table_formspec(player:get_player_name()); + table_formspec(player:get_player_name()) end end -end); +end) -- Called after a table is placed. Sets up the table's inventory and metadata. -- -- pos: The node's position local function setup_table_node(pos) - local meta = minetest.get_meta(pos); - meta:get_inventory():set_size("input", 1); - meta:get_inventory():set_size("output", 1); - meta:get_inventory():set_size("copy_input", 1); - meta:get_inventory():set_size("copy_output", 1); + local meta = minetest.get_meta(pos) + meta:get_inventory():set_size("input", 1) + meta:get_inventory():set_size("output", 1) + meta:get_inventory():set_size("copy_input", 1) + meta:get_inventory():set_size("copy_output", 1) - meta:set_int("size", settings.default_size); - meta:set_int("scale", SCALE_SMALL); - meta:set_int("detail", 0); + meta:set_int("size", settings.default_size) + meta:set_int("scale", SCALE_SMALL) + meta:set_int("detail", 0) end -- Called when the player tries to put an item into one of the table's @@ -795,18 +929,18 @@ end -- listname: The name of the inventory the item is being placed in. -- stack: The itemstack -- --- Returns 0 if the place is invalid; otherwise, returns the number of items +-- Returns 0 if the place is invalid otherwise, returns the number of items -- that can be placed. local function table_can_put(_, listname, _, stack, _) if listname == "copy_output" then - return 0; + return 0 end if stack:get_name() ~= "cartographer:map" and (listname == "output" or listname == "copy_input") then - return 0; + return 0 end - return stack:get_count(); + return stack:get_count() end -- Called when the player tries to move an item between two of the table's @@ -815,14 +949,14 @@ end -- to_list: The name of the inventory the item is being placed in. -- count: The number of items being moved -- --- Returns 0 if the move is invalid; otherwise, returns the number of items +-- Returns 0 if the move is invalid otherwise, returns the number of items -- that can be moved. local function table_can_move(_, _, _, to_list, _, count, _) if to_list == "copy_output" then - return 0; + return 0 end - return count; + return count end -- Called when a change occurs in a table's inventory @@ -835,7 +969,7 @@ local function table_on_items_changed(pos, listname, _, _, _) (data.tab == 1 and listname == "input") or (data.tab == 2 and listname == "output") or (data.tab == 3 and listname == "copy_input")) then - table_formspec(player); + table_formspec(player) end end end @@ -867,9 +1001,9 @@ minetest.register_node("cartographer:simple_table", { player_tables[player:get_player_name()] = { pos = minetest.get_pointed_thing_position(pointed_thing), tab = 1, - }; + } - audio.play_feedback("cartographer_open_map", player); + audio.play_feedback("cartographer_open_map", player) table_formspec(player:get_player_name()) end, @@ -879,7 +1013,7 @@ minetest.register_node("cartographer:simple_table", { allow_metadata_inventory_put = table_can_put, on_metadata_inventory_put = table_on_items_changed, on_metadata_inventory_take = table_on_items_changed, -}); +}) minetest.register_node("cartographer:standard_table", { description = "Simple Cartographer's Table", @@ -907,9 +1041,9 @@ minetest.register_node("cartographer:standard_table", { player_tables[player:get_player_name()] = { pos = minetest.get_pointed_thing_position(pointed_thing), tab = 1, - }; + } - audio.play_feedback("cartographer_open_map", player); + audio.play_feedback("cartographer_open_map", player) table_formspec(player:get_player_name()) end, @@ -919,7 +1053,7 @@ minetest.register_node("cartographer:standard_table", { allow_metadata_inventory_put = table_can_put, on_metadata_inventory_put = table_on_items_changed, on_metadata_inventory_take = table_on_items_changed, -}); +}) minetest.register_node("cartographer:advanced_table", { description = "Advanced Cartographer's Table", @@ -947,9 +1081,9 @@ minetest.register_node("cartographer:advanced_table", { player_tables[player:get_player_name()] = { pos = minetest.get_pointed_thing_position(pointed_thing), tab = 1, - }; + } - audio.play_feedback("cartographer_open_map", player); + audio.play_feedback("cartographer_open_map", player) table_formspec(player:get_player_name()) end, @@ -959,4 +1093,4 @@ minetest.register_node("cartographer:advanced_table", { allow_metadata_inventory_put = table_can_put, on_metadata_inventory_put = table_on_items_changed, on_metadata_inventory_take = table_on_items_changed, -}); +})