diff --git a/skin_api.lua b/skin_api.lua index 9672f72..1d47851 100644 --- a/skin_api.lua +++ b/skin_api.lua @@ -10,6 +10,128 @@ cartographer.skin = { texture = "cartographer_player_icon", }, + -- The skinning data for the cartographer's tables + table_skins = { + simple_table = { + node_mesh = "cartographer_simple_table.obj", + node_texture = "cartographer_simple_table.png", + + background = { + texture = "cartographer_simple_table_bg", + radius = 16, + }, + button = { + font_color = "#694a3a", + texture = "cartographer_simple_table_button", + selected_texture = "cartographer_simple_table_button_pressed", + hovered_texture = "cartographer_simple_table_button_hovered", + pressed_texture = "cartographer_simple_table_button_pressed", + radius = 8, + }, + slot = { + texture = "cartographer_simple_table_slot", + radius = 8, + }, + separator = { + texture = "cartographer_simple_table_separator", + radius = "9,1", + }, + label = { + font_color = "#694a3a", + texture = "cartographer_simple_table_slot", + radius = 8, + }, + tab = { + font_color = "#694a3a", + texture = "cartographer_simple_table_tab", + selected_texture = "cartographer_simple_table_tab_selected", + hovered_texture = "cartographer_simple_table_tab_hovered", + pressed_texture = "cartographer_simple_table_tab_hovered", + radius = 10, + }, + paper_texture = "cartographer_paper"; + pigment_texture = "cartographer_pigment"; + }, + standard_table = { + node_mesh = "cartographer_standard_table.obj", + node_texture = "cartographer_standard_table.png", + background = { + texture = "cartographer_simple_table_bg", + radius = 16, + }, + button = { + font_color = "#694a3a", + texture = "cartographer_simple_table_button", + selected_texture = "cartographer_simple_table_button_pressed", + hovered_texture = "cartographer_simple_table_button_hovered", + pressed_texture = "cartographer_simple_table_button_pressed", + radius = 8, + }, + slot = { + texture = "cartographer_simple_table_slot", + radius = 8, + }, + separator = { + texture = "cartographer_simple_table_separator", + radius = "9,1", + }, + label = { + font_color = "#694a3a", + texture = "cartographer_simple_table_slot", + radius = 8, + }, + tab = { + font_color = "#694a3a", + texture = "cartographer_simple_table_tab", + selected_texture = "cartographer_simple_table_tab_selected", + hovered_texture = "cartographer_simple_table_tab_hovered", + pressed_texture = "cartographer_simple_table_tab_hovered", + radius = 10, + }, + paper_texture = "default_paper"; + pigment_texture = "dye_black"; + }, + advanced_table = { + node_mesh = "cartographer_advanced_table.obj", + node_texture = "cartographer_advanced_table.png", + background = { + texture = "cartographer_simple_table_bg", + radius = 16, + }, + button = { + font_color = "#694a3a", + texture = "cartographer_simple_table_button", + selected_texture = "cartographer_simple_table_button_pressed", + hovered_texture = "cartographer_simple_table_button_hovered", + pressed_texture = "cartographer_simple_table_button_pressed", + radius = 8, + }, + slot = { + texture = "cartographer_simple_table_slot", + radius = 8, + }, + separator = { + texture = "cartographer_simple_table_separator", + radius = "9,1", + }, + label = { + font_color = "#694a3a", + texture = "cartographer_simple_table_slot", + radius = 8, + }, + tab = { + font_color = "#694a3a", + texture = "cartographer_simple_table_tab", + selected_texture = "cartographer_simple_table_tab_selected", + hovered_texture = "cartographer_simple_table_tab_hovered", + pressed_texture = "cartographer_simple_table_tab_hovered", + radius = 10, + }, + paper_texture = "default_paper"; + pigment_texture = "dye_black"; + }, + }, + -- The texture to use in maps when biome data is missing or empty unknown_biome_texture = "cartographer_unknown_biome", }; diff --git a/table.lua b/table.lua index 2e93c60..ca58986 100644 --- a/table.lua +++ b/table.lua @@ -3,10 +3,27 @@ local SIZE_LARGE = 40; local SCALE_SMALL = 1; local SCALE_LARGE = 4; -local separator = [[ - formspec_version[3] - box[0.1,%f;10.1,0.01;black] -]]; +-- Draw background elements in the same arrangement as inventory slots +-- x: The x position of the inventory +-- y: The y position of the inventory +-- cols: The width of the inventory, in columns +-- rows: The height of the inventory, in rows +-- skin: A 9-slice background skin table +-- +-- Returns a formspec string +local function inventory_bg(x, y, cols, rows, skin) + local data = ""; + for i = 0,cols - 1 do + for j = 0,rows - 1 do + data = data .. string.format("background9[%f,%f;1,1;%s.png;false;%s]", + x + (i * 1.25), y + (j * 1.25), + skin.texture, + tostring(skin.radius)); + end + end + + return data; +end local function get_material_cost(size, detail) local paper = 0; @@ -46,74 +63,102 @@ end local fs = {}; -function fs.header(w, h, rank, tab) - local data = [[ - formspec_version[3] - size[%f,%f] - ]]; - data = data:format(w, h); - - if rank < 2 then - data = data .. "tabheader[0,0;tabs;Materials,Create Map;%d;false;false]"; - data = data:format(tab); - else - data = data .. "tabheader[0,0;tabs;Materials,Create Map,Copy Map;%d;false;false]"; - data = data:format(tab); - end - - return data; +-- Draw a 1px thick horizontal separator formspec element +-- y: The y position of the separator +-- skin: A 9-slice background skin table +-- +-- Returns a formspec string +function fs.separator(y, skin) + return string.format("background9[0.1,%f;10.05,0.01;%s.png;false;%s]", y, skin.texture, tostring(skin.radius)) end -function fs.materials(x, y, rank, meta) - local paper = meta:get_int("paper"); - local pigment = meta:get_int("pigment"); +-- Draw all the essential formspec data (size, background, styles, tabs) +-- w: The width of the formspec +-- h: The height of the formspec +-- rank: An into defining the 'rank' of the table being displayed +-- tab: An int defining the index of the selected tab +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.header(w, h, rank, tab, skin) + local data = "formspec_version[3]" + .. string.format("size[%f,%f]", w, h) + .. string.format("background9[-0.1,0;1,1;%s.png;true;%s]", skin.background.texture, tostring(skin.background.radius)) + .. string.format("style_type[button;noclip=true;border=false;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png;bgimg_middle=%s;textcolor=%s]", skin.tab.texture, skin.tab.hovered_texture, skin.tab.pressed_texture, tostring(skin.tab.radius), skin.tab.font_color) + .. string.format("style[tab%d;noclip=true;border=false;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png;bgimg_middle=%s;textcolor=%s]", tab, skin.tab.selected_texture, skin.tab.selected_texture, skin.tab.selected_texture, tostring(skin.tab.radius), skin.tab.font_color) + .. string.format("button[0.25,-0.375;1.5,0.55;tab1;Materials]", tab) + .. string.format("button[1.75,-0.375;1.5,0.55;tab2;Create Map]", tab); - local data = [[ - container[%f,%f] - formspec_version[3] - label[0,0.25;paper x %d] - label[3,0.25;Pigment x %d] - ]]; - data = data:format(x, y, paper, pigment); + if rank >= 2 then + data = data .. string.format("button[3.25,-0.375;1.5,0.55;tab3;Copy Map]", tab); + end - return data .. "container_end[]"; + return data .. string.format("style_type[button;border=false;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png;bgimg_middle=%s;textcolor=%s]", skin.button.texture, skin.button.hovered_texture, skin.button.pressed_texture, tostring(skin.button.radius), skin.button.font_color); +end + +-- Draw material counters from a table's metadata +-- x: The x position of the labels +-- y: The y position of the labels +-- meta: A metadata object containing the material quantities +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.materials(x, y, meta, skin) + return string.format("container[%f,%f]", x, y) + .. "formspec_version[3]" + .. string.format("background9[0,0.125;1,0.25;%s.png;false;%s]", skin.label.texture, tostring(skin.label.radius)) + .. string.format("image[0.125,0.125;0.25,0.25;%s.png]", skin.paper_texture) + .. string.format("label[0.375,0.25;%sx %d]", minetest.get_color_escape_sequence(skin.label.font_color), meta:get_int("paper")) + .. string.format("background9[1.25,0.125;1,0.25;%s.png;false;%s]", skin.label.texture, tostring(skin.label.radius)) + .. string.format("image[1.375,0.125;0.25,0.25;%s.png]", skin.pigment_texture) + .. string.format("label[1.625,0.25;%sx %d]", minetest.get_color_escape_sequence(skin.label.font_color), meta:get_int("pigment")) + .. "container_end[]"; end function fs.cost(x, y, materials) local data = ""; local i = 0; for name,value in pairs(materials) do - data = data .. "label[" .. tostring(x) .. "," .. tostring(y + (i * 0.25)) .. ";" .. name .. " x " .. tostring(value) .. "]"; + data = data .. "label[" .. tostring(x) .. "," .. tostring(y + (i * 0.25)) .. ";" .. minetest.get_color_escape_sequence("#694a3a") .. name .. " x " .. tostring(value) .. "]"; i = i + 1; end return data; end -function fs.convert(x, y, pos) - local data = [[ - container[%f,%f] - formspec_version[3] - list[nodemeta:%d,%d,%d;input;0,0;1,1;] - button[3.5,0.25;2,0.5;convert;Convert Materials] - ]]; - data = data:format(x, y, pos.x, pos.y, pos.z); - data = data .. fs.cost(1.25, 0.25, { - paper = 0, - Pigment = 0, - }) .. "container_end[]"; - - return data; +-- Draw the material conversion tab UI +-- x: The x position of the interface +-- y: The y position of the interface +-- pos: The table position (for displaying the inventory) +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.convert(x, y, pos, skin) + return string.format("container[%f,%f]", x, y) + .. "formspec_version[3]" + .. inventory_bg(0, 0, 1, 1, skin.slot) + .. string.format("list[nodemeta:%d,%d,%d;input;0,0;1,1;]", pos.x, pos.y, pos.z) + .. "button[1.25,0.5;2,0.5;convert;Convert Materials]" + .. fs.cost(1.25, 0.125, { Paper = 0, Pigment = 0, }) + .. "container_end[]"; end -function fs.craft(x, y, pos, rank, meta) - local data = [[ - container[%f, %f] - formspec_version[3] - list[nodemeta:%d,%d,%d;output;0,1;1,1;] - button[3.5,1.5;2,0.5;craft;Craft Map] - ]] .. separator:format(0.75); - data = data:format(x, y, pos.x, pos.y, pos.z); +-- Draw the map crafting tab UI +-- x: The x position of the interface +-- y: The y position of the interface +-- pos: The table position (for displaying the inventory) +-- meta: A metadata object containing the table settings and material +-- quantities +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.craft(x, y, pos, rank, meta, skin) + local data = string.format("container[%f,%f]", x, y) + .. "formspec_version[3]" + .. inventory_bg(0, 0.75, 1, 1, skin.slot) + .. string.format("list[nodemeta:%d,%d,%d;output;0,0.75;1,1;]", pos.x, pos.y, pos.z) + .. "button[1.25,1.25;2,0.5;craft;Craft Map]" + .. fs.cost(1.25, 0.875, get_full_material_cost(meta)); if rank > 1 then local size = "s"; @@ -121,12 +166,9 @@ function fs.craft(x, y, pos, rank, meta) size = "l"; end - data = data .. [[ - style[%s;bgcolor=blue] - button[0,0;0.5,0.5;s;S] - button[0.5,0;0.5,0.5;l;L] - ]]; - data = data:format(size); + data = data .. string.format("style[%s;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png]", size, skin.button.selected_texture, skin.button.selected_texture, skin.button.selected_texture) + .. "button[0,0;0.5,0.5;s;S]" + .. "button[0.5,0;0.5,0.5;l;L]"; end if rank > 2 then @@ -135,100 +177,120 @@ function fs.craft(x, y, pos, rank, meta) scale = "4x"; end - data = data .. [[ - style[%s;bgcolor=blue] - button[3.5,0;0.5,0.5;1x;1x] - button[4.0,0;0.5,0.5;4x;4x] - ]]; - data = data:format(scale); + data = data .. string.format("style[%s;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png]", scale, skin.button.selected_texture, skin.button.selected_texture, skin.button.selected_texture) + .. "button[3.5,0;0.5,0.5;1x;1x]" + .. "button[4.0,0;0.5,0.5;4x;4x]"; end - local detail = tostring(meta:get_int("detail") + 1); - data = data .. [[ - style[%s;bgcolor=blue] - button[1.25,0;0.5,0.5;1;1] - button[1.75,0;0.5,0.5;2;2] - ]]; + data = data .. string.format("style[%d;bgimg=%s.png;bgimg_hovered=%s.png;bgimg_pressed=%s.png]", meta:get_int("detail") + 1, skin.button.selected_texture, skin.button.selected_texture, skin.button.selected_texture) + .. "button[1.25,0;0.5,0.5;1;1]" + .. "button[1.75,0;0.5,0.5;2;2]"; if rank > 1 then data = data .. "button[2.25,0;0.5,0.5;3;3]"; if rank > 2 then data = data .. "button[2.75,0;0.5,0.5;4;4]"; end end - data = data:format(detail) .. fs.cost(3.5, 1, get_full_material_cost(meta)) .. "container_end[]"; - return data; + return data .. "container_end[]"; end -function fs.copy(x, y, pos) - local data = [[ - container[%f,%f] - formspec_version[3] - list[nodemeta:%d,%d,%d;copy_input;0,0;1,1;] - list[nodemeta:%d,%d,%d;copy_output;0,1.25;1,1;] - button[3.5,0.25;2,0.5;copy;Copy Map] - ]]; - data = data:format(x, y, pos.x, pos.y, pos.z, pos.x, pos.y, pos.z); - data = data .. fs.cost(1.25, 0.25, { - paper = 0, - Pigment = 0, - }) .. "container_end[]"; - - return data; +-- Draw the map copying tab UI +-- x: The x position of the interface +-- y: The y position of the interface +-- pos: The table position (for displaying the inventory) +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.copy(x, y, pos, skin) + return string.format("container[%f,%f]", x, y) + .. "formspec_version[3]" + .. inventory_bg(0, 0, 1, 1, skin.slot) + .. string.format("list[nodemeta:%d,%d,%d;copy_input;0,0;1,1;]", pos.x, pos.y, pos.z) + .. "button[1.25,0.5;2,0.5;copy;Copy Map]" + .. fs.cost(1.25, 0.125, { Paper = 0, Pigment = 0, }) + .. inventory_bg(8.75, 0, 1, 1, skin.slot) + .. string.format("list[nodemeta:%d,%d,%d;copy_output;8.75,0;1,1;]", pos.x, pos.y, pos.z) + .. "container_end[]"; end -function fs.inv(x, y) - local data = [[ - container[%f, %f] - formspec_version[3] - list[current_player;main;0,0;8,4;] - container_end[] - ]]; - - return data:format(x, y) +-- Draw the player's inventory +-- x: The x position of the inventory +-- y: The y position of the inventory +-- skin: A formspec skin table +-- +-- Returns a formspec string +function fs.inv(x, y, skin) + return string.format("container[%f,%f]", x, y) + .. "formspec_version[3]" + .. inventory_bg(0, 0, 8, 4, skin.slot) + .. "list[current_player;main;0,0;8,4;]" + .. "container_end[]"; end local player_tables = {}; +-- Show the table formspec to the specified player +-- The player must be recorded in player_tables in order to receive +-- a formspec. +-- +-- player: A string containing the player's name +-- tab: Which tab of the interface to display local function table_formspec(player, tab) local pos = player_tables[player]; + + if not pos then + return; + end + local meta = minetest.get_meta(pos); local rank = 1; + local skin = cartographer.skin.table_skins.simple_table; local name = minetest.get_node(pos).name; if name == "cartographer:standard_table" then rank = 2; + skin = cartographer.skin.table_skins.standard_table; elseif name == "cartographer:advanced_table" then rank = 3; + skin = cartographer.skin.table_skins.advanced_table; end if tab == 1 then minetest.show_formspec(player, "simple_table", - fs.header(10.25, 6.75, rank, tab) .. - fs.materials(0.25, 0, rank, meta) .. - separator:format(0.4) .. - fs.convert(0.25, 0.5, pos) .. - fs.inv(0.25, 1.75) + fs.header(10.25, 7.375, rank, 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) ); elseif tab == 2 then minetest.show_formspec(player, "simple_table", - fs.header(10.25, 8.0, rank, tab) .. - fs.materials(0.25, 0, rank, meta) .. - separator:format(0.4) .. - fs.craft(0.25, 0.5, pos, rank, meta) .. - fs.inv(0.25, 3) + fs.header(10.25, 8.0, rank, 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(2.75, skin.separator) .. + fs.inv(0.25, 3, skin) ); elseif tab == 3 then minetest.show_formspec(player, "simple_table", - fs.header(10.25, 8.0, rank, tab) .. - fs.materials(0.25, 0, rank, meta) .. - separator:format(0.4) .. - fs.copy(0.25, 0.5, pos) .. - fs.inv(0.25, 3) + fs.header(10.25, 7.375, rank, 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) ); end end +-- Called when a player sends input to the server from a formspec +-- This callback handles player input in the table formspec +-- player: The player who sent the input +-- name: The formspec name +-- fields: A table containing the input minetest.register_on_player_receive_fields(function(player, name, fields) if name == "simple_table" then minetest.chat_send_all(name..": "); @@ -372,8 +434,12 @@ minetest.register_on_player_receive_fields(function(player, name, fields) elseif fields["4x"] ~= nil then meta:set_int("scale", SCALE_LARGE); table_formspec(player:get_player_name(), 2) - elseif fields["tabs"] ~= nil then - table_formspec(player:get_player_name(), tonumber(fields["tabs"])); + elseif fields["tab1"] ~= nil then + table_formspec(player:get_player_name(), 1); + elseif fields["tab2"] ~= nil then + table_formspec(player:get_player_name(), 2); + elseif fields["tab3"] ~= nil then + table_formspec(player:get_player_name(), 3); end end end); @@ -393,8 +459,8 @@ end minetest.register_node("cartographer:simple_table", { description = "Shabby Cartographer's Table", drawtype = "mesh", - mesh = "cartographer_simple_table.obj", - tiles = { "cartographer_simple_table.png" }, + mesh = cartographer.skin.table_skins.simple_table.node_mesh, + tiles = { cartographer.skin.table_skins.simple_table.node_texture }, paramtype2 = "facedir", groups = { choppy = 2, @@ -423,8 +489,8 @@ minetest.register_node("cartographer:simple_table", { minetest.register_node("cartographer:standard_table", { description = "Simple Cartographer's Table", drawtype = "mesh", - mesh = "cartographer_standard_table.obj", - tiles = { "cartographer_standard_table.png" }, + mesh = cartographer.skin.table_skins.standard_table.node_mesh, + tiles = { cartographer.skin.table_skins.standard_table.node_texture }, paramtype2 = "facedir", groups = { choppy = 2, @@ -453,8 +519,8 @@ minetest.register_node("cartographer:standard_table", { minetest.register_node("cartographer:advanced_table", { description = "Advanced Cartographer's Table", drawtype = "mesh", - mesh = "cartographer_advanced_table.obj", - tiles = { "cartographer_advanced_table.png" }, + mesh = cartographer.skin.table_skins.advanced_table.node_mesh, + tiles = { cartographer.skin.table_skins.advanced_table.node_texture }, paramtype2 = "facedir", groups = { choppy = 2, diff --git a/textures/cartographer_paper.png b/textures/cartographer_paper.png new file mode 100644 index 0000000..bfe06d4 Binary files /dev/null and b/textures/cartographer_paper.png differ diff --git a/textures/cartographer_pigment.png b/textures/cartographer_pigment.png new file mode 100644 index 0000000..2941b05 Binary files /dev/null and b/textures/cartographer_pigment.png differ diff --git a/textures/cartographer_simple_table_bg.png b/textures/cartographer_simple_table_bg.png new file mode 100644 index 0000000..c74421a Binary files /dev/null and b/textures/cartographer_simple_table_bg.png differ diff --git a/textures/cartographer_simple_table_button.png b/textures/cartographer_simple_table_button.png new file mode 100644 index 0000000..4efcac5 Binary files /dev/null and b/textures/cartographer_simple_table_button.png differ diff --git a/textures/cartographer_simple_table_button_hovered.png b/textures/cartographer_simple_table_button_hovered.png new file mode 100644 index 0000000..dc81ded Binary files /dev/null and b/textures/cartographer_simple_table_button_hovered.png differ diff --git a/textures/cartographer_simple_table_button_pressed.png b/textures/cartographer_simple_table_button_pressed.png new file mode 100644 index 0000000..ae14d7a Binary files /dev/null and b/textures/cartographer_simple_table_button_pressed.png differ diff --git a/textures/cartographer_simple_table_separator.png b/textures/cartographer_simple_table_separator.png new file mode 100644 index 0000000..c115636 Binary files /dev/null and b/textures/cartographer_simple_table_separator.png differ diff --git a/textures/cartographer_simple_table_slot.png b/textures/cartographer_simple_table_slot.png new file mode 100644 index 0000000..100113e Binary files /dev/null and b/textures/cartographer_simple_table_slot.png differ diff --git a/textures/cartographer_simple_table_tab.png b/textures/cartographer_simple_table_tab.png new file mode 100644 index 0000000..41e8c30 Binary files /dev/null and b/textures/cartographer_simple_table_tab.png differ diff --git a/textures/cartographer_simple_table_tab_hovered.png b/textures/cartographer_simple_table_tab_hovered.png new file mode 100644 index 0000000..9500961 Binary files /dev/null and b/textures/cartographer_simple_table_tab_hovered.png differ diff --git a/textures/cartographer_simple_table_tab_selected.png b/textures/cartographer_simple_table_tab_selected.png new file mode 100644 index 0000000..27618b9 Binary files /dev/null and b/textures/cartographer_simple_table_tab_selected.png differ