From 07101b99fee40092c1738907d660185f06a32092 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Tue, 20 Jun 2017 05:02:53 -0400 Subject: [PATCH 1/5] add helper function for crafting param2-colorized items One call registers the full set of 32, 89, or 256 colors. Pass it a recipe of the following general form ```lua unifieddyes.register_color_craft({ output = "mymod:colorized_node", type = palette = , neutral_node = "some_mod:neutral_node", recipe = { } }) ``` palette may be either "wallmounted" (32 colors), false or omitted entirely (89 colors), or "extended" (256 colors). The recipe section is either a shapeless list, or a standard three-line shaped recipe, same as the regular register_craft() function. The key difference is two placeholder keys that are now supported: * if an item in the recipe is "MAIN_DYE", then Unified Dyes will, with each pass of its registration loop, substitute the actual "dye:foo" craft item in its place which corresponds with the current loop's color. * if an item in the recipe list is "NEUTRAL_NODE", then the value of the "neutral_node" field will be substituted in its place. The expectation here is that the modder probably has some base recipe in mind that, given no dyes, would result in a neutral, uncolored node. This call creates all the recipes that would be needed to craft colored versions of that neutral node either using that base recipe with dye added, or by crafting the neutral node with some dye after the fact. --- init.lua | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index ff2fd41..5ae1b0c 100644 --- a/init.lua +++ b/init.lua @@ -30,8 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc., --===================================================================== unifieddyes = {} -unifieddyes.last_used_dye = {} -unifieddyes.last_dyed_node = {} local creative_mode = minetest.settings:get_bool("creative_mode") @@ -89,6 +87,17 @@ unifieddyes.HUES_EXTENDED = { { "crimson", 0xff, 0x00, 0x40 } } +unifieddyes.HUES_WALLMOUNTED = { + "red", + "orange", + "yellow", + "green", + "cyan", + "blue", + "violet", + "magenta" +} + unifieddyes.SATS = { "", "_s50" @@ -136,6 +145,65 @@ local default_dyes = { "yellow" } +-- this helper function registers all of the recipes needed to create colored +-- blocks with any of the dyes supported by that block's palette. + +function unifieddyes.register_color_craft(craft) + if not craft or not craft.recipe or not craft.output or not craft.neutral_node then return end + + local hues_table = unifieddyes.HUES_EXTENDED + local sats_table = unifieddyes.SATS + local vals_table = unifieddyes.VALS_EXTENDED + + if not craft.palette then + hues_table = unifieddyes.HUES + sats_table = unifieddyes.SATS + vals_table = unifieddyes.VALS + elseif craft.palette == "wallmounted" then + hues_table = unifieddyes.HUES_WALLMOUNTED + sats_table = {""} + vals_table = unifieddyes.VALS + end + + for _,hue in ipairs(hues_table) do + for _,sat in ipairs(sats_table) do + for _,val in ipairs(vals_table) do + + local color = "dye:"..val..hue[1]..sat + local paletteidx = unifieddyes.getpaletteidx(color, craft.palette) + local newrecipe = table.copy(craft.recipe) + + for k, item in ipairs(newrecipe) do + if item == "MAIN_DYE" then newrecipe[k] = color end + if item == "NEUTRAL_NODE" then newrecipe[k] = craft.neutral_node end + end + + local stack = ItemStack(craft.output) + stack:get_meta():set_int("palette_index", paletteidx) + stack:get_meta():set_string("dye", color) + local colorized_itemstack = stack:to_string() + + minetest.register_craft({ + output = colorized_itemstack, + type = craft.type, + recipe = newrecipe + }) + + if craft.neutral_node ~= string.split(craft.output, " ")[1] then + minetest.register_craft( { + output = colorized_itemstack, + type = "shapeless", + recipe = { + craft.neutral_node, + color + } + }) + end + end + end + end +end + -- automatically recolor a placed node to match the last-used dye -- should be called in the node's `after_place_node` callback. From ad8ab99bd845c8203fb00297fd60468fcaf942b6 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Tue, 20 Jun 2017 05:10:59 -0400 Subject: [PATCH 2/5] disable auto-coloring code entirely --- init.lua | 84 ++++---------------------------------------------------- 1 file changed, 5 insertions(+), 79 deletions(-) diff --git a/init.lua b/init.lua index 5ae1b0c..f44b733 100644 --- a/init.lua +++ b/init.lua @@ -145,6 +145,11 @@ local default_dyes = { "yellow" } +-- just a stub to keep old mods from crashing when expecting auto-coloring + +function unifieddyes.recolor_on_place(foo) +end + -- this helper function registers all of the recipes needed to create colored -- blocks with any of the dyes supported by that block's palette. @@ -204,72 +209,6 @@ function unifieddyes.register_color_craft(craft) end end --- automatically recolor a placed node to match the last-used dye --- should be called in the node's `after_place_node` callback. - -function unifieddyes.recolor_on_place(pos, placer, itemstack, pointed_thing) - - local playername = placer:get_player_name() - local stackname = itemstack:get_name() - - if unifieddyes.last_dyed_node[playername] ~= stackname then - if unifieddyes.last_used_dye[playername] then - minetest.chat_send_player(playername, "Switched to \""..stackname.."\" while auto-coloring, color reset to neutral.") - end - unifieddyes.last_used_dye[playername] = nil - unifieddyes.last_dyed_node[playername] = nil - end - - unifieddyes.last_dyed_node[playername] = stackname - - if unifieddyes.last_used_dye[playername] then - local lastdye = unifieddyes.last_used_dye[playername] - - local inv = placer:get_inventory() - if (lastdye and lastdye ~= "" and inv:contains_item("main", lastdye.." 1")) or creative_mode then - - local nodedef = minetest.registered_nodes[stackname] - local newname = nodedef.ud_replacement_node or stackname - local node = minetest.get_node(pos) - - local palette_type = true -- default to 89-color split, because the others are easier to check for. - local oldfdir = node.param2 % 32 - - if nodedef.palette == "unifieddyes_palette.png" then - palette_type = false - oldfdir = 0 - elseif nodedef.palette == "unifieddyes_palette_colorwallmounted.png" then - palette_type = "wallmounted" - oldfdir = node.param2 % 8 - elseif nodedef.palette == "unifieddyes_palette_extended.png" then - palette_type = "extended" - oldfdir = 0 - end - - local paletteidx, hue = unifieddyes.getpaletteidx(lastdye, palette_type) - if palette_type == true then newname = string.gsub(newname, "_grey", "_"..unifieddyes.HUES[hue]) end - - minetest.set_node(pos, { name = newname, param2 = oldfdir + paletteidx }) - - local meta = minetest.get_meta(pos) - meta:set_string("dye", lastdye) - - if not creative_mode then - inv:remove_item("main", lastdye.." 1") - end - else - minetest.chat_send_player(playername, "Ran out of "..unifieddyes.last_used_dye[playername]..", resetting to neutral.") - unifieddyes.last_used_dye[playername] = nil - end - end -end - -minetest.register_on_leaveplayer(function(player) - local playername = player:get_player_name() - unifieddyes.last_used_dye[playername] = nil - unifieddyes.last_dyed_node[playername] = nil -end) - -- code borrowed from homedecor -- call this function to reset the rotation of a "wallmounted" object on place @@ -662,14 +601,6 @@ function unifieddyes.on_use(itemstack, player, pointed_thing) end end - if player:get_player_control().sneak then - if unifieddyes.last_used_dye[playername] then - minetest.chat_send_player(playername, "Shift-punched a node, switching back to neutral color." ) - end - unifieddyes.last_used_dye[playername] = nil - return - end - -- if the target is unknown, has no groups defined, or isn't UD-colorable, just bail out if not (nodedef and nodedef.groups and nodedef.groups.ud_param2_colorable) then minetest.chat_send_player(playername, "That node can't be colored.") @@ -699,11 +630,6 @@ function unifieddyes.on_use(itemstack, player, pointed_thing) if paletteidx then - if unifieddyes.last_used_dye[playername] ~= stackname then - minetest.chat_send_player(playername, "Color "..stackname.." selected, auto-coloring activated." ) - unifieddyes.last_used_dye[playername] = stackname - end - local meta = minetest.get_meta(pos) local prevdye = meta:get_string("dye") local inv = player:get_inventory() From 731c7d133e59b2c4c30c626d4f10d4424f386c2f Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Tue, 20 Jun 2017 05:20:25 -0400 Subject: [PATCH 3/5] disable old after_dig_node() callbacks (don't split a digged node into neutral+dye) --- init.lua | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/init.lua b/init.lua index f44b733..85f5380 100644 --- a/init.lua +++ b/init.lua @@ -145,11 +145,15 @@ local default_dyes = { "yellow" } --- just a stub to keep old mods from crashing when expecting auto-coloring +-- just stubs to keep old mods from crashing when expecting auto-coloring +-- or getting back the dye on dig. function unifieddyes.recolor_on_place(foo) end +function unifieddyes.after_dig_node(foo) +end + -- this helper function registers all of the recipes needed to create colored -- blocks with any of the dyes supported by that block's palette. @@ -547,26 +551,6 @@ function unifieddyes.on_construct(pos) meta:set_string("palette", "ext") end --- call this in your node's after_dig_node to get the last-used dye back. - -function unifieddyes.after_dig_node(pos, oldnode, oldmetadata, digger) - local prevdye - - if oldmetadata and oldmetadata.fields then - prevdye = oldmetadata.fields.dye - end - - local inv = digger:get_inventory() - - if prevdye and not (inv:contains_item("main", prevdye) and creative_mode) and minetest.registered_items[prevdye] then - if inv:room_for_item("main", prevdye) then - inv:add_item("main", prevdye) - else - minetest.add_item(pos, prevdye) - end - end -end - function unifieddyes.on_use(itemstack, player, pointed_thing) local stackname = itemstack:get_name() local playername = player:get_player_name() From a8caed8195013354eee73910f8dd8e048ac32f26 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Tue, 20 Jun 2017 05:46:30 -0400 Subject: [PATCH 4/5] separate the make-colored-itemstack code into its own function --- init.lua | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/init.lua b/init.lua index 85f5380..315f5fb 100644 --- a/init.lua +++ b/init.lua @@ -154,6 +154,16 @@ end function unifieddyes.after_dig_node(foo) end +-- This helper function mostly by juhdanad, creates a colored itemstack + +function unifieddyes.make_colored_itemstack(itemstack, palette, color) + local paletteidx = unifieddyes.getpaletteidx(color, palette) + local stack = ItemStack(itemstack) + stack:get_meta():set_int("palette_index", paletteidx) + stack:get_meta():set_string("dye", color) + return stack:to_string() +end + -- this helper function registers all of the recipes needed to create colored -- blocks with any of the dyes supported by that block's palette. @@ -179,7 +189,6 @@ function unifieddyes.register_color_craft(craft) for _,val in ipairs(vals_table) do local color = "dye:"..val..hue[1]..sat - local paletteidx = unifieddyes.getpaletteidx(color, craft.palette) local newrecipe = table.copy(craft.recipe) for k, item in ipairs(newrecipe) do @@ -187,10 +196,8 @@ function unifieddyes.register_color_craft(craft) if item == "NEUTRAL_NODE" then newrecipe[k] = craft.neutral_node end end - local stack = ItemStack(craft.output) - stack:get_meta():set_int("palette_index", paletteidx) - stack:get_meta():set_string("dye", color) - local colorized_itemstack = stack:to_string() + local colorized_itemstack = + unifieddyes.make_colored_itemstack(craft.output, craft.palette, color) minetest.register_craft({ output = colorized_itemstack, From a55f6faa14cf5e5b5e1aea3b78a00051d5b3e3b0 Mon Sep 17 00:00:00 2001 From: Vanessa Dannenberg Date: Tue, 21 Aug 2018 23:28:17 -0400 Subject: [PATCH 5/5] further refine how colored itemstacks work --- init.lua | 103 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/init.lua b/init.lua index 315f5fb..82a41ef 100644 --- a/init.lua +++ b/init.lua @@ -127,6 +127,14 @@ unifieddyes.GREYS = { "black" } +unifieddyes.GREYS_EXTENDED = table.copy(unifieddyes.GREYS) + +for i = 1, 14 do + if i ~= 0 and i ~= 3 and i ~= 7 and i ~= 11 and i ~= 15 then + table.insert(unifieddyes.GREYS_EXTENDED, "grey_"..i) + end +end + local default_dyes = { "black", "blue", @@ -154,18 +162,49 @@ end function unifieddyes.after_dig_node(foo) end --- This helper function mostly by juhdanad, creates a colored itemstack +-- This helper function creates a colored itemstack -function unifieddyes.make_colored_itemstack(itemstack, palette, color) +function unifieddyes.make_colored_itemstack(item, palette, color) local paletteidx = unifieddyes.getpaletteidx(color, palette) - local stack = ItemStack(itemstack) + local stack = ItemStack(item) stack:get_meta():set_int("palette_index", paletteidx) - stack:get_meta():set_string("dye", color) return stack:to_string() end --- this helper function registers all of the recipes needed to create colored --- blocks with any of the dyes supported by that block's palette. +-- if your node was once 89-color and uses an LBM to convert to the 256-color palette, +-- call this in that node def's on_construct: + +function unifieddyes.on_construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("palette", "ext") +end + +-- these helper functions register all of the recipes needed to create colored +-- nodes with any of the dyes supported by that node's palette. + +local function register_c(craft, hue, sat, val) + local color = "" + if val then + color = "dye:"..val..hue[1]..sat + else + color = "dye:"..hue -- if val is nil, then it's grey. + end + + local recipe = minetest.serialize(craft.recipe) + recipe = string.gsub(recipe, "MAIN_DYE", color) + recipe = string.gsub(recipe, "NEUTRAL_NODE", craft.neutral_node) + local newrecipe = minetest.deserialize(recipe) + + local colored_itemstack = + unifieddyes.make_colored_itemstack(craft.output, craft.palette, color) + + minetest.register_craft({ + output = colored_itemstack, + type = craft.type, + recipe = newrecipe + }) + +end function unifieddyes.register_color_craft(craft) if not craft or not craft.recipe or not craft.output or not craft.neutral_node then return end @@ -173,51 +212,34 @@ function unifieddyes.register_color_craft(craft) local hues_table = unifieddyes.HUES_EXTENDED local sats_table = unifieddyes.SATS local vals_table = unifieddyes.VALS_EXTENDED + local greys_table = unifieddyes.GREYS_EXTENDED if not craft.palette then hues_table = unifieddyes.HUES sats_table = unifieddyes.SATS vals_table = unifieddyes.VALS + greys_table = unifieddyes.GREYS elseif craft.palette == "wallmounted" then hues_table = unifieddyes.HUES_WALLMOUNTED sats_table = {""} vals_table = unifieddyes.VALS + greys_table = unifieddyes.GREYS end for _,hue in ipairs(hues_table) do - for _,sat in ipairs(sats_table) do - for _,val in ipairs(vals_table) do + for _,val in ipairs(vals_table) do + for _,sat in ipairs(sats_table) do - local color = "dye:"..val..hue[1]..sat - local newrecipe = table.copy(craft.recipe) + if sat == "_s50" and val ~= "" and val ~= "medium_" and val ~= "dark_" then break end + register_c(craft, hue, sat, val) - for k, item in ipairs(newrecipe) do - if item == "MAIN_DYE" then newrecipe[k] = color end - if item == "NEUTRAL_NODE" then newrecipe[k] = craft.neutral_node end - end - - local colorized_itemstack = - unifieddyes.make_colored_itemstack(craft.output, craft.palette, color) - - minetest.register_craft({ - output = colorized_itemstack, - type = craft.type, - recipe = newrecipe - }) - - if craft.neutral_node ~= string.split(craft.output, " ")[1] then - minetest.register_craft( { - output = colorized_itemstack, - type = "shapeless", - recipe = { - craft.neutral_node, - color - } - }) - end end end end + + for _, grey in ipairs(greys_table) do + register_c(craft, grey) + end end -- code borrowed from homedecor @@ -550,19 +572,11 @@ function unifieddyes.getpaletteidx(color, palette_type) end end --- if your node was once 89-color and uses an LBM to convert to the 256-color palette, --- call this in that node def's on_construct: - -function unifieddyes.on_construct(pos) - local meta = minetest.get_meta(pos) - meta:set_string("palette", "ext") -end - function unifieddyes.on_use(itemstack, player, pointed_thing) local stackname = itemstack:get_name() local playername = player:get_player_name() - if pointed_thing and pointed_thing.type == "node" then + if pointed_thing and pointed_thing.type == "node" and unifieddyes.select_node(pointed_thing) then if minetest.is_protected(unifieddyes.select_node(pointed_thing), playername) and not minetest.check_player_privs(playername, "protection_bypass") then minetest.chat_send_player(playername, "Sorry, someone else owns that spot.") @@ -1029,7 +1043,9 @@ minetest.register_alias("dye:medium_orange", "dye:brown") minetest.register_alias("unifieddyes:black", "dye:black") minetest.register_alias("unifieddyes:dark_grey", "dye:dark_grey") +minetest.register_alias("unifieddyes:grey", "dye:grey") minetest.register_alias("unifieddyes:light_grey", "dye:light_grey") +minetest.register_alias("unifieddyes:white", "dye:white") minetest.register_alias("unifieddyes:grey_0", "dye:black") minetest.register_alias("unifieddyes:grey_4", "dye:dark_grey") @@ -1051,6 +1067,7 @@ minetest.register_alias("unifieddyes:carbon_black", "dye:black") minetest.register_alias("unifieddyes:aqua", "unifieddyes:spring") minetest.register_alias("unifieddyes:skyblue", "unifieddyes:azure") minetest.register_alias("unifieddyes:redviolet", "unifieddyes:rose") +minetest.register_alias("unifieddyes:brown", "dye:brown") print(S("[UnifiedDyes] Loaded!"))