Compare commits

15 Commits

3 changed files with 525 additions and 67 deletions

View File

@ -1,15 +1,9 @@
dye
default?
unifieddyes?
coloredwood?
unifiedbricks?
stained_glass?
cotton?
wool?
flags?
blox?
homedecor?
plasticbox?
kerova?
hardenedclay?
clstone?
@ -21,3 +15,5 @@ mydeck?
mycorners?
mymulch?
clothing?
cblocks?
morecolors?

574
init.lua
View File

@ -20,9 +20,16 @@
-- Version 0.6
-- Version 0.9
-- Changelog:
-- 07.08.17 Adjusted to new hardware coloring (paramtype2 based)
-- 16.02.17 Removed support for lrfurn (that mod uses the new coloring mechanism as well)
-- 08.02.17 Removed support for homedecor, blox, plasticbox, stainedglass, coloredwood and unifiedbricks
-- as those now use a new feature of newer versions of MT that makes the colormachine
-- obsolete for them.
-- 22.04.16 Added support for myfences: https://forum.minetest.net/viewtopic.php?f=9&t=14275
-- 28.09.15 Added support for cblocks: https://forum.minetest.net/viewtopic.php?f=9&t=13303
-- 23.05.15 As all dyes can be crafted into other dyes, only white dye is consumed - provided the
-- other dyes needed for the crafting chain are stored.
-- 22.05.15 Added support for new homedecor meshnodes.
@ -66,18 +73,19 @@
colormachine = {};
colormachine.colors = {
"red",
"orange",
"yellow",
"lime",
"green",
"aqua",
"cyan",
"skyblue",
"blue",
"violet",
"magenta",
"redviolet"
"red", -- ff 00 00
"orange", -- ff 80 00
"yellow", -- ff ff 00
"lime", -- 80 ff 00
"green", -- 00 ff 00
"spring", -- 00 ff 80 old name: "aqua",
"cyan", -- 00 ff ff
"azure", -- 00 80 ff old: "skyblue",
"blue", -- 00 00 ff
"violet", -- 80 00 ff
"magenta",-- ff 00 ff
"rose" -- ff 00 80 old: "redviolet"
-- TODO: what about nodes with the old names? aqua -> spring, skyblue -> azure, and redviolet -> rose aliases
}
@ -87,8 +95,8 @@ local stained_glass_exception = 0;
-- the names of suitable sources of that color (note: this does not work by group!);
-- you can add your own color sources here if you want
colormachine.basic_dye_sources = { "flowers:rose", "flowers:tulip", "flowers:dandelion_yellow",
"", "default:cactus", "", "", "", -- no lime, no aqua, no cyan, no skyblue
"flowers:geranium", "flowers:viola", "", "", -- no magenta, no redviolet
"", "default:cactus", "", "", "", -- no lime, no spring, no cyan, no azure
"flowers:geranium", "flowers:viola", "", "", -- no magenta, no rose
"default:clay_lump", "", "", "", "default:coal_lump" };
-- if flowers is not installed
@ -105,13 +113,13 @@ colormachine.dye_mixes = { red = {}, -- base color
yellow = {}, -- base color
lime = {3,5}, -- yellow + green
green = {3,9}, -- yellow + blue
aqua = {5,7}, -- green + cyan
spring = {5,7}, -- green + cyan
cyan = {5,9}, -- green + blue
skyblue = {7,9}, -- cyan + blue
azure = {7,9}, -- cyan + blue
blue = {}, -- base color
violet = {9,11}, -- blue + magenta
magenta = {9,1}, -- blue + red
redviolet = {11,1}, -- magenta + red
rose = {11,1}, -- magenta + red
white = {}, -- base color
lightgrey = {13,15}, -- white + grey
@ -138,6 +146,112 @@ for i,v in ipairs( colormachine.grey_names ) do
colormachine.colors_and_greys[ #colormachine.colors + i ] = v;
end
--[[
colormachine.dye_palette[ name_of_palette ] = { -- i.e. "unifieddyes_palette_reds.png"
color, -- 1..12; -1 if grey is ~= -1
shade, -- 1..8; -1 if grey is ~= -1
grey, -- 1..5; -1 if color or shade is ~= -1
name_of_dye, -- i.e. "unifieddyes:dark_red_s50.png"
param2_value, -- 0..size of palette-1
colorstring, -- i.e. "a85400" for dark orange
}
--]]
colormachine.dye_palette = {};
-- entries: c(olor), s(hade), g(reyscale), dye_name, param2_value, color_code
colormachine.dye_palette[ "colorfacedir_palette.png" ] = {
{ -1, -1, 1, "dye:white", 0, "ffffff"}, -- 1
{ 1, 3, -1, "dye:red", 1, "8b0000"}, -- 2
{ 2, 3, -1, "dye:orange", 2, "ffa500"}, -- 3
{ 3, 3, -1, "dye:yellow", 3, "eeee00"}, -- 4
{ 5, 3, -1, "dye:green", 4, "006400"}, -- 5
{ 9, 3, -1, "dye:blue", 5, "00008b"}, -- 6
{ -1, -1, 3, "dye:grey", 6, "808080"}, -- 7
{ 11, 3, -1, "dye:magenta", 7, "ff1493"}, -- 8
};
-- 24 colors
-- we have some left (standard: 15 dyes)
-- dark green is darker than normal green; necessary because
-- the colors ought to be the same as for the 8-color-palette
colormachine.dye_palette[ "unifieddyes_palette_colorwallmounted.png"] = {
{ -1, -1, 1, "dye:white", 0, "ffffff"}, -- 1 white
{ -1, -1, 2, "nonexistant", 1, "bfbfbf"}, -- 2 light grey
{ -1, -1, 3, "dye:grey", 2, "808080"}, -- 3 grey
{ -1, -1, 4, "dye:dark_grey", 3, "404040"}, -- 4 dark grey
{ -1, -1, 5, "dye:black", 4, "141414"}, -- 5 black
{ 8, 1, -1, "nonexistant", 5, "8080ff"}, -- 6 azure?
{ 2, 4, -1, "dye:brown", 6, "aa5500"}, -- 7 ocker brown
{ 12, 1, -1, "dye:pink", 7, "ffc1da"}, -- 8 pink
{ 1, 1, -1, "nonexistant", 8, "ff0000"}, -- 9 bright red
{ 2, 1, -1, "dye:orange", 9, "ff8000"}, -- 10 bright orange
{ 3, 1, -1, "dye:yellow", 10, "ffff00"}, -- 11 bright yellow
{ 5, 1, -1, "nonexistant", 11, "00ff00"}, -- 12 bright green
{ 7, 1, -1, "nonexistant", 12, "00ffff"}, -- 13 bright cyan
{ 9, 1, -1, "nonexistant", 13, "0000ff"}, -- 14 bright blue
{ 10, 1, -1, "nonexistant", 14, "8000ff"}, -- 15 bright violet
{ 11, 1, -1, "dye:magenta", 15, "ff00ff"}, -- 16 bright magenta
{ 1, 3, -1, "dye:red", 16, "a80000"}, -- 17 dark red
{ 2, 3, -1, "nonexistant", 17, "a85400"}, -- 18 dark orange
{ 3, 3, -1, "nonexistant", 18, "a8a800"}, -- 19 dark yellow
{ 5, 3, -1, "dye:dark_green",19, "00a800"}, -- 20 dark green
{ 7, 3, -1, "dye:cyan", 20, "00a8a8"}, -- 21 dark cyan
{ 9, 3, -1, "nonexistant", 21, "0000a8"}, -- 22 dark blue
{ 10, 3, -1, "dye:violet", 22, "5400a8"}, -- 23 dark violet
{ 11, 3, -1, "nonexistant", 23, "a800a8"}, -- 24 dark magenta
{ 1, 5, -1, "nonexistant", 24, "550000"}, -- 25 very dark red
{ 2, 5, -1, "nonexistant", 25, "552a00"}, -- 26 also: very dark orange
{ 3, 5, -1, "nonexistant", 26, "555500"}, -- 27 very dark yellow
{ 5, 5, -1, "dye:green", 27, "005500"}, -- 28 (very dark green)
{ 7, 5, -1, "nonexistant", 28, "005500"}, -- 29 very dark cyan
{ 9, 5, -1, "dye:blue", 29, "000055"}, -- 30 (very dark blue)
{ 10, 5, -1, "nonexistant", 30, "2a0055"}, -- 31 very dark violet
{ 11, 5, -1, "nonexistant", 31, "550055"}, -- 32 very dark mangeta
};
colormachine.add_unifieddyes_palette = function( color_name, c_nr )
local color_name_old = color_name;
if( color_name == "spring" ) then
color_name_old = "aqua";
elseif( color_name == "azure" ) then
color_name_old = "skyblue";
elseif( color_name == "rose") then
color_name_old = "redviolet";
end
colormachine.dye_palette[ "unifieddyes_palette_"..color_name_old.."s.png"] = {
{ c_nr, 1, -1, "dye:white", 0, "ffffff"}, -- 1
{ c_nr, 2, -1, "unifieddyes_"..color_name..".png", 1, "ff0000"}, -- 2
{ c_nr, 3, -1, "unifieddyes_"..color_name.."_s50.png", 2, "c04040"}, -- 3
-- TODO: c_nr, 4 - unsure which color name that might represent
{ c_nr, 4, -1, "nonexistant", 3, "ff8080"}, -- 4
{ c_nr, 5, -1, "unifieddyes_medium_"..color_name..".png", 4, "a80000"}, -- 5
{ c_nr, 6, -1, "unifieddyes_medium_"..color_name.."_s50.png",5, "802a2a"}, -- 6
{ c_nr, 7, -1, "unifieddyes_dark_" ..color_name..".png", 6, "550000"}, -- 7
{ c_nr, 8, -1, "unifieddyes_dark_" ..color_name.."_s50.png",7, "3f0e0e"}, -- 8
-- TODO: adjust color mask for further colors
};
-- grey colors are handled diffrently
-- TODO: we have only 5 places to show them and are defining 8
if( color_name == "grey" ) then
for i,v in ipairs( colormachine.dye_palette[ "unifieddyes_palette_"..color_name_old.."s.png"] ) do
v[3] = v[2];
v[1] = -1;
v[2] = -1;
end
end
end
-- add the huge amount of color palettes for unifieddyes
for c_nr,color_name in ipairs( colormachine.colors ) do
colormachine.add_unifieddyes_palette( color_name, c_nr );
end
colormachine.add_unifieddyes_palette( "grey", -1 );
-- defines the order in which blocks are shown
-- nr: the diffrent block types need to be ordered by some system; the number defines that order
-- modname: some mods define more than one type of colored blocks; the modname is needed
@ -149,11 +263,13 @@ end
-- block: unpainted basic block
-- add: item names are formed by <modname>:<add><colorname> (with colorname beeing variable)
-- names for the textures are formed by <index><colorname><png> mostly (see colormachine.translate_color_name(..))
-- p: amount of blocks colored with one piece of dye
colormachine.data = {
-- the dyes as such
unifieddyes_ = { nr=1, modname='unifieddyes', shades={1,0,1,1,1,1,1,1}, grey_shades={1,1,1,1,1}, u=1, descr="ufdye", block="dye:white", add="", p=1 },
--[[
-- coloredwood: sticks not supported (they are only craftitems)
coloredwood_wood_ = { nr=2, modname='coloredwood', shades={1,0,1,1,1,1,1,1}, grey_shades={1,1,1,1,1}, u=1, descr="planks", block="default:wood", add="wood_", p=2 },
coloredwood_fence_ = { nr=3, modname='coloredwood', shades={1,0,1,1,1,1,1,1}, grey_shades={1,1,1,1,1}, u=1, descr="fence", block="default:fence_wood", add="fence_", p=2},
@ -163,6 +279,7 @@ colormachine.data = {
unifiedbricks_brickblock_ = { nr=5, modname='unifiedbricks', shades={1,0,1,1,1,1,1,1}, grey_shades={1,1,1,1,1}, u=1, descr="brick", block="default:brick", add="brickblock_",p=1},
-- the multicolored bricks come in fewer intensities (only 3 shades) and support only 3 insted of 5 shades of grey
unifiedbricks_multicolor_ = { nr=6, modname='unifiedbricks', shades={1,0,0,0,1,0,1,0}, grey_shades={0,1,1,1,0}, u=1, descr="mbrick", block="default:brick", add="multicolor_",p=1},
--]]
hardenedclay_ = { nr=3.5, modname='hardenedclay', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="hclay", block="hardenedclay:hardened_clay_white", add="hardened_clay_", p=16},
colouredstonebricks_ = { nr=3.6, modname='colouredstonebricks', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="cbrick", block="default:stonebrick", add="", p=1},
@ -175,12 +292,14 @@ colormachine.data = {
colorcubes_window_ = { nr=3.93,modname='colorcubes', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="ccubew",block="default:stone", add="", p=1, obj_postfix='_window' },
--[[
-- stained_glass: has a "faint" and "pastel" version as well (which are kind of additional shades used only by this mod)
-- no shades of grey for the glass
stained_glass_ = { nr=7, modname='stained_glass', shades={1,0,1,1,1,1,1,1}, grey_shades={0,0,0,0,0}, u=1, descr="glass", block="moreblocks:super_glow_glass", add="",p=2},
stained_glass_faint_ = { nr=8, modname='stained_glass', shades={0,0,1,0,0,0,0,0}, grey_shades={0,0,0,0,0}, u=1, descr="fglass", block="moreblocks:super_glow_glass", add="",p=2},
stained_glass_pastel_ = { nr=9, modname='stained_glass', shades={0,0,1,0,0,0,0,0}, grey_shades={0,0,0,0,0}, u=1, descr="pglass", block="moreblocks:super_glow_glass", add="",p=2},
--]]
-- use 9.5 to insert it between stained glass and cotton
framedglass_ = { nr=9.5, modname='framedglass', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="fglass", block="framedglass:steel_framed_obsidian_glass", add="steel_framed_obsidian_glass",p=1},
@ -205,14 +324,17 @@ colormachine.data = {
-- beds_bed_top_top_ = { nr=13, modname='beds', shades={0,0,1,0,0,0,0,0}, grey_shades={1,0,1,0,1}, u=0, descr="beds", block="beds:bed_white", add="bed_bottom_",p=1},
--[[
lrfurn_armchair_front_ = { nr=14, modname='lrfurn', shades={0,0,1,0,0,0,0,0}, grey_shades={1,0,1,0,1}, u=0, descr="armchair",block="lrfurn:armchair_white", add="armchair_",p=1, composed=1 },
lrfurn_sofa_right_front_ = { nr=15, modname='lrfurn', shades={0,0,1,0,0,0,0,0}, grey_shades={1,0,1,0,1}, u=0, descr="sofa", block="lrfurn:longsofa_white", add="sofa_right_",p=1, composed=1 },
lrfurn_longsofa_middle_front_= { nr=16, modname='lrfurn', shades={0,0,1,0,0,0,0,0}, grey_shades={1,0,1,0,1}, u=0, descr="longsofa",block="lrfurn:sofa_white", add="longsofa_right_",p=1, composed=1 },
--]]
-- grey variants do not seem to exist, even though the textures arethere (perhaps nobody wants a grey flag!)
flags_ = { nr=17, modname='flags', shades={0,0,1,0,0,0,0,0}, grey_shades={1,0,0,0,1}, u=1, descr="flags", block="flags:white", add="", p=3 },
--[[
blox_stone_ = { nr=18, modname='blox', shades={1,0,1,0,0,0,0,0}, grey_shades={1,0,0,0,1}, u=0, descr="SnBlox", block="default:stone", add="stone", p=2 },
blox_quarter_ = { nr=19, modname='blox', shades={1,0,1,0,0,0,0,0}, grey_shades={1,0,0,0,1}, u=0, descr="S4Blox", block="default:stone", add="quarter", p=4 },
blox_checker_ = { nr=20, modname='blox', shades={1,0,1,0,0,0,0,0}, grey_shades={1,0,0,0,1}, u=0, descr="S8Blox", block="default:stone", add="checker", p=4 },
@ -259,8 +381,8 @@ colormachine.data = {
homedecor_bottle_ = { nr=16.66, modname='homedecor', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,0,0,0}, u=0, descr="hbottle", block="vessels:glass_bottle", add="bottle_", composed=1},
homedecor_welcome_mat_ = { nr=16.67, modname='homedecor', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,0,0}, u=0, descr="hwmat", block="homedecor:welcome_mat_grey", add="welcome_mat_", composed=1},
plasticbox_ = { nr=16.7, modname='plasticbox', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="plastic", block="plasticbox:plasticbox", add="plasticbox_",p=16},
--]]
kerova_chest_front_ = { nr=16.8, modname='kerova', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="kerova", block="default:chest", add="chest_",p=16},
@ -293,8 +415,10 @@ colormachine.data = {
clothing_inv_shirt_ = { nr=44, modname='clothing', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="clshirt", block="clothing:shirt_white", add="shirt_",p=1},
clothing_inv_pants_ = { nr=45, modname='clothing', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="clpants", block="clothing:pants_white", add="pants_",p=1},
clothing_inv_cape_ = { nr=46, modname='clothing', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="clcape", block="clothing:cape_white", add="cape_",p=1},
}
cblocks_wood_ = { nr=2.01,modname='cblocks', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="cblwo", block="default:wood", add="wood_",p=1, composed=1},
cblocks_stonebrick_ = { nr=2.02,modname='cblocks', shades={1,0,1,0,0,0,1,0}, grey_shades={1,0,1,1,1}, u=0, descr="cblsb", block="default:stonebrick", add="stonebrick_",p=1, composed=1},
}
local mydeck_names = {'deck_boards','deck_beam',
@ -390,6 +514,23 @@ colormachine.data[ 'mymulch_' ] = {
p=1};
local myfences_names = {'corner_post', 'garden', 'garden_corner', 'picket', 'picket_corner',
'picketb', 'picketb_corner', 'privacy', 'privacy_corner'};
for i,v in ipairs( myfences_names ) do
colormachine.data[ v..'_' ] = {
nr= 51.0 + 1/100*i,
modname='myfences',
shades={1,0,1,0,0,0,1,0},
grey_shades={1,1,1,1,1},
u=0,
descr="myfe"..tostring(i),
block="myfences:"..v,
add=v..'_',
composed=1,
p=1};
end
myfences_names = nil;
colormachine.ordered = {}
@ -397,9 +538,9 @@ colormachine.ordered = {}
-- the function that creates the color chooser based on the textures of the nodes offered (texture names have to start with m_prefix)
colormachine.generate_form = function( m_prefix )
local form = "size["..tostring( #colormachine.colors+2 )..",10]".."label[5,0;Select a color:]"..
"label[5,8.2;Select a color or]"..
"button[7,8.2;2,1;abort;abort selection]"..
local form = "size["..tostring( #colormachine.colors+2 )..",11]".."label[5,0;Select a color:]"..
"label[5,10.4;Select a color or]"..
"button[7,10.2;2,1;abort;abort selection]"..
"label[0.3,1;light]";
-- not all mods offer all shades (and some offer even more)
@ -417,6 +558,25 @@ colormachine.generate_form = function( m_prefix )
"label[0.3,7;dark]";
end
-- stair nodes and the like would be just too many nodes to show in the menu; therefore, each
-- combination of texture, palette and paramtype2 gets just one entry with alternate blocks
-- beeing listed on the menu page
if( colormachine.data[ m_prefix ].similar_blocks and #colormachine.data[ m_prefix ].similar_blocks > 1 ) then
form = form.."label[1,8.8;Similar blocks using the same texture and colors:]";
-- show each alternate block (usually diffrent shapes, i.e. stairs) as a button because that looks best
-- (not that the button does much except go back)
for i,block in ipairs( colormachine.data[ m_prefix ].similar_blocks ) do
if( i<14) then
form = form.."item_image_button["..tostring(i)..",9.2;1,1;"..block..";"..minetest.formspec_escape(block)..";]";
end
end
-- this can happen if i.e. unifieddyes and moreblocks meet
if( #colormachine.data[ m_prefix ].similar_blocks >13) then
form = form.."label[10.3,8.8;"..minetest.formspec_escape("..plus "..
tostring( #colormachine.data[ m_prefix ].similar_blocks-13 ).." more not shown here.").."]";
end
end
for x,basecolor in ipairs( colormachine.colors ) do
local p_offset = 1;
@ -597,6 +757,10 @@ colormachine.translate_color_name = function( meta, k, new_color, c, s, g, as_ob
c = tonumber(meta:get_string('selected_color'));
s = tonumber(meta:get_string('selected_shade'));
g = tonumber(meta:get_string('selected_grey_shade'));
-- wrong metadata?
if( not(c) or c=="" or not(s) or s=="" or not(g) or g=="") then
return nil;
end
end
@ -606,6 +770,34 @@ colormachine.translate_color_name = function( meta, k, new_color, c, s, g, as_ob
return nil;
end
-- use hardwarecoloring
if( colormachine.data[k].palette ) then
local palette = colormachine.dye_palette[ colormachine.data[k].palette ];
if( palette ) then
-- elements of palette: c(olor), s(hade), g(reyscale), dye_name, param2_value, color_code
-- search for the right entry in the dye_palette
local found = false;
for i,cp in ipairs( palette ) do
if( ( g==-1 and cp[1]==c and cp[2]==s) or (g~=-1 and cp[3]==g )) then
found = i;
end
end
if( not( found )) then
return nil;
end
-- there is just one block; coloring works through param2/itemstack data
if( as_obj_name==1 ) then
return colormachine.data[k].block;
end
-- formspec_escape is required here
return minetest.formspec_escape(
colormachine.data[k].texture_name.."^[colorize:#"..
palette[ found ][6]..":196");
end
end
local k_orig = k;
-- unifieddyes_ does not supply all colors
if( k == 'unifieddyes_'
@ -708,7 +900,7 @@ colormachine.translate_color_name = function( meta, k, new_color, c, s, g, as_ob
if( g>0 ) then
return nil; -- no grey values for them
end
local h_trans = {yellow=1, lime=2, green=3, aqua=4, cyan=5, skyblue=6, blue=7, violet=8, magenta=9, redviolet=10, red=11,orange=12};
local h_trans = {yellow=1, lime=2, green=3, spring=4, cyan=5, azure=6, blue=7, violet=8, magenta=9, rose=10, red=11,orange=12, aqua=4, skyblue=6, redviolet=10};
local h = h_trans[ colormachine.colors[c] ];
@ -846,7 +1038,7 @@ colormachine.translate_color_name = function( meta, k, new_color, c, s, g, as_ob
return prefix..new_color..postfix;
elseif( new_color == 'light_red' ) then
return prefix..'pink'..postfix;
-- lime, aqua, skyblue and redviolet do not exist as standard wool/dye colors
-- lime, spring, azure and rose do not exist as standard wool/dye colors
elseif( g == -1 and (c==4 or c==6 or c==8 or c==12) and k_orig ~= 'unifieddyes_') then
return nil;
-- all other colors of normal dye/wool exist only in normal shade
@ -864,8 +1056,61 @@ end
-- if a block is inserted, the name of its color is very intresting (for removing color or for setting that color)
-- (kind of the inverse of translate_color_name)
colormachine.get_color_from_blockname = function( mod_name, block_name )
-- palette_index is used for hardware coloring: stack:get_meta():get_string("palette_index"); it is nil otherwise
colormachine.get_color_from_blockname = function( mod_name, block_name, palette_index )
-- we are dealing with the new hardware coloring
if( palette_index ~= nil and palette_index ~= "") then
local data = colormachine.data[ block_name.."_" ];
if( not( data )
or not( data.palette )
or not( data.paramtype2 )) then
return { error_code ="Sorry, this hardware colored block is not supported by the spray booth.",
found_name = "",
blocktype = ""};
end
-- determine the name of the color (found_name)
local palette = colormachine.dye_palette[ data.palette ];
local found_name = nil;
-- palette_index seems to carry the multiplier in it
local p2 = tonumber(palette_index);
if( data.paramtype2=="colorfacedir" ) then
p2 = (p2 - (p2%32))/32;
elseif( data.paramtype2 == "colorwallmounted" ) then
p2 = (p2 - (p2% 8))/ 8;
end
-- determine the (unifieddyes) name of the color the block has
for i,c_data in ipairs( palette ) do
if( c_data[5] == p2 ) then
if( c_data[3]==-1 ) then
-- compose the name
found_name = colormachine.colors[c_data[1] ];
local prefix = colormachine.prefixes[ math.floor( (c_data[2] - 1 )/2)+1 ];
local postfix = "";
if( c_data[2]%2==0 ) then
postfix = "_s50";
end
if( found_name and prefix and postfix ) then
found_name = prefix..found_name..postfix;
end
else
found_name = colormachine.grey_names[c_data[3]];
end
end
end
if( not( found_name )) then
return { error_code = "Error: No suitable palette found with index "..tostring(palette_index).." for this block.",
found_name = "",
blocktype = ""};
end
return { error_code = nil,
found_name = found_name,
blocktype = block_name.."_"};
end
if( not( mod_name )) then
mod_name = "does not exist";
end
local bname = mod_name..":"..block_name;
local found = {};
for k,v in pairs( colormachine.data ) do
@ -1118,6 +1363,9 @@ colormachine.blocktype_menu = function( meta, new_color, page )
local per_line = 13;
local anz_lines = 3;
local per_page = anz_lines * per_line;
if( not( page )) then
page = 1;
end
local start_at_offset = per_page * page;
new_color = colormachine.decode_color_name( meta, new_color );
@ -1137,8 +1385,15 @@ colormachine.blocktype_menu = function( meta, new_color, page )
-- only installed mods are of intrest
if( k ~= nil and colormachine.data[ k ].installed == 1 and i > start_at_offset and i <= (start_at_offset + per_page)) then
-- if there are diffrent shapes (i.e. stairs, moreblock nodes, xconnected etc.), show the number
-- of shapes using this texture, palette, paramtype2 combination (i.e. [3] for 3 shapes)
local descr = colormachine.data[k].descr;
if( colormachine.data[ k ].similar_blocks and #colormachine.data[ k ].similar_blocks > 1 ) then
descr = minetest.formspec_escape("["..tostring( #colormachine.data[ k ].similar_blocks ).."]");
end
-- that particular mod may not offer this color
form = form.."button["..tostring(x)..","..tostring(y-0.8).. ";1,1;"..k..";"..colormachine.data[k].descr.."]"..
form = form.."button["..tostring(x)..","..tostring(y-0.8).. ";1,1;"..k..";"..descr.."]"..
"item_image["..tostring(x)..","..tostring(y )..";1,1;"..colormachine.data[k].block.."]";
local button = colormachine.print_color_image( meta, k, new_color, nil, nil, nil, tostring(x), tostring(y+1), 1);-- translated_color as return value for button
@ -1180,6 +1435,16 @@ colormachine.blocktype_menu = function( meta, new_color, page )
return form;
end
colormachine.owner_has_creative_priv = function( meta )
if( not( meta )) then
return false;
end
local owner = meta:get_string("owner");
if( not(owner) or owner=="" or not(minetest.check_player_privs( owner, {creative=true}))) then
return false;
end
return true;
end
-- this function tries to figure out which block type was inserted and how the color can be decoded
@ -1202,12 +1467,16 @@ colormachine.main_menu_formspec = function( pos, option )
"label[9.3,-0.5;Additional storage for dyes:]"..
"list[current_name;extrastore;9.3,0;5,9]";
if( minetest.setting_getbool("creative_mode") ) then
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if( colormachine.owner_has_creative_priv( meta )) then
form = form.."label[0.5,0.25;CREATIVE MODE:]".."label[0.5,0.75;no dyes or input consumed]";
end
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory();
local s = tonumber(meta:get_string('selected_shade' ));
local g = tonumber(meta:get_string('selected_grey_shade' ));
local c = tonumber(meta:get_string('selected_color' ));
-- display the name of the color the machine is set to
form = form.."label[1.0,4.3;Current painting color:]"..
@ -1227,6 +1496,14 @@ colormachine.main_menu_formspec = function( pos, option )
for k,v in pairs( colormachine.data ) do
if( bname == v.block and colormachine.data[ k ].installed==1) then
table.insert( found, k );
-- the block might be listed under "similar blocks"
elseif( colormachine.data[ k ].similar_blocks) then
for j,block in ipairs( colormachine.data[ k ].similar_blocks) do
if( block and block == bname ) then
table.insert( found, k );
end
end
end
end
@ -1237,8 +1514,15 @@ colormachine.main_menu_formspec = function( pos, option )
local anz_blocks = stack:get_count();
-- a block that can be colored
if( #found > 0 ) then
-- are we dealing with one of the new blocks using hardware coloring?
local stackmeta = stack:get_meta();
local palette_index = nil;
if( meta ) then
palette_index = stackmeta:get_string("palette_index");
end
-- a block (unpainted) that can be colored
if( #found > 0 and (not( palette_index) or palette_index=="" or tonumber(palette_index)==0)) then
local out_offset = 3.5-math.floor( #found / 2 );
if( out_offset < 0 ) then
@ -1267,12 +1551,33 @@ colormachine.main_menu_formspec = function( pos, option )
-- how many of these blocks can we actually paint?
local can_be_painted = 0;
if( not( minetest.setting_getbool("creative_mode") )) then
if( not( colormachine.owner_has_creative_priv( meta ))) then
can_be_painted = colormachine.calc_dyes_needed( meta, inv, math.ceil( anz_blocks / factor ), 0 );
else
can_be_painted = 99; -- an entire stack can be painted in creative mode
end
inv:set_stack( "output", i, block_name.." "..tostring( math.min( can_be_painted * factor, anz_blocks )));
local ostack = ItemStack( block_name.." "..tostring( math.min( can_be_painted * factor, anz_blocks )));
-- are we dealing with a block that uses hardware coloring and item metadata?
if( colormachine.data[v].palette
and colormachine.dye_palette[ colormachine.data[v].palette ]) then
local ometa = ostack:get_meta();
for p_nr, c_data in ipairs( colormachine.dye_palette[ colormachine.data[v].palette ] ) do
if( c_data[1]==c and c_data[2]==s and c_data[3]==g ) then
-- calculate the right palette index
local p2 = c_data[5];
if( colormachine.data[v].paramtype2=="colorfacedir" ) then
p2 = p2 * 32;
elseif( colormachine.data[v].paramtype2 == "colorwallmounted" ) then
p2 = p2 * 8;
end
-- set the right meta value
ometa:set_string( "palette_index", p2 );
end
end
end
inv:set_stack( "output", i, ostack);
p_values[ i ] = factor;
@ -1322,7 +1627,7 @@ colormachine.main_menu_formspec = function( pos, option )
-- it is possible that we are dealing with an already painted block - in that case we have to dertermie the color
local found_color_data = colormachine.get_color_from_blockname( parts[1], parts[2] );
local found_color_data = colormachine.get_color_from_blockname( nil, stack:get_name(), palette_index );
if( found_color_data.error_code ~= nil ) then
form = form.."label[2.2,3.0;"..found_color_data.error_code..".]";
return form;
@ -1357,9 +1662,89 @@ colormachine.main_menu_formspec = function( pos, option )
return form;
end
-- determines the name of the dye that was used to create the current param2 value;
-- transforms param2 to the value as suitable if dye dye_node_name is applied;
-- old_node_name is just passed on
colormachine.identify_color_by_param2_and_palette = function( dye_node_name, param2, faktor, old_node_name, palette_name )
if( not( colormachine.dye_palette[ palette_name ] )) then
return;
end
local palette = colormachine.dye_palette[ palette_name ];
local old_dye_name = nil;
local color = math.floor(( param2 - (param2%faktor))/faktor);
local new_param2 = param2;
-- data structure of entries in palette: c(olor), s(hade), g(reyscale), dye_name, param2_value, color_code
for i,c in ipairs( palette ) do
-- find out the name of the old dye that had been used
if( c[5] == color ) then -- param2_value
old_dye_name = c[4]; -- dye_name
end
-- adjust param2 to the new color
if( dye_node_name == c[4] and c[5]>-1) then
new_param2 = (new_param2%faktor) + (c[5]*faktor);
end
end
-- the color can be translated to the color-palette from the dye mod
return { possible={old_node_name}, old_dye = old_dye_name, param2 = new_param2 };
end
-- returns a list of all blocks that can be created by applying dye_node_name to the basic node of old_node_name
colormachine.get_node_name_painted = function( old_node_name, dye_node_name )
colormachine.get_node_name_painted = function( old_node_name, dye_node_name, param2 )
-- do we have a node that can be colored through setting param2?
local def = minetest.registered_nodes[ old_node_name ];
if( def and def.paramtype2 ) then
local color = nil;
local anz_color = 0;
if( def.paramtype2 == "color" ) then
-- 256 colors available
color = param2;
anz_color = 256;
elseif( def.paramtype2 == "colorwallmounted") then
-- 32 colors (5 bit)
color = math.floor(( param2 - (param2%8))/8);
anz_color = 32;
elseif( def.paramtype2 == "colorfacedir" ) then
-- 8 colors (3 bit)
color = math.floor(( param2 - (param2%32))/32);
anz_color = 8;
else
color = nil;
end
-- use normal dyes for nodes using colorfacedir_palette
if( def.palette and def.palette == "colorfacedir_palette.png" and def.paramtype2=="colorfacedir") then
return colormachine.identify_color_by_param2_and_palette( dye_node_name, param2, 32, old_node_name, def.palette );
end
if( def.palette and def.palette == "unifieddyes_palette_colorwallmounted.png" and anz_color==32) then
return colormachine.identify_color_by_param2_and_palette( dye_node_name, param2, 8, old_node_name, def.palette );
end
--[[
if( def.palette ) then
local palette_type = "-unknown-";
if( def.palette == "unifieddyes_palette.png") then
palette_type = false;
elseif( def.palette == "unifieddyes_palette_colorwallmounted.png") then
palette_type = "wallmounted";
elseif( def.palette == "unifieddyes_palette_extended.png") then
palette_type = "extended";
end
if( false ) then --TODO
local hue, sat, val = unifieddyes.get_hsv( dye_node_name );
local paletteidx, hue = unifieddyes.getpaletteidx(lastdye, palette_type)
end
end
--]]
if( color and anz_color>0) then
return { possible={old_node_name}, old_dye = dye_node_name, param2 = new_param2 };
end
end
-- classical nodes that have diffrent nodes for each color
local possible_blocks = {};
local unpainted_block = "";
local old_dye = "";
@ -1403,7 +1788,7 @@ colormachine.get_node_name_painted = function( old_node_name, dye_node_name )
-- remove paint
if( not( dye_node_name ) or dye_node_name == "") then
return {possible={unpainted_block},old_dye = old_dye};
return {possible={unpainted_block},old_dye = old_dye, param2 = param2};
end
-- decode dye name
@ -1433,13 +1818,13 @@ colormachine.get_node_name_painted = function( old_node_name, dye_node_name )
if( #found < 1 ) then
return;
end
return { possible=found, old_dye = old_dye };
return { possible=found, old_dye = old_dye, param2 = param2 };
end
colormachine.check_owner = function( pos, player )
-- only the owner can put something in
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
if( meta:get_string('owner') ~= player:get_player_name() ) then
minetest.chat_send_player( player:get_player_name(),
@ -1501,7 +1886,7 @@ end
colormachine.on_metadata_inventory_put = function( pos, listname, index, stack, player )
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
-- nothing to do if onnly a dye was inserted
@ -1559,14 +1944,14 @@ end
colormachine.on_metadata_inventory_take = function( pos, listname, index, stack, player )
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if( listname == "output" ) then
-- in creative mode, no pigments are consumed
if( minetest.setting_getbool("creative_mode") ) then
if( colormachine.owner_has_creative_priv( meta )) then
-- update the main menu
meta:set_string( 'formspec', colormachine.main_menu_formspec( pos, "analyze" ));
return;
@ -1799,8 +2184,79 @@ colormachine.mix_colors = function( inv, i, sender )
end
-- helper function for colormachine.init
-- analyzes all nodes and adds entires in colormachine.data for each combination
-- of palette, paramtype2 (if colored) and texture (front view preferred); nodes
-- which share these three values are listed as alternative nodes;
-- colormachine.data is later used to create a menu page for each entry it has
colormachine.init_hardware_colored = function()
-- identify those nodes that use the new paramtype2 color method
local nr_add = 1;
for k,def in pairs( minetest.registered_nodes ) do
-- if the node supports hardware coloring
if( def.palette
and (def.paramtype2=="color" or def.paramtype2=="colorwallmounted" or def.paramtype2=="colorfacedir")) then
local texture = "?";
-- take front view if possible
if( def.tiles and def.tiles[5] and type(def.tiles[5])=="string") then
texture = def.tiles[5];
elseif( def.tiles and def.tiles[5] and def.tiles[5].name ) then
texture = def.tiles[5].name;
elseif( def.textures and def.textures[5] and type(def.textures[5])=="string" ) then
texture = def.textures[5];
elseif( def.tiles and def.tiles[1] and type(def.tiles[1])=="string") then
texture = def.tiles[1];
elseif( def.tiles and def.tiles[1] and def.tiles[1].name ) then
texture = def.tiles[1].name;
elseif( def.textures and def.textures[1] and type(def.textures[1])=="string" ) then
texture = def.textures[1];
else
texture = "default_meseblock.png";
end
-- each combination of texture, palette and paramtype is added only once as
-- there is no point in having each stair-, stairsplus-, xconnected- or
-- whatever shape show up individually
local found = false;
-- k,def are already used in the main loop
for k2,v2 in pairs( colormachine.data ) do
if( v2.texture_name == texture
and v2.palette == def.palette
and v2.paramtype2 == def.paramtype2 ) then
found = k2;
end
end
-- add the node to the menu if the combination is not yet known
if( not( found )) then
colormachine.data[ k.."_" ] = {
nr=tonumber("2."+nr_add),
modname='default', -- TODO: might not always be correct
shades={1,1,1,1,1,1,1,1}, grey_shades={1,1,1,1,1}, u=1,
descr=k, block=k, add="", p=1,
palette = def.palette,
paramtype2 = def.paramtype2,
texture_name= texture,
installed = 1,
similar_blocks = { k }};
nr_add = nr_add + 1;
else
-- store blocks which share the same texture, palette and paramtype2
table.insert( colormachine.data[ found ].similar_blocks, k );
end
end
end
end -- done with identifying hardware colored nodes
-- this generates the formspec for all supported mods and the general colormachine.dye_management_formspec
colormachine.init = function()
-- analyze nodes that use hardware coloring and add them to the menu automaticly
colormachine.init_hardware_colored();
local liste = {};
-- create formspecs for all machines
for k,v in pairs( colormachine.data ) do
@ -1831,24 +2287,24 @@ colormachine.init = function()
end
local form = "size[14,10]"..
"list[current_player;main;1,5;8,4;]"..
"list[current_player;main;1,5.2;8,4;]"..
"label[1,0.2;"..minetest.formspec_escape('Insert dye sources here -->').."]"..
"list[current_name;refill;4,0;1,1;]"..
"label[6,0.2;Selected color:]"..
"label[0.1,1;sources:]"..
"label[0.1,2;dyes:]"..
"label[0.1,3;storage:]"..
"button[1,4;4,1;main_menu;Back to main menu]"..
"button[5,4;4,1;blocktype_menu;Show supported blocks]"..
"button[1,4.2;4,1;main_menu;Back to main menu]"..
"button[5,4.2;4,1;blocktype_menu;Show supported blocks]"..
"list[current_name;dyes;1,3;"..tostring(#colormachine.colors)..",1;]".. -- normal colors
-- remaining fields of the dyes inventory: grey colors, arranged vertically
-- (not enough space for the "dyes" label)
"label[0.1,0.6;need:]"..
"label[9.3,4.5;need:]"..
"label[10,4.5;sources:]"..
"label[12,4.5;storage:]"..
"list[current_name;dyes;12,5;1,"..tostring(#colormachine.grey_names)..";"..tostring(#colormachine.colors).."]";
"label[9.3,4.7;need:]"..
"label[10,4.7;sources:]"..
"label[12,4.7;storage:]"..
"list[current_name;dyes;12,5.2;1,"..tostring(#colormachine.grey_names)..";"..tostring(#colormachine.colors).."]";
local needed = {};
@ -1871,7 +2327,9 @@ colormachine.init = function()
form = form.."item_image["..tostring(i)..",1;1,1;"..source.."]";
-- even those colors may be additionally mixed
if( #colormachine.dye_mixes[ colormachine.colors_and_greys[ i ] ] == 2 ) then
if( colormachine.colors_and_greys[ i ]
and colormachine.dye_mixes[ colormachine.colors_and_greys[ i ] ]
and #colormachine.dye_mixes[ colormachine.colors_and_greys[ i ] ] == 2 ) then
form = form.. "button["..tostring(i-0.1)..",1.9;0.8,0.2;mix_"..colormachine.colors_and_greys[ i ]..";mix]";
end
@ -1889,7 +2347,7 @@ colormachine.init = function()
end
form = form.. "item_image["..tostring(i)..",2;1,1;"..tostring( prefix..colormachine.colors[ i ] ).."]"..
"label["..tostring(i)..",3.6;" ..tostring( colormachine.colors_and_greys[ i ] ).."]";
"label["..tostring(i)..",3.8;" ..tostring( colormachine.colors_and_greys[ i ] ).."]";
else
form = form.."label["..tostring(i+0.2)..",3;n/a]";
end
@ -1979,7 +2437,7 @@ minetest.register_node("colormachine:colormachine", {
on_construct = function(pos)
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
meta:set_string('selected_shade', 3 ); -- grey-shade
meta:set_string('selected_grey_shade', 1 );
@ -1995,16 +2453,16 @@ minetest.register_node("colormachine:colormachine", {
inv:set_size("paintless", 1); -- output slot for blocks with paint scratched off
inv:set_size("dyes", 18); -- internal storage for the dye powders
inv:set_size("extrastore",5*9); -- additional storage for dyes
--meta:set_string( 'formspec', colormachine.blocktype_menu( meta, 'white' ));
meta:set_string( 'formspec', colormachine.main_menu_formspec(pos, "analyze") );
end,
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
meta:set_string( "owner", ( placer:get_player_name() or "" ));
meta:set_string( "infotext", "Spray booth (owned by "..( meta:get_string( "owner" ) or "" )..")");
--meta:set_string( 'formspec', colormachine.blocktype_menu( meta, 'white' ));
meta:set_string( 'formspec', colormachine.main_menu_formspec(pos, "analyze") );
end,
on_receive_fields = function(pos, formname, fields, sender)
@ -2018,7 +2476,7 @@ minetest.register_node("colormachine:colormachine", {
fields.page = 0;
end
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
for k,v in pairs( fields ) do
if( k == 'main_menu' ) then
meta:set_string( 'formspec', colormachine.main_menu_formspec(pos, "analyze") );
@ -2122,7 +2580,7 @@ minetest.register_node("colormachine:colormachine", {
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
if( not( colormachine.check_owner( pos, player ))) then

View File

@ -1,5 +1,9 @@
-- This is based upon the paint_roller mod by Krock.
-- if the old color of the block can be identified and is supported, its
-- corresponding dye is added to the player's inventory;
-- if at all possible, the block is colored with the dye that is found in
-- the player's inventory to the right of the paintroller
minetest.register_tool("colormachine:paint_roller", {
description = "Paint roller",
inventory_image = "paint_roller.png",
@ -22,9 +26,9 @@ minetest.register_tool("colormachine:paint_roller", {
local stack = inv:get_stack("main", idx) --dye
local stack_name = stack:get_name()
local res = colormachine.get_node_name_painted( node_name, stack_name );
local res = colormachine.get_node_name_painted( node_name, stack_name, node.param2 );
if( not( res) or not( res.possible ) or #res.possible < 1 or (#res.possible==1 and res.possible[1]==node_name)) then
if( not( res) or not( res.possible ) or #res.possible < 1 or (#res.possible==1 and res.possible[1]==node_name and node.param2==res.param2)) then
return;
end
local index = 1;
@ -45,7 +49,7 @@ minetest.register_tool("colormachine:paint_roller", {
end
-- paint the node
minetest.set_node(pointed_thing.under, {name=res.possible[ index ], param2=node.param2})
minetest.set_node(pointed_thing.under, {name=res.possible[ index ], param2=res.param2})
--itemstack:add_wear( 65535 / 30 );
return itemstack