2017-07-30 21:37:15 +02:00
local modpath = minetest.get_modpath ( minetest.get_current_modname ( ) )
2018-08-01 11:36:19 +02:00
local function set_color ( meta , color )
meta : set_int ( " palette_index " , color )
meta : set_string ( " description " , " Dye (color # " .. color .. " ) " )
end
2017-07-30 21:37:15 +02:00
local function change_variation ( itemstack )
local meta = itemstack : get_meta ( )
local color = meta : get_int ( " palette_index " )
local variation
local new_color
if color >= 240 then
if color == 255 then
new_color = 240
else
new_color = color + 1
end
else
variation = color % 10
local hue = color - variation
new_color = ( variation + 1 ) % 10 + hue
end
2018-08-01 11:36:19 +02:00
set_color ( meta , new_color )
2017-07-30 21:37:15 +02:00
return itemstack
end
local function change_hue ( itemstack )
local meta = itemstack : get_meta ( )
local color = meta : get_int ( " palette_index " )
local new_color = color + 10
if color >= 230 then
if color == 255 then
new_color = 0
else
new_color = math.max ( color + 1 , 240 )
end
end
2018-08-01 11:36:19 +02:00
set_color ( meta , new_color )
2017-07-30 21:37:15 +02:00
return itemstack
end
minetest.register_craftitem ( " 256_dyes:dye " , {
description = " Dye " ,
groups = { } ,
inventory_image = " 256_dyes_dye.png " ,
wield_image = " 256_dyes_dye.png " ,
2018-07-30 22:51:26 +02:00
palette = " 256_dyes_palette.png " ,
2017-07-30 21:37:15 +02:00
stack_max = 99 ,
color = " #400000 " ,
on_use = change_variation ,
on_place = change_hue ,
on_secondary_use = change_hue ,
} )
local file = io.open ( modpath .. " /colors.dat " , " r " )
local raw_colors = minetest.decompress ( file : read ( " *all " ) )
file : close ( )
local colors = { }
for i = 0 , 255 do
local pos = i * 3
raw_color = raw_colors : sub ( pos + 1 , pos + 3 )
color = { raw_color : byte ( 1 , 3 ) }
colors [ i ] = color
end
local function mix ( ... )
local list = { ... }
local n = # list
local sum_c = 0
local sum_m = 0
local sum_y = 0
for _ , i in ipairs ( list ) do
r , g , b = unpack ( colors [ i ] )
local c , m , y = 255 - r , 255 - g , 255 - b
sum_c = sum_c + c ^ 2
sum_m = sum_m + m ^ 2
sum_y = sum_y + y ^ 2
end
local true_color = { math.sqrt ( sum_c / n ) , math.sqrt ( sum_m / n ) , math.sqrt ( sum_y / n ) } -- I found that calculating the quadratic mean of CMY colors gives more realistic mixes because it makes the mix more sensitive to dark colors
local min_diff = 765
local nearest = 0
for i = 0 , 255 do
local color = colors [ i ]
local c , m , y = 255 - color [ 1 ] , 255 - color [ 2 ] , 255 - color [ 3 ]
local diff = math.abs ( c - true_color [ 1 ] ) + math.abs ( m - true_color [ 2 ] ) + math.abs ( y - true_color [ 3 ] )
if diff < min_diff then
min_diff = diff
nearest = i
end
end
return nearest
end
for i = 1 , 9 do
recipe = { }
for j = 1 , i do
table.insert ( recipe , " 256_dyes:dye " )
end
minetest.register_craft ( {
type = " shapeless " ,
output = " 256_dyes:dye " ,
recipe = recipe ,
} )
end
local function dye_craft ( itemstack , player , old_craft_grid , craft_inv )
if itemstack : get_name ( ) ~= " 256_dyes:dye " then
return
end
local list_colors = { }
for _ , stack in ipairs ( old_craft_grid ) do
if not stack : is_empty ( ) then
if stack : get_name ( ) == " 256_dyes:dye " then
local meta = stack : get_meta ( )
table.insert ( list_colors , meta : get_int ( " palette_index " ) )
else
return
end
end
end
if # list_colors == 0 then
return
end
itemstack = ItemStack ( " 256_dyes:dye " .. # list_colors )
local new_color = mix ( unpack ( list_colors ) )
local meta = itemstack : get_meta ( )
2018-08-01 11:36:19 +02:00
set_color ( meta , new_color )
2017-07-30 21:37:15 +02:00
return itemstack
end
minetest.register_craft_predict ( dye_craft )
minetest.register_on_craft ( dye_craft )