From adaa109b8aaa64638be3c0298e765e5c09910253 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 31 Mar 2021 10:57:51 +0200 Subject: [PATCH] update --- mods/advtrains/advtrains/mod.conf | 2 +- mods/advtrains/advtrains/p_mesecon_iface.lua | 2 +- mods/ambience/init.lua | 23 +- mods/anvils/depends.txt | 1 + mods/anvils/tools.lua | 36 + mods/biome_lib/depends.txt | 3 - mods/biome_lib/init.lua | 50 +- mods/biome_lib/mod.conf | 2 + mods/biome_lib/search_functions.lua | 20 +- mods/carts/mod.conf | 2 +- mods/farming/food.lua | 40 + mods/farming/textures/farming_gyoza.png | Bin 0 -> 603 bytes mods/farming/textures/farming_onigiri.png | Bin 0 -> 204 bytes mods/gloopblocks/crafts.lua | 31 + mods/gloopblocks/depends.txt | 22 - mods/gloopblocks/main.lua | 25 + mods/gloopblocks/mod.conf | 2 + .../models/gloopblocks_sidewalk.obj | 119 ++ .../gloopblocks_concrete_sidewalk_overlay.png | Bin 0 -> 73 bytes .../textures/gloopblocks_packed_dirt.png | Bin 0 -> 417 bytes .../homedecor_bathroom/init.lua | 4 +- .../homedecor_common/nodeboxes.lua | 7 +- .../homedecor_furniture/init.lua | 254 --- .../homedecor_furniture_medieval/init.lua | 18 + .../homedecor_kitchen/init.lua | 279 ++- .../models/homedecor_kitchen_cabinet.obj | 50 + .../models/homedecor_kitchen_cabinet_half.obj | 52 + .../models/homedecor_kitchen_sink.obj | 265 ++- .../homedecor_kitchen_cabinet_bevel.png | Bin 87 -> 112 bytes ...omedecor_kitchen_cabinet_colored_front.png | Bin 0 -> 244 bytes ...cor_kitchen_cabinet_colored_front_half.png | Bin 0 -> 190 bytes ...hen_cabinet_colored_front_with_drawers.png | Bin 0 -> 254 bytes .../homedecor_kitchen_cabinet_front.png | Bin 315 -> 532 bytes .../homedecor_kitchen_cabinet_front_half.png | Bin 265 -> 381 bytes ...cor_kitchen_cabinet_front_with_drawers.png | Bin 0 -> 561 bytes .../homedecor_kitchen_cabinet_half_bevel.png | Bin 0 -> 109 bytes .../textures/homedecor_kitchen_sink_top.png | Bin 358 -> 286 bytes .../homedecor_lighting/init.lua | 8 + .../homedecor_tables/misc.lua | 357 ++-- .../homedecor_tables/mod.conf | 1 + .../models/homedecor_table_large_square.obj | 107 + .../models/homedecor_table_small_round.obj | 1754 ++++++++++++++--- .../models/homedecor_table_small_square.obj | 180 +- .../textures/homedecor_glass_face_clean.png | Bin 74 -> 0 bytes ...es.png => homedecor_glass_table_edges.png} | Bin .../homedecor_glass_table_large_inv.png | Bin 2457 -> 0 bytes .../homedecor_glass_table_large_square.png | Bin 0 -> 604 bytes ...homedecor_glass_table_large_square_inv.png | Bin 0 -> 315 bytes .../homedecor_glass_table_large_tb.png | Bin 146 -> 0 bytes .../homedecor_glass_table_small_round.png | Bin 241 -> 597 bytes .../homedecor_glass_table_small_round_inv.png | Bin 3865 -> 713 bytes .../homedecor_glass_table_small_square.png | Bin 358 -> 642 bytes ...homedecor_glass_table_small_square_inv.png | Bin 3938 -> 334 bytes .../textures/homedecor_table_legs_brass.png | Bin 331 -> 476 bytes .../textures/homedecor_table_legs_wood.png | Bin 0 -> 357 bytes .../homedecor_table_legs_wrought_iron.png | Bin 325 -> 439 bytes .../homedecor_utility_table_edges.png | Bin 465 -> 0 bytes .../textures/homedecor_utility_table_legs.png | Bin 338 -> 0 bytes .../homedecor_utility_table_legs_inv.png | Bin 4371 -> 0 bytes .../textures/homedecor_utility_table_tb.png | Bin 576 -> 0 bytes .../textures/homedecor_wood_table_edges.png | Bin 0 -> 204 bytes .../homedecor_wood_table_large_edges.png | Bin 465 -> 0 bytes .../homedecor_wood_table_large_inv.png | Bin 4095 -> 0 bytes .../homedecor_wood_table_large_square.png | Bin 0 -> 1217 bytes .../homedecor_wood_table_large_square_inv.png | Bin 0 -> 652 bytes .../homedecor_wood_table_large_tb.png | Bin 529 -> 0 bytes .../homedecor_wood_table_small_round.png | Bin 573 -> 2294 bytes .../homedecor_wood_table_small_round_inv.png | Bin 5201 -> 2007 bytes .../homedecor_wood_table_small_square.png | Bin 982 -> 1467 bytes .../homedecor_wood_table_small_square_inv.png | Bin 4200 -> 901 bytes mods/skinsdb/formspecs.lua | 99 +- mods/skinsdb/mod.conf | 1 + mods/skinsdb/textures/ui_misc_form.png | Bin 6177 -> 0 bytes mods/skinsdb/unified_inventory_page.lua | 19 +- mods/unified_inventory/init.lua | 4 + mods/unified_inventory/internal.lua | 13 +- mods/unifieddyes/airbrush.lua | 498 +++++ mods/unifieddyes/aliases.lua | 23 + mods/unifieddyes/api.lua | 494 +++++ mods/unifieddyes/color-tables.lua | 237 +++ mods/unifieddyes/dyes-crafting.lua | 309 +++ mods/unifieddyes/init.lua | 1568 +-------------- 82 files changed, 4416 insertions(+), 2565 deletions(-) delete mode 100644 mods/biome_lib/depends.txt create mode 100644 mods/farming/textures/farming_gyoza.png create mode 100644 mods/farming/textures/farming_onigiri.png delete mode 100644 mods/gloopblocks/depends.txt create mode 100644 mods/gloopblocks/models/gloopblocks_sidewalk.obj create mode 100644 mods/gloopblocks/textures/gloopblocks_concrete_sidewalk_overlay.png create mode 100644 mods/gloopblocks/textures/gloopblocks_packed_dirt.png create mode 100644 mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet.obj create mode 100644 mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet_half.obj create mode 100644 mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_colored_front.png create mode 100644 mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_colored_front_half.png create mode 100644 mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_colored_front_with_drawers.png create mode 100644 mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front_with_drawers.png create mode 100644 mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_half_bevel.png create mode 100644 mods/homedecor_modpack/homedecor_tables/models/homedecor_table_large_square.obj delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_face_clean.png rename mods/homedecor_modpack/homedecor_tables/textures/{homedecor_glass_table_large_edges.png => homedecor_glass_table_edges.png} (100%) delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_large_inv.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_large_square.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_large_square_inv.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_large_tb.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_table_legs_wood.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_edges.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs_inv.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_tb.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_edges.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_edges.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_inv.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_square.png create mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_square_inv.png delete mode 100644 mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_tb.png delete mode 100644 mods/skinsdb/textures/ui_misc_form.png create mode 100644 mods/unifieddyes/airbrush.lua create mode 100644 mods/unifieddyes/aliases.lua create mode 100644 mods/unifieddyes/api.lua create mode 100644 mods/unifieddyes/color-tables.lua create mode 100644 mods/unifieddyes/dyes-crafting.lua diff --git a/mods/advtrains/advtrains/mod.conf b/mods/advtrains/advtrains/mod.conf index 027e08a1..5808d1a7 100644 --- a/mods/advtrains/advtrains/mod.conf +++ b/mods/advtrains/advtrains/mod.conf @@ -4,4 +4,4 @@ description=Core system for realistic trains in Minetest author=orwell96 depends=serialize_lib -optional_depends=mesecons,digtron +optional_depends=mesecons,mesecons_switch,digtron diff --git a/mods/advtrains/advtrains/p_mesecon_iface.lua b/mods/advtrains/advtrains/p_mesecon_iface.lua index 0eef96ae..33fcecda 100644 --- a/mods/advtrains/advtrains/p_mesecon_iface.lua +++ b/mods/advtrains/advtrains/p_mesecon_iface.lua @@ -1,7 +1,7 @@ -- p_mesecon_iface.lua -- Mesecons interface by overriding the switch -if not mesecon then return end +if minetest.get_modpath("mesecons_switch") == nil then return end minetest.override_item("mesecons_switch:mesecon_switch_off", { groups = { diff --git a/mods/ambience/init.lua b/mods/ambience/init.lua index 1f7bb4f0..f911d378 100644 --- a/mods/ambience/init.lua +++ b/mods/ambience/init.lua @@ -200,17 +200,17 @@ minetest.register_globalstep(function(dtime) ok = true -- everything starts off ok - -- stop current sound if another set active or gain changed + -- are we playing something already? if playing[player_name] and playing[player_name].handler then + -- stop current sound if another set active or gain changed if playing[player_name].set ~= set_name - or (playing[player_name].set == set_name - and playing[player_name].gain ~= MORE_GAIN) then + or playing[player_name].gain ~= MORE_GAIN then ---print ("-- change stop", set_name, playing[player_name].old_handler) +--print ("-- change stop", set_name, playing[player_name].handler) - minetest.sound_stop(playing[player_name].old_handler) + minetest.sound_stop(playing[player_name].handler) playing[player_name].set = nil playing[player_name].handler = nil @@ -220,11 +220,9 @@ minetest.register_globalstep(function(dtime) end end - -- set random chance and reset seed + -- set random chance chance = random(1, 1000) - math.randomseed(tod + chance) - -- if chance is lower than set frequency then select set if ok and set_name and chance < sound_sets[set_name].frequency then @@ -249,8 +247,7 @@ minetest.register_globalstep(function(dtime) -- set what player is currently listening to playing[player_name] = { - set = set_name, gain = MORE_GAIN, - handler = handler, old_handler = handler + set = set_name, gain = MORE_GAIN, handler = handler } -- set timer to stop sound @@ -261,17 +258,15 @@ minetest.register_globalstep(function(dtime) -- make sure we are stopping same sound we started if playing[player_name] and playing[player_name].handler - and playing[player_name].old_handler == handler then + and playing[player_name].handler == handler then --print("-- timed stop", set_name, handler) - --minetest.sound_stop(playing[player_name].handler) minetest.sound_stop(handler) -- reset player variables and backup handler playing[player_name] = { - set = nil, gain = nil, - handler = nil, old_handler = nil + set = nil, gain = nil, handler = nil } end end) diff --git a/mods/anvils/depends.txt b/mods/anvils/depends.txt index 1ab50c5d..37b0856b 100644 --- a/mods/anvils/depends.txt +++ b/mods/anvils/depends.txt @@ -5,3 +5,4 @@ ethereal? moreores? 3d_armor? xanadu? +mobs? diff --git a/mods/anvils/tools.lua b/mods/anvils/tools.lua index 7375fe4a..b01708d4 100644 --- a/mods/anvils/tools.lua +++ b/mods/anvils/tools.lua @@ -141,7 +141,43 @@ if minetest.get_modpath("3d_armor") then end end +if minetest.get_modpath("shields") then + + if armor.materials.steel then + add_tool("shields:shield_steel", "default:steel_ingot", 7) + end + + if armor.materials.bronze then + add_tool("shields:shield_bronze", "default:bronze_ingot", 7) + end + + if armor.materials.diamond then + add_tool("shields:shield_diamond", "default:diamond", 7) + end + + if armor.materials.gold then + add_tool("shields:shield_gold", "default:gold_ingot", 7) + end + + if armor.materials.mithril then + add_tool("shields:shield_mithril", "moreores:mithril_ingot", 7) + end + + if armor.materials.crystal then + add_tool("shields:shield_crystal", "ethereal:crystal_ingot", 7) + end +end + +if minetest.get_modpath("mobs_monster") then + add_tool("mobs:pick_lava", "mobs:lava_orb", 3, true) +end + -- Xanadu mod if minetest.get_modpath("xanadu") then add_tool("xanadu:axe_super", "default:diamond", 18, true) + add_tool("mobs:pick_lava", "mobs:lava_orb", 3, true) + add_tool("xanadu:helmet_ccrystal", "ethereal:crystal_ingot", 5) + add_tool("xanadu:chestplate_ccrystal", "ethereal:crystal_ingot", 8) + add_tool("xanadu:leggings_ccrystal", "ethereal:crystal_ingot", 7) + add_tool("xanadu:boots_ccrystal", "ethereal:crystal_ingot", 4) end diff --git a/mods/biome_lib/depends.txt b/mods/biome_lib/depends.txt deleted file mode 100644 index c48fe0d0..00000000 --- a/mods/biome_lib/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -default -intllib? - diff --git a/mods/biome_lib/init.lua b/mods/biome_lib/init.lua index b8635b9d..aefc9f1b 100644 --- a/mods/biome_lib/init.lua +++ b/mods/biome_lib/init.lua @@ -1,4 +1,4 @@ --- Biome library mod by Vanessa Ezekowitz +-- Biome library mod by VanessaE -- -- I got the temperature map idea from "hmmmm", values used for it came from -- Splizard's snow mod. @@ -395,7 +395,7 @@ end -- a surface during the initial map read stage. function biome_lib:generate_block_with_air_checking() - if #biome_lib.blocklist_aircheck == 0 then + if not biome_lib.blocklist_aircheck[1] then return end @@ -407,30 +407,13 @@ function biome_lib:generate_block_with_air_checking() local blockhash = minetest.hash_node_position(minp) - if not biome_lib.surface_nodes_aircheck.blockhash then - - if type(minetest.find_nodes_in_area_under_air) == "function" then -- use newer API call - biome_lib.surface_nodes_aircheck.blockhash = - minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck) - else - local search_area = minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_aircheck) - - -- search the generated block for air-bounded surfaces the slow way. - - biome_lib.surface_nodes_aircheck.blockhash = {} - - for i = 1, #search_area do - local pos = search_area[i] - local p_top = { x=pos.x, y=pos.y+1, z=pos.z } - if minetest.get_node(p_top).name == "air" then - biome_lib.surface_nodes_aircheck.blockhash[#biome_lib.surface_nodes_aircheck.blockhash + 1] = pos - end - end - end + if not biome_lib.surface_nodes_aircheck.blockhash then -- read it into the block cache + biome_lib.surface_nodes_aircheck.blockhash = + minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck) biome_lib.actioncount_aircheck.blockhash = 1 else - if biome_lib.actioncount_aircheck.blockhash <= #biome_lib.actionslist_aircheck then + if biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash] then -- [1] is biome, [2] is node/function/model biome_lib:populate_surfaces( biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][1], @@ -438,10 +421,9 @@ function biome_lib:generate_block_with_air_checking() biome_lib.surface_nodes_aircheck.blockhash, true) biome_lib.actioncount_aircheck.blockhash = biome_lib.actioncount_aircheck.blockhash + 1 else - if biome_lib.surface_nodes_aircheck.blockhash then - table.remove(biome_lib.blocklist_aircheck, 1) - biome_lib.surface_nodes_aircheck.blockhash = nil - end + table.remove(biome_lib.blocklist_aircheck, 1) + biome_lib.surface_nodes_aircheck.blockhash = nil + biome_lib.actioncount_aircheck.blockhash = nil end end end @@ -450,7 +432,7 @@ end -- checking for air during the initial map read stage. function biome_lib:generate_block_no_aircheck() - if #biome_lib.blocklist_no_aircheck == 0 then + if not biome_lib.blocklist_no_aircheck[1] then return end @@ -460,25 +442,21 @@ function biome_lib:generate_block_no_aircheck() local blockhash = minetest.hash_node_position(minp) if not biome_lib.surface_nodes_no_aircheck.blockhash then - - -- directly read the block to be searched into the chunk cache - biome_lib.surface_nodes_no_aircheck.blockhash = minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck) biome_lib.actioncount_no_aircheck.blockhash = 1 else - if biome_lib.actioncount_no_aircheck.blockhash <= #biome_lib.actionslist_no_aircheck then + if biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash] then biome_lib:populate_surfaces( biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][1], biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][2], biome_lib.surface_nodes_no_aircheck.blockhash, false) biome_lib.actioncount_no_aircheck.blockhash = biome_lib.actioncount_no_aircheck.blockhash + 1 else - if biome_lib.surface_nodes_no_aircheck.blockhash then - table.remove(biome_lib.blocklist_no_aircheck, 1) - biome_lib.surface_nodes_no_aircheck.blockhash = nil - end + table.remove(biome_lib.blocklist_no_aircheck, 1) + biome_lib.surface_nodes_no_aircheck.blockhash = nil + biome_lib.actioncount_no_aircheck.blockhash = nil end end end diff --git a/mods/biome_lib/mod.conf b/mods/biome_lib/mod.conf index 033b72e9..b3312f63 100644 --- a/mods/biome_lib/mod.conf +++ b/mods/biome_lib/mod.conf @@ -1,2 +1,4 @@ name = biome_lib min_minetest_version = 5.2.0 +depends = default +optional_depends = intllib diff --git a/mods/biome_lib/search_functions.lua b/mods/biome_lib/search_functions.lua index d665b5fe..1f11476d 100644 --- a/mods/biome_lib/search_functions.lua +++ b/mods/biome_lib/search_functions.lua @@ -52,9 +52,23 @@ function biome_lib:find_open_side(pos) return nil end --- "Record" the chunks being generated by the core mapgen +-- "Record" the map chunks being generated by the core mapgen, +-- split into individual mapblocks to reduce lag minetest.register_on_generated(function(minp, maxp, blockseed) - biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { minp, maxp } - biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { minp, maxp } + for x = 0, 5 do + local minx = minp.x + x*16 + for y = 0, 5 do + local miny = minp.y + y*16 + for z = 0, 5 do + local minz = minp.z + z*16 + + local bmin = {x=minx, y=miny, z=minz} + local bmax = {x=minx + 15, y=miny + 15, z=minz + 15} + + biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { bmin, bmax } + biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { bmin, bmax } + end + end + end end) diff --git a/mods/carts/mod.conf b/mods/carts/mod.conf index 0eab35c3..63347d20 100644 --- a/mods/carts/mod.conf +++ b/mods/carts/mod.conf @@ -1,4 +1,4 @@ name = carts description = Carts (formerly boost_cart) depends = default, player_api -optional_depends = dungeon_loot +optional_depends = dungeon_loot, mesecons diff --git a/mods/farming/food.lua b/mods/farming/food.lua index 1287b59f..2a1c2862 100644 --- a/mods/farming/food.lua +++ b/mods/farming/food.lua @@ -556,6 +556,7 @@ minetest.register_craft({ "group:food_egg", "group:food_egg", "farming:vanilla_extract" }, replacements = { + {"cucina_vegana:soy_milk", "vessels:drinking_glass"}, {"group:food_milk", "bucket:bucket_empty"}, {"farming:vanilla_extract", "vessels:glass_bottle"} } @@ -599,3 +600,42 @@ minetest.register_craft({ {"farming:pot", "farming:pot"}, } }) + +-- Onigiri + +minetest.register_craftitem("farming:onigiri", { + description = S("Onirigi"), + inventory_image = "farming_onigiri.png", + on_use = minetest.item_eat(2), + groups = {flammable = 2}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:onigiri", + recipe = { + "group:food_rice", "group:food_rice", "group:food_seaweed", "group:food_salt" + } +}) + +-- Gyoza + +minetest.register_craftitem("farming:gyoza", { + description = S("Gyoza"), + inventory_image = "farming_gyoza.png", + on_use = minetest.item_eat(4), + groups = {flammable = 2}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:gyoza 4", + recipe = { + "group:food_cabbage", "group:food_garlic_clove", "group:food_onion", + "group:food_meat_raw", "group:food_salt", "group:food_skillet", + "group:food_flour" + }, + replacements = { + {"group:food_skillet", "farming:skillet"} + } +}) diff --git a/mods/farming/textures/farming_gyoza.png b/mods/farming/textures/farming_gyoza.png new file mode 100644 index 0000000000000000000000000000000000000000..2005e7991cde4c5898613b7db93ab00c1981a26c GIT binary patch literal 603 zcmV-h0;K(kP)qCqI-iVl(2|?CGOwlW4Kp*+9WsI(5 z$(hM3Q!>i~Dw|S3c!4S#f(NB4nHjYy?ZJbrOs}%mNE8vjYy-$!-bhzk5~%M{M=TWv zbHzDh! z4GR*YbjM>4!2`bUAS>6H*My~^e3ZytL;T#kBr)`LaLQQSqW$PbG!Uk+{08lTXO zuB3X*gACS7jkMQTR&0Cal}m9TL9T>|j{__#wvD7qQ-6gdI_hZ;rL538PpwPmsAD9a zs=SHG+Z3J$qaY;CFB;U(roBY?8loC6L2ua0L~(F_>~1vNcr#QQd*c>j(eU@0q z^}3+wVhB9w@G61v$?EN8<}8jiO{|_9dz*}Wo6khc yxX8{~q*J9FazuJE5eu=u9v#(CxQ8hd(`TmwDPc zKa4?SP`aE+x{_1Iah&Y6qx43~2S-R4rYQq7`zG`QW7u^;@Qeg2zg$KUiFW&w7IOFH z=K1$a7D8)TZwe$_xzf_qh5T`-A@m90_0Mem2Gf)hszN1JtsD{-S_#d8#wD( zxU)3?_5-Zk+d9Q4PDgJFrSg;szkYL&z#Y!>yqsEV$`9@j=MbX&*(f3`D-$AcN@b-l zZ 0 then -- slab starting from -z - return { -0.5, -0.5, -0.5, 0.5, 0.5, -0.5+depth } + return { -0.5, -0.5, -0.5+s, 0.5, 0.5, -0.5+depth+s } else -- slab starting from +z (z1=0.5-(-depth)) - return { -0.5, -0.5, 0.5+depth, 0.5, 0.5, 0.5 } + return { -0.5, -0.5, 0.5+depth+s, 0.5, 0.5, 0.5+s } end end, bar_y = function(radius) return {-radius, -0.5, -radius, radius, 0.5, radius} end, diff --git a/mods/homedecor_modpack/homedecor_furniture/init.lua b/mods/homedecor_modpack/homedecor_furniture/init.lua index 5c317ddb..bcb9dea4 100644 --- a/mods/homedecor_modpack/homedecor_furniture/init.lua +++ b/mods/homedecor_modpack/homedecor_furniture/init.lua @@ -1,38 +1,5 @@ local S = minetest.get_translator("homedecor_furniture") -local table_colors = { - { "", S("Table"), homedecor.plain_wood }, - { "_mahogany", S("Mahogany Table"), homedecor.mahogany_wood }, - { "_white", S("White Table"), homedecor.white_wood } -} - -for _, t in ipairs(table_colors) do - local suffix, desc, texture = unpack(t) - - homedecor.register("table"..suffix, { - description = desc, - tiles = { texture }, - node_box = { - type = "fixed", - fixed = { - { -0.4, -0.5, -0.4, -0.3, 0.4, -0.3 }, - { 0.3, -0.5, -0.4, 0.4, 0.4, -0.3 }, - { -0.4, -0.5, 0.3, -0.3, 0.4, 0.4 }, - { 0.3, -0.5, 0.3, 0.4, 0.4, 0.4 }, - { -0.5, 0.4, -0.5, 0.5, 0.5, 0.5 }, - { -0.4, -0.2, -0.3, -0.3, -0.1, 0.3 }, - { 0.3, -0.2, -0.4, 0.4, -0.1, 0.3 }, - { -0.3, -0.2, -0.4, 0.4, -0.1, -0.3 }, - { -0.3, -0.2, 0.3, 0.3, -0.1, 0.4 }, - }, - }, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - }) -end - - - local ob_cbox = { type = "fixed", fixed = { -0.5, -0.5, 0, 0.5, 0.5, 0.5 } @@ -69,224 +36,3 @@ homedecor.register("wall_shelf", { } } }) - --- Crafts - - -minetest.register_craft({ - output = "homedecor:table", - recipe = { - { "group:wood","group:wood", "group:wood" }, - { "group:stick", "", "group:stick" }, - }, -}) - -minetest.register_craft({ - type = "shapeless", - output = "homedecor:table_mahogany", - recipe = { - "homedecor:table", - "dye:brown", - }, -}) - -minetest.register_craft({ - type = "shapeless", - output = "homedecor:table_mahogany", - recipe = { - "homedecor:table", - "unifieddyes:dark_orange", - }, -}) - -minetest.register_craft({ - type = "shapeless", - output = "homedecor:table_white", - recipe = { - "homedecor:table", - "dye:white", - }, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "homedecor:table", - burntime = 30, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "homedecor:table_mahogany", - burntime = 30, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "homedecor:table_white", - burntime = 30, -}) - -minetest.register_craft({ - output = "homedecor:standing_lamp_off", - recipe = { - {"homedecor:table_lamp_off"}, - {"group:stick"}, - {"group:stick"}, - }, -}) - -unifieddyes.register_color_craft({ - output = "homedecor:standing_lamp_off", - palette = "extended", - type = "shapeless", - neutral_node = "homedecor:standing_lamp_off", - recipe = { - "NEUTRAL_NODE", - "MAIN_DYE" - } -}) - -minetest.register_craft({ - type = "fuel", - recipe = "homedecor:table_lamp_off", - burntime = 10, -}) - -minetest.register_craft({ - output = "homedecor:table_lamp_off", - recipe = { - { "wool:white", "default:torch", "wool:white"}, - { "", "group:stick", ""}, - { "", "stairs:slab_wood", "" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:table_lamp_off", - recipe = { - { "cottages:wool", "default:torch", "cottages:wool"}, - { "", "group:stick", ""}, - { "", "stairs:slab_wood", "" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:table_lamp_off", - recipe = { - { "wool:white", "default:torch", "wool:white"}, - { "", "group:stick", ""}, - { "", "moreblocks:slab_wood", "" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:table_lamp_off", - recipe = { - { "cottages:wool", "default:torch", "cottages:wool"}, - { "", "group:stick", ""}, - { "", "moreblocks:slab_wood", "" }, - }, -}) - -unifieddyes.register_color_craft({ - output = "homedecor:table_lamp_off", - palette = "extended", - type = "shapeless", - neutral_node = "homedecor:table_lamp_off", - recipe = { - "NEUTRAL_NODE", - "MAIN_DYE" - } -}) - -minetest.register_craft({ - output = "homedecor:toilet", - recipe = { - { "","","bucket:bucket_water"}, - { "group:marble","group:marble", "group:marble" }, - { "", "bucket:bucket_empty", "" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:sink", - recipe = { - { "group:marble","bucket:bucket_empty", "group:marble" }, - { "", "group:marble", "" } - }, -}) - -minetest.register_craft({ - output = "homedecor:taps", - recipe = { - { "default:steel_ingot","bucket:bucket_water", "default:steel_ingot" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:taps_brass", - recipe = { - { "technic:brass_ingot","bucket:bucket_water", "technic:brass_ingot" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:shower_tray", - recipe = { - { "group:marble","bucket:bucket_empty", "group:marble" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:shower_head", - recipe = { - {"default:steel_ingot", "bucket:bucket_water"}, - }, -}) - -minetest.register_craft({ - output = "homedecor:bathtub_clawfoot_brass_taps", - recipe = { - { "homedecor:taps_brass", "", "" }, - { "group:marble", "", "group:marble" }, - {"default:steel_ingot", "group:marble", "default:steel_ingot"}, - }, -}) - -minetest.register_craft({ - output = "homedecor:bathtub_clawfoot_chrome_taps", - recipe = { - { "homedecor:taps", "", "" }, - { "group:marble", "", "group:marble" }, - {"default:steel_ingot", "group:marble", "default:steel_ingot"}, - }, -}) - -minetest.register_craft({ - output = "homedecor:bars 6", - recipe = { - { "default:steel_ingot","default:steel_ingot","default:steel_ingot" }, - { "homedecor:pole_wrought_iron","homedecor:pole_wrought_iron","homedecor:pole_wrought_iron" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:L_binding_bars 3", - recipe = { - { "homedecor:bars","" }, - { "homedecor:bars","homedecor:bars" }, - }, -}) - -minetest.register_craft({ - output = "homedecor:torch_wall 10", - recipe = { - { "default:coal_lump" }, - { "default:steel_ingot" }, - }, -}) - --- Aliases for 3dforniture mod. - -minetest.register_alias("3dforniture:table", "homedecor:table") -minetest.register_alias('table', 'homedecor:table') diff --git a/mods/homedecor_modpack/homedecor_furniture_medieval/init.lua b/mods/homedecor_modpack/homedecor_furniture_medieval/init.lua index efb331f0..7db474ac 100644 --- a/mods/homedecor_modpack/homedecor_furniture_medieval/init.lua +++ b/mods/homedecor_modpack/homedecor_furniture_medieval/init.lua @@ -57,6 +57,24 @@ homedecor.register("chains", { sounds = default.node_sound_stone_defaults(), }) +-- Crafts + +minetest.register_craft({ + output = "homedecor:bars 6", + recipe = { + { "default:steel_ingot","default:steel_ingot","default:steel_ingot" }, + { "homedecor:pole_wrought_iron","homedecor:pole_wrought_iron","homedecor:pole_wrought_iron" }, + }, +}) + +minetest.register_craft({ + output = "homedecor:L_binding_bars 3", + recipe = { + { "homedecor:bars","" }, + { "homedecor:bars","homedecor:bars" }, + }, +}) + minetest.register_alias("3dforniture:bars", "homedecor:bars") minetest.register_alias("3dforniture:L_binding_bars", "homedecor:L_binding_bars") minetest.register_alias("3dforniture:chains", "homedecor:chains") diff --git a/mods/homedecor_modpack/homedecor_kitchen/init.lua b/mods/homedecor_modpack/homedecor_kitchen/init.lua index 7197b8a6..8b9ee66a 100644 --- a/mods/homedecor_modpack/homedecor_kitchen/init.lua +++ b/mods/homedecor_modpack/homedecor_kitchen/init.lua @@ -137,43 +137,159 @@ homedecor.register("dishwasher_"..m, { end local cabinet_sides = "(default_wood.png^[transformR90)^homedecor_kitchen_cabinet_bevel.png" -local cabinet_bottom = "(default_wood.png^[colorize:#000000:100)" - .."^(homedecor_kitchen_cabinet_bevel.png^[colorize:#46321580)" +local cabinet_sides_colored = "(homedecor_generic_wood_plain.png^[transformR90)^homedecor_kitchen_cabinet_bevel.png" + +local ic_cabinet_sides = string.gsub(cabinet_sides, "%^", "&") +local ic_cabinet_sides_colored = string.gsub(cabinet_sides_colored, "%^", "&") + +local cabinet_bottom = "(default_wood.png^[colorize:#000000:100)^homedecor_kitchen_cabinet_bevel.png" +local cabinet_bottom_colored = "homedecor_generic_wood_plain.png^homedecor_kitchen_cabinet_bevel.png" local function N_(x) return x end local counter_materials = { "", N_("granite"), N_("marble"), N_("steel") } +homedecor.kitchen_convert_nodes = {} + for _, mat in ipairs(counter_materials) do local desc = S("Kitchen Cabinet") + local desc2 = S("Kitchen Cabinet with drawers") local material = "" if mat ~= "" then desc = S("Kitchen Cabinet (@1 top)", S(mat)) + desc2 = S("Kitchen Cabinet with drawers (@1 top)", S(mat)) material = "_"..mat end - homedecor.register("kitchen_cabinet"..material, { + homedecor.register("kitchen_cabinet_colorable"..material, { description = desc, - tiles = { 'homedecor_kitchen_cabinet_top'..material..'.png', - cabinet_bottom, - cabinet_sides, - cabinet_sides, - cabinet_sides, - 'homedecor_kitchen_cabinet_front.png'}, - groups = { snappy = 3 }, + tiles = { + 'homedecor_kitchen_cabinet_top'..material..'.png', + cabinet_bottom, + cabinet_sides, + cabinet_sides, + cabinet_sides, + 'homedecor_kitchen_cabinet_front.png^homedecor_kitchen_cabinet_bevel.png' + }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_cabinet_top"..material..".png" + .."{homedecor_kitchen_cabinet_front.png" + .."{"..ic_cabinet_sides, + mesh = "homedecor_kitchen_cabinet.obj", + paramtype2 = "wallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + airbrush_replacement_node = "homedecor:kitchen_cabinet_colored"..material, + place_param2 = 0, + groups = { snappy = 3, ud_param2_colorable = 1}, sounds = default.node_sound_wood_defaults(), infotext=S("Kitchen Cabinet"), inventory = { size=24, lockable=true, }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end }) + + homedecor.register("kitchen_cabinet_colored"..material, { + description = desc, + tiles = { + {name = 'homedecor_kitchen_cabinet_top'..material..'.png', color = 0xFFFFFFFF}, + {name = cabinet_bottom, color = 0xFFFFFFFF }, + cabinet_sides_colored, + cabinet_sides_colored, + cabinet_sides_colored, + 'homedecor_kitchen_cabinet_colored_front.png^homedecor_kitchen_cabinet_bevel.png' + }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_cabinet_top"..material..".png" + .."{homedecor_kitchen_cabinet_front.png" + .."{"..ic_cabinet_sides_colored, + mesh = "homedecor_kitchen_cabinet.obj", + paramtype2 = "colorwallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + groups = { snappy = 3, ud_param2_colorable = 1, not_in_creative_inventory = 1 }, + sounds = default.node_sound_wood_defaults(), + infotext=S("Kitchen Cabinet"), + inventory = { + size=24, + lockable=true, + }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end + }) + + homedecor.register("kitchen_cabinet_colorable_with_drawers"..material, { + description = desc2, + tiles = { + 'homedecor_kitchen_cabinet_top'..material..'.png', + cabinet_bottom, + cabinet_sides, + cabinet_sides, + cabinet_sides, + 'homedecor_kitchen_cabinet_front_with_drawers.png^homedecor_kitchen_cabinet_bevel.png' + }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_cabinet_top"..material..".png" + .."{homedecor_kitchen_cabinet_front_with_drawers.png" + .."{"..ic_cabinet_sides, + mesh = "homedecor_kitchen_cabinet.obj", + paramtype2 = "wallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + airbrush_replacement_node = "homedecor:kitchen_cabinet_colored_with_drawers"..material, + groups = { snappy = 3, ud_param2_colorable = 1}, + sounds = default.node_sound_wood_defaults(), + infotext=S("Kitchen Cabinet with drawers"), + inventory = { + size=24, + lockable=true, + }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end + }) + + homedecor.register("kitchen_cabinet_colored_with_drawers"..material, { + description = desc2, + tiles = { + {name = 'homedecor_kitchen_cabinet_top'..material..'.png', color = 0xFFFFFFFF}, + {name = cabinet_bottom, color = 0xFFFFFFFF }, + cabinet_sides_colored, + cabinet_sides_colored, + cabinet_sides_colored, + 'homedecor_kitchen_cabinet_colored_front_with_drawers.png^homedecor_kitchen_cabinet_bevel.png' + }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_cabinet_top"..material..".png" + .."{homedecor_kitchen_cabinet_colored_front_with_drawers.png" + .."{"..ic_cabinet_sides_colored, + mesh = "homedecor_kitchen_cabinet.obj", + paramtype2 = "colorwallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + groups = { snappy = 3, ud_param2_colorable = 1, not_in_creative_inventory = 1 }, + sounds = default.node_sound_wood_defaults(), + infotext=S("Kitchen Cabinet with drawers"), + inventory = { + size=24, + lockable=true, + }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end + }) + + homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet"..material + homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet_locked"..material + end -local kitchen_cabinet_half_box = homedecor.nodebox.slab_y(0.5, 0.5) -homedecor.register("kitchen_cabinet_half", { +local kitchen_cabinet_half_box = homedecor.nodebox.slab_z(0.5, 0.5) + +homedecor.register("kitchen_cabinet_colorable_half", { description = S('Half-height Kitchen Cabinet (on ceiling)'), tiles = { cabinet_sides, @@ -181,29 +297,77 @@ homedecor.register("kitchen_cabinet_half", { cabinet_sides, cabinet_sides, cabinet_sides, - 'homedecor_kitchen_cabinet_front_half.png' + 'homedecor_kitchen_cabinet_front_half.png^homedecor_kitchen_cabinet_half_bevel.png' }, + mesh = "homedecor_kitchen_cabinet_half.obj", + paramtype2 = "wallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + airbrush_replacement_node = "homedecor:kitchen_cabinet_colored_half", + place_param2 = 0, selection_box = kitchen_cabinet_half_box, node_box = kitchen_cabinet_half_box, - groups = { snappy = 3 }, + groups = { snappy = 3, ud_param2_colorable = 1 }, sounds = default.node_sound_wood_defaults(), infotext=S("Kitchen Cabinet"), inventory = { size=12, lockable=true, }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end }) -homedecor.register("kitchen_cabinet_with_sink", { +homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet_half" +homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet_half_locked" + +homedecor.register("kitchen_cabinet_colored_half", { + description = S('Half-height Kitchen Cabinet (on ceiling)'), + tiles = { + { name = cabinet_sides, color = 0xFFFFFFFF }, + cabinet_bottom_colored, + cabinet_sides_colored, + cabinet_sides_colored, + cabinet_sides_colored, + 'homedecor_kitchen_cabinet_colored_front_half.png^homedecor_kitchen_cabinet_half_bevel.png' + }, + mesh = "homedecor_kitchen_cabinet_half.obj", + paramtype2 = "colorwallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + selection_box = kitchen_cabinet_half_box, + node_box = kitchen_cabinet_half_box, + groups = { snappy = 3, ud_param2_colorable = 1, not_in_creative_inventory = 1 }, + sounds = default.node_sound_wood_defaults(), + infotext=S("Kitchen Cabinet"), + inventory = { + size=12, + lockable=true, + }, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end +}) + +homedecor.register("kitchen_cabinet_colorable_with_sink", { description = S("Kitchen Cabinet with sink"), mesh = "homedecor_kitchen_sink.obj", tiles = { "homedecor_kitchen_sink_top.png", - "homedecor_kitchen_cabinet_front.png", + cabinet_bottom, cabinet_sides, - cabinet_bottom + cabinet_sides, + cabinet_sides, + "homedecor_kitchen_cabinet_front.png^homedecor_kitchen_cabinet_bevel.png" }, - groups = { snappy = 3 }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_sink_top.png" + .."{homedecor_kitchen_cabinet_front.png" + .."{"..ic_cabinet_sides, + paramtype2 = "wallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + airbrush_replacement_node = "homedecor:kitchen_cabinet_colored_with_sink", + place_param2 = 0, + groups = { snappy = 3, ud_param2_colorable = 1 }, sounds = default.node_sound_wood_defaults(), infotext=S("Under-sink cabinet"), inventory = { @@ -222,6 +386,54 @@ homedecor.register("kitchen_cabinet_with_sink", { }, on_destruct = function(pos) homedecor.stop_particle_spawner({x=pos.x, y=pos.y+1, z=pos.z}) + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + end +}) + +homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet_with_sink" +homedecor.kitchen_convert_nodes[#homedecor.kitchen_convert_nodes + 1] = "homedecor:kitchen_cabinet_with_sink_locked" + +homedecor.register("kitchen_cabinet_colored_with_sink", { + description = S("Kitchen Cabinet with sink"), + mesh = "homedecor_kitchen_sink.obj", + tiles = { + { name = "homedecor_kitchen_sink_top.png", color = 0xFFFFFFFF }, + { name = cabinet_bottom, color = 0xFFFFFFFF}, + cabinet_sides_colored, + cabinet_sides_colored, + cabinet_sides_colored, + "homedecor_kitchen_cabinet_colored_front.png^homedecor_kitchen_cabinet_bevel.png", + }, + inventory_image = "[inventorycube" + .."{homedecor_kitchen_sink_top.png" + .."{homedecor_kitchen_cabinet_front.png" + .."{"..ic_cabinet_sides_colored, + paramtype2 = "colorwallmounted", + palette = "unifieddyes_palette_colorwallmounted.png", + groups = { snappy = 3, ud_param2_colorable = 1, not_in_creative_inventory = 1 }, + sounds = default.node_sound_wood_defaults(), + infotext=S("Under-sink cabinet"), + inventory = { + size=16, + lockable=true, + }, + node_box = { + type = "fixed", + fixed = { + { -8/16, -8/16, -8/16, 8/16, 6/16, 8/16 }, + { -8/16, 6/16, -8/16, -6/16, 8/16, 8/16 }, + { 6/16, 6/16, -8/16, 8/16, 8/16, 8/16 }, + { -8/16, 6/16, -8/16, 8/16, 8/16, -6/16 }, + { -8/16, 6/16, 6/16, 8/16, 8/16, 8/16 }, + } + }, + on_destruct = function(pos) + homedecor.stop_particle_spawner({x=pos.x, y=pos.y+1, z=pos.z}) + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) end }) @@ -257,10 +469,7 @@ homedecor.register("kitchen_faucet", { on_rotate = minetest.get_modpath("screwdriver") and screwdriver.disallow or nil, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local below = minetest.get_node_or_nil({x=pos.x, y=pos.y-1, z=pos.z}) - if below and - below.name == "homedecor:sink" or - below.name == "homedecor:kitchen_cabinet_with_sink" or - below.name == "homedecor:kitchen_cabinet_with_sink_locked" then + if below and string.find(below.name, "homedecor:.*sink") then local particledef = { outlet = { x = 0, y = -0.19, z = 0.13 }, velocity_x = { min = -0.05, max = 0.05 }, @@ -555,3 +764,29 @@ minetest.register_craft({ { "homedecor:toilet_paper", "homedecor:toilet_paper" } }, }) + +minetest.register_lbm({ + name = ":homedecor:convert_kitchen_cabinets", + label = "Convert homedecor kitchen cabinets to use [color]wallmounted", + run_at_every_load = false, + nodenames = homedecor.kitchen_convert_nodes, + action = function(pos, node) + local name = node.name + local newname = string.gsub(name, "_cabinet", "_cabinet_colorable") + + local old_fdir = math.floor(node.param2 % 32) + local new_fdir = 3 + + if old_fdir == 0 then + new_fdir = 3 + elseif old_fdir == 1 then + new_fdir = 4 + elseif old_fdir == 2 then + new_fdir = 2 + elseif old_fdir == 3 then + new_fdir = 5 + end + + minetest.swap_node(pos, { name = newname, param2 = new_fdir }) + end +}) diff --git a/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet.obj b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet.obj new file mode 100644 index 00000000..86f0be0b --- /dev/null +++ b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet.obj @@ -0,0 +1,50 @@ +# Blender v2.83.5 OBJ File: 'kitchen_cabinet.blend' +# www.blender.org +o Cube_Cube.001 +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v -0.500000 0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 1.000000 +vt -0.000000 0.000000 +vt 1.000000 -0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.000000 +vt 1.000000 -0.000000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 +g Cube_Cube.001_top +s off +f 8/1/1 4/2/1 2/3/1 6/4/1 +g Cube_Cube.001_bottom +f 7/5/2 5/6/2 1/7/2 3/8/2 +g Cube_Cube.001_right +f 5/9/3 7/5/3 8/1/3 6/10/3 +g Cube_Cube.001_left +f 4/2/4 3/8/4 1/11/4 2/12/4 +g Cube_Cube.001_back +f 7/13/5 3/14/5 4/15/5 8/16/5 +g Cube_Cube.001_front +f 6/17/6 2/18/6 1/19/6 5/20/6 diff --git a/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet_half.obj b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet_half.obj new file mode 100644 index 00000000..39c0b0e4 --- /dev/null +++ b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_cabinet_half.obj @@ -0,0 +1,52 @@ +# Blender v2.83.5 OBJ File: 'kitchen_cabinet_half.blend' +# www.blender.org +o Cube_Cube.001 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.000000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.500000 -0.000000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.000000 +v -0.500000 0.500000 0.500000 +v 0.500000 -0.500000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt -0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.500000 +vt 1.000000 0.500000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 -0.0000 0.0000 +g Cube_Cube.001_top +s off +f 1/1/1 5/2/1 7/3/1 3/4/1 +g Cube_Cube.001_bottom +f 2/5/2 6/6/2 4/7/2 8/8/2 +g Cube_Cube.001_right +f 7/3/3 5/9/3 4/10/3 6/11/3 +g Cube_Cube.001_left +f 1/12/4 3/4/4 2/13/4 8/14/4 +g Cube_Cube.001_back +f 3/15/5 7/16/5 6/17/5 2/18/5 +g Cube_Cube.001_front +f 5/19/6 1/20/6 8/21/6 4/22/6 diff --git a/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_sink.obj b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_sink.obj index 832fae10..bb80812d 100644 --- a/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_sink.obj +++ b/mods/homedecor_modpack/homedecor_kitchen/models/homedecor_kitchen_sink.obj @@ -1,101 +1,166 @@ -v -0.5 -0.5 -0.5 -v 0.5 -0.5 -0.5 -v 0.5 -0.5 0.5 -v -0.5 -0.5 0.5 -v -0.5 0.5 0.5 -v -0.5 0.5 -0.5 -v 0.5 0.5 -0.5 -v 0.5 0.5 0.5 -v -0.387 0.5 0.388 -v -0.387 0.5 -0.387 -v 0.388 0.5 -0.387 -v 0.388 0.5 0.388 -v -0.387 0.4 0.388 -v -0.387 0.4 -0.387 -v 0.388 0.4 -0.387 -v 0.388 0.4 0.388 -v 0.063 0.4 -0.062 -v 0.063 0.4 0.063 -v -0.062 0.4 -0.062 -v -0.062 0.4 0.063 -v 0.063 0.313 0.063 -v 0.063 0.313 -0.062 -v -0.062 0.313 0.063 -v -0.062 0.313 -0.062 -vt 0.469 0.906 -vt 0.469 0.531 -vt 0.531 0.469 -vt 0.531 0.969 -vt 0.031 0.969 -vt 0.094 0.906 -vt 0.031 0.469 -vt 0.094 0.531 -vt 0.813 0.5 -vt 0.813 0.938 -vt 0.781 0.938 -vt 0.781 0.5 -vt 0.688 0.5 -vt 0.719 0.5 -vt 0.719 0.938 -vt 0.688 0.938 -vt 0.906 0.5 -vt 0.906 0.938 -vt 0.875 0.938 -vt 0.875 0.5 -vt 0.594 0.5 -vt 0.625 0.5 -vt 0.625 0.938 -vt 0.594 0.938 -vt 0.313 0.75 -vt 0.313 0.688 -vt 0.25 0.688 -vt 0.25 0.75 -vt 0.219 0.375 -vt 0.219 0.313 -vt 0.25 0.313 -vt 0.25 0.375 -vt 0.25 0.406 -vt 0.313 0.375 -vt 0.313 0.406 -vt 0.313 0.313 -vt 0.344 0.313 -vt 0.344 0.375 -vt 0.25 0.281 -vt 0.313 0.281 -vt 0 0 -vt 1 0 -vt 1 1 -vt 0 1 -vn 0 1 0 -vn -1 0 0 -vn 0 0 -1 -vn 1 0 0 -vn 0 0 1 -vn 0 -1 0 -g 1 +# Blender v2.83.5 OBJ File: 'kitchen_sink.blend' +# www.blender.org +o Cube_Cube.001 +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v -0.500000 0.500000 0.500000 +v 0.000000 -0.500000 0.500000 +v 0.000000 0.500000 0.500000 +v 0.000000 0.062500 0.437500 +v -0.062500 0.062500 0.375000 +v 0.062500 0.062500 0.375000 +v 0.062500 -0.062500 0.437500 +v 0.000000 -0.062500 0.437500 +v 0.062500 -0.062500 0.375000 +v -0.062500 -0.062500 0.437500 +v -0.062500 0.062500 0.437500 +v -0.062500 -0.062500 0.375000 +v 0.000000 0.375000 0.437500 +v 0.062500 0.062500 0.437500 +v 0.000000 -0.375000 0.437500 +v -0.375000 -0.375000 0.437500 +v -0.375000 0.375000 0.500000 +v -0.375000 0.375000 0.437500 +v 0.375000 0.375000 0.437500 +v 0.000000 0.375000 0.500000 +v 0.375000 0.375000 0.500000 +v 0.000000 -0.375000 0.500000 +v 0.375000 -0.375000 0.500000 +v 0.375000 -0.375000 0.437500 +v -0.375000 -0.375000 0.500000 +vt 0.437500 0.375000 +vt 0.562500 0.437500 +vt 0.437500 0.437500 +vt 0.125000 0.875000 +vt 0.875000 0.875000 +vt 1.000000 1.000000 +vt 0.625000 0.500000 +vt 0.625000 0.562500 +vt 0.562500 0.562500 +vt 0.875000 0.062500 +vt 0.125000 0.125000 +vt 0.125000 0.062500 +vt 0.875000 0.875000 +vt 0.437500 0.562500 +vt 0.562500 0.562500 +vt 0.875000 0.125000 +vt 0.125000 0.125000 +vt 0.000000 0.000000 +vt 0.375000 0.500000 +vt 0.375000 0.437500 +vt 0.437500 0.625000 +vt 0.437500 0.562500 +vt 0.875000 0.500000 +vt 0.875000 0.125000 +vt 0.937500 0.500000 +vt 0.125000 0.500000 +vt 0.125000 0.875000 +vt 0.062500 0.875000 +vt 0.562500 0.437500 +vt 0.437500 0.437500 +vt 0.125000 0.937500 +vt 0.875000 0.937500 +vt 0.937500 0.125000 +vt 0.937500 0.875000 +vt 0.062500 0.500000 +vt 0.062500 0.125000 +vt 0.562500 0.375000 +vt 0.625000 0.437500 +vt 0.375000 0.562500 +vt 0.562500 0.625000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.125000 0.500000 +vt 0.875000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.500000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 1.000000 +vt -0.000000 0.000000 +vt 1.000000 -0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.000000 +vt 1.000000 -0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +g Cube_Cube.001_top s off -f 9/1/1 10/2/1 6/3/1 5/4/1 -f 5/4/1 8/5/1 12/6/1 9/1/1 -f 7/7/1 6/3/1 10/2/1 11/8/1 -f 8/5/1 7/7/1 11/8/1 12/6/1 -f 15/9/2 16/10/2 12/11/2 11/12/2 -f 16/13/3 13/14/3 9/15/3 12/16/3 -f 13/17/4 14/18/4 10/19/4 9/20/4 -f 14/21/5 15/22/5 11/23/5 10/24/5 -f 13/2/1 16/1/1 18/25/1 20/26/1 -f 19/27/1 14/8/1 13/2/1 20/26/1 -f 17/28/1 15/6/1 14/8/1 19/27/1 -f 16/1/1 15/6/1 17/28/1 18/25/1 -f 17/29/2 22/30/2 21/31/2 18/32/2 -f 18/33/3 21/32/3 23/34/3 20/35/3 -f 20/34/4 23/36/4 24/37/4 19/38/4 -f 19/31/5 24/39/5 22/40/5 17/36/5 -f 24/27/1 23/26/1 21/25/1 22/28/1 -g 2 -f 2/41/3 1/42/3 6/43/3 7/44/3 -g 3 -f 1/41/2 4/42/2 5/43/2 6/44/2 -f 2/42/4 7/43/4 8/44/4 3/41/4 -f 4/41/5 3/42/5 8/43/5 5/44/5 -g 4 -f 1/43/6 2/44/6 3/41/6 4/42/6 +f 14/1/1 13/2/1 16/3/1 +f 32/4/2 24/5/2 8/6/2 +f 11/7/3 18/8/3 12/9/3 +f 28/10/1 31/11/1 30/12/1 +f 25/13/2 17/14/2 18/15/2 +f 28/16/2 30/17/2 2/18/2 +f 15/19/4 14/20/4 16/3/4 +f 12/9/5 17/21/5 19/22/5 +f 20/23/3 26/24/3 27/25/3 +f 22/26/4 23/27/4 32/28/4 +f 26/24/2 21/29/2 14/30/2 +f 32/31/5 25/13/5 24/32/5 +f 12/9/2 19/22/2 16/3/2 13/2/2 +f 28/10/1 26/24/1 31/11/1 +f 26/24/3 28/33/3 27/25/3 +f 27/25/3 24/34/3 20/23/3 +f 24/34/3 25/13/3 20/23/3 +f 32/28/4 29/35/4 22/26/4 +f 29/35/4 30/36/4 22/26/4 +f 30/36/4 31/11/4 22/26/4 +f 32/31/5 23/27/5 25/13/5 +f 14/1/1 21/37/1 13/2/1 +f 12/9/3 13/2/3 11/7/3 +f 13/2/3 21/38/3 11/7/3 +f 16/3/4 19/22/4 15/19/4 +f 19/22/4 17/39/4 15/19/4 +f 12/9/5 18/40/5 17/21/5 +f 11/41/2 20/23/2 18/15/2 +f 20/23/2 25/13/2 18/15/2 +f 25/13/2 23/27/2 17/14/2 +f 23/27/2 22/26/2 17/14/2 +f 22/26/2 15/42/2 17/14/2 +f 14/30/2 15/42/2 22/26/2 +f 22/26/2 31/11/2 14/30/2 +f 31/11/2 26/24/2 14/30/2 +f 26/24/2 20/23/2 21/29/2 +f 20/23/2 11/41/2 21/29/2 +f 4/43/2 9/44/2 32/4/2 +f 9/44/2 29/45/2 32/4/2 +f 27/46/2 10/47/2 24/5/2 +f 10/47/2 8/6/2 24/5/2 +f 4/43/2 32/4/2 8/6/2 +f 6/48/2 10/47/2 28/16/2 +f 10/47/2 27/46/2 28/16/2 +f 29/45/2 9/44/2 30/17/2 +f 9/44/2 2/18/2 30/17/2 +f 6/48/2 28/16/2 2/18/2 +g Cube_Cube.001_bottom +f 5/49/6 1/50/6 3/51/6 7/52/6 +g Cube_Cube.001_right +f 8/6/4 10/53/4 6/54/4 5/55/4 7/52/4 +g Cube_Cube.001_left +f 9/56/3 4/43/3 3/51/3 1/57/3 2/58/3 +g Cube_Cube.001_back +f 7/59/1 3/60/1 4/61/1 8/62/1 +g Cube_Cube.001_front +f 1/63/5 5/64/5 6/65/5 2/66/5 diff --git a/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_bevel.png b/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_bevel.png index 137eb3ee750b2d69316cd0941548b144ec44c8d7..ad6dac3fec5290bfa327063df43aade63ce49e44 100644 GIT binary patch delta 81 zcmV-X0IvU6aF8TSH%UZ6R5;7+%&`psAP7alhoN;mR`~lT7L-`H0k+%#XH~Unk`xYL nW~X`N;?o2ZOz^m*0J0lg9Rmp<|Gl=&00000NkvXXu0mjfTiGDK delta 56 zcmXR2pP*ta=jq}YVsSc|V^jD%56(0O;gqI8W;b35(}r7Y0ZojXXZYw^eQ1+n00K`} KKbLh*2~7a;&k07cKX$0i#V4Z|Y7AP5Q;o5?8nUrlDkCOGrJF!2MOAO`hKhx!bDpK{@H57!9p zmr}oaBW$ggNpo8u&_|tUJxK0Ho#@_DK zF);pF3Fp;dIq+|^6+*3@X6|ti zC&q$Bn$QKQc_pYP>0gl8Y;L%HY7NU}Ic$}U>-XKtFJ(ng=Qj=7Q2+n{07*qoM6N<$ Ef~in!B>(^b literal 0 HcmV?d00001 diff --git a/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front.png b/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front.png index 406739f8a8780ac3d5dae8b7679389b5e94305f7..8f66ff6450f3871dbf9dc37de99a190080cb3b72 100644 GIT binary patch delta 517 zcmV+g0{Z>C0+a-h8Gi-<001BJ|6u?C0ozGLK~y-)os&yz6JZpFpGhY(xsK5!%#hT= zV9`J{pcE8b>8b=5UFgD9{Q>?Ae?>uXZ=tvz^GV!HGg8a zJ7lk)qg1oeH3bo1Av@2OxkoYM9n+INP_0BJpjPZCG!w%a|~!i_l{VC2!D zH&Eb{L}Y)c4-n{kJQe8iui=rrQzYVNC{`_|)%dYXR(``7IiwPhfWKH6132SrKG}!p z5&D1O;o}!004?fL_t(|+Evd3 z5(GgE1<+oO?H2Oyf5tJ3sTVWHhlUqT5H@qfJ;z*Ygkd_*#ZPEc&7cY7!)C@E%;1(dL&bHkNI3QiYnH{oZhWG-TDUdv7)Y4iU5T78o!^{E0 x9Z*^%*r3uzza(}3(ck^K|N4Fy@PczbxCy!r8_teTljQ&a002ovPDHLkV1iJmaN_^~ diff --git a/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front_half.png b/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front_half.png index 2e6a60ca241fffa2852578e0b384aaf0337a400b..d5d8e31b7cdd3318cd05d81737bbfead189b6f21 100644 GIT binary patch delta 355 zcmV-p0i6Dc0{sGzBYy!zNkl3wVa}^jLF2QAlV0G1`$Pdh@^w< z(IGFztejU9&vIUA%@zU zuFd=1@k?URDXy($W5NL#<);`w-syc zL^2aQ+_#uOv;C;xcq(WC-j+JO@Vh_(0PuKsrE^YER&zAG9HS@_u#(MOtDT-+Wkp$S z`4~l(5LzSw6snqsb1Ic8faHyW5$W3(d`Etz*A4-|Od0qU`J*4~ER5FOjhXv=ZFHdk zoSmn&W~p3nlUyW~$_~sXYSK=}6X{A(0?_RZNRkpI`tvXrUJY1@2Jf2kvZj_kJQ9Kv zjKyI^pGKMzQMr(=uqRE8 zd6nb}CsORcb?tK@9Ne?=j`h2a6MUTa+|J;Xs%Y(Vg-}86w+7vp(;xdoLLZEL9F5(q z_p!))9*v{PP`cgd7l8S*Mx2d3vf}D-MnAEBmL9hU*#(EaNoUFuOc@|90dI$662JjS zX(v?xg4YC?3I%pc0C#H)=${J!EcJ7VP?o}hwKBkKJl=a-qk07*qoM6N<$g3C>D{{R30 diff --git a/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front_with_drawers.png b/mods/homedecor_modpack/homedecor_kitchen/textures/homedecor_kitchen_cabinet_front_with_drawers.png new file mode 100644 index 0000000000000000000000000000000000000000..510243b22ab2d3d2a6e10d78c56faddaf9a6ce4c GIT binary patch literal 561 zcmV-10?z%3P)$C zU2oE07(Fj5RG_U8R;Y}X5lp~nWYa`0h&P&;#cO|nKVVn>hF$vyyzz1|#u$xeF~&rf zZAM2%Of*0YAhdj>n{%bmwXotvYlq6YdfxLs=XuY0AF{r-N=`LH*RrYj(|48pmH612 z04RRz+`E;jchy?+r*<;BTS!ZamJ&F!zP5Vf+A?OLua8*27XX3D2AM}s-rl|%q5v%L z%zp8s+xOx_89?`NAVh-c#d!c+zz3k!Y{3?Mm$gb$bp@HFIDpL3*;7LU0L(D}PypWV z>`7AFzUv+i>_UhH|8W=%(~h8!&mo_)S=;n<0J{e8Y;)HUuzqjx^Um}zb!Y;(oSJuz z14A`DO1BQIPylq(acN^~zit=1U*wxBDVI0L6adN`onBmE`XYB0TFe3XT0Z~~pdFGB z5)ISkdYc09@bR1eQQH;#>KiBKcxG-V!-M;GWJM$1bF9x|1HN+eC@Y2m$ci@Iy76k8 z_D`HW?0xzxbg4LF@wHkb9Zga`?_4bG%ZQxRQ;vrOz;@|}+f-Oio)1hCF&;pr@n;Y6 z!9eOMi5Q;%rhn5#tEbx8C=a0kWW}(q@HYED2#m!T4ZA!u6{1- HoD!Mj zK~BUl47A7YM(qjp1BkcrCO*M$xFH@9ZlT*a_8uY?M4{Wc*`67X;_&Osvxr25s+yU* z1BeJ_jtCK9=2|O&)|!Z@h` zW@ctYRBMHZ&}pbDT5J13&N=72@4LGKIAG87{Bv}HfNSo^~dm<7M{nKer z?HGmu%d(u0#LPO5BbD#>J{GvUy8Cv^y8<)Q@^$SWq+k9R%hhyQ+XKCMaR_=!t0n>l kz*yH+2W{4vDWznMZd3nsaJ^_JXaE2J07*qoM6N<$f;3EmkpKVy literal 358 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 q+){W>bUyEi6vH0000kdg00033Nkl z!41PO2t_|Advpvo=@h+sfnL2yH|Pjfcj*fB5LK=T5U24iiQe}IJ_@}Qr_KW0DgJ!J zHN_vw_EkOTfJdwX`iDS8`95o*V@?=A$IL4-b$49cqJ9KQk_U_TqP9U&&y9pV;qk_*h2kNu#)aG@mIQCk%|@W(aBvB6fL{8h zEUK5y;KprSkS=UX@i59g?c$_=Lcrde`QQw1Xu4MhJ9F-~RcNmZ9B&;|2o63jH%D8C zVD2^#9BthkzG-4!v6n_8a1;-NG>cCQMEImYj86&(9bTsSL(h}H_Yck!^^PCbLc@#u`UBq@ikG$S5|47Ch~orw++#)-@Zrjv6S s{w6cV3hvwp6nL80kjXG(0ShyO*OV2nuBq&>0b0V~>FVdQ&MBb@0Ks4|jQ{`u diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_round.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_round.png index 1932f0fe5171a8e9e5e1b14122f3a7ed08f333ba..1329b1b53edb21fbf1277e896d7b896020d96359 100644 GIT binary patch literal 597 zcmV-b0;>IqP))I*3`IXUx`rpm-~o7t)NazH-F6GMx`gUfYF+REJ3dDGOuCdvv6e`J0K~P%>L|_o z_#i&HD|*LspA(RspMT=Ji~mB9U!4y+2t9TN_!9zWEVnf;bj(QrP;pdzaiDE%LGDA3 zZ`|Y27TAqTJd%YA0nK>DcjHl?g57t;quNv>usC^;cx`G75^HXvxhJ8oc;dq`fV6oe;QA45A5dRW|V8%qmup!0a@4c5j=du#*f+v z%ABihj`V03f_>`1k)YuH;SScRgE4oRhhUw$IegeezhfgZ#PogFJ~BRs}NF`xmP#l}Jj27HaX;@Q?^7 zk8-f%`ChB^Z6MhKx$&{mF3|)1N(e~fE4^?9b{}cX!3WHsvG3pXs#dP6P^x+LFLOJiI{DbxVn>aOP+Fu49Sp5PwX;^NMgR^;v<6OeU1A14nl0KlL$+d>&^CvB)~2$b&M$_I`#ULyVa z+J}W}Z1k$7TVJYxed}q{F>mFf+Ugc!DF(b-6_5tn8 z(_!xaGirTyX0pxy8WAJ&)f=cspAI7$RH!mxOjG-w)*ZQpGsXbPcfBJiLxuzqf+V$y zYn>;oF@^`NTtRUxP?5Xdku+pXP43WTK%ar!przG>9s^g<1Pj#Wu6HEG$Pp(=UUPy! rjWJT{NlK(;M@#_&B;W9kzOr=$j=YY=;}JXp00000NkvXXu0mjfkUe0G diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_round_inv.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_round_inv.png index 0d868375b0aa6a09a93a2ef40bbf832196f29eb4..d6af47720b41d24ecd21210385133bc283ecb13a 100644 GIT binary patch literal 713 zcmV;)0yh1LP)kdg0007zNklaxk>eR~ zLz^>>`F?WUKh|jRKGNajDN^8oLr%Hm7cj;I)6Dad26Y*kvB6LT9;d`I+f3RWzvnFl z=+fl}pH!ArzNlTQvKunOzf}QejvYqYIlB_z(Iz{x!U7}gsJU2xDkYpHHrf06dff;^ zCIs>18}`^#OF_>NKnZ7#HFoSewE!=X)?`inW=$!1bf1AUP8r9p2Sehxt0Qm7Iu2zu z9wBl94W=uSU<39x^MK z;xs_ga5q5>08W__*XvYs(n83iBKrI)lfg z?DX$Cl7#CKRAo8G6erg-Snc0+58=Qnjpj8ibY5R+a}@u&V06HBp@S!F>MNb!M}Tax z%f@4Lj}*DVu51M-QWaCJ$9LTzT&-jJ`%eJKE){H50DGMKRgRhqfJk}*3s_7f^zNU`^3g1!F(*~1ds5v0}e00000NkvXXu0mjf@*YE` literal 3865 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 bs#f(sjH-iy2wRT=00000NkvXXu0mjf4Iiq) diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_square.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_square.png index 66baf21bf497433350960eee88133e23596dae88..e89ea540b97c84dc8567060f9a308b49933e0ef0 100644 GIT binary patch literal 642 zcmV-|0)737P)Nkl!O-#ZiTsU!Tz?Vv7MUdgBz`Y3v=)e#7N4D#}t{NwY>6E7Nv0+-@GYhuc zeZ~D91Uha@hikzXEPN{sSLt(>&7N*m!P!#>_Jj(&9ByY#9gMzfKR9dZ`rxY~wll7| zQ4!n=H;vQ_?IZSVTwlhNB5I0Eg+#sIb`T9JNK4KduCnbA~XoHQW+Fvw51~%o#^=7%lCKWWVCxO=!K#(R0uWwM20-|7>$64 zjAabO(&We8o=QRFg~g~2gsW9pSSmt1U0zrYR0qNzkrx)DQV@AzIZ+)*WXKE4nMy(A zg=I%|AlJOgZv%|#Kq5n4Sawtg;_33jvZqoId0{cC1L10w7nTDRfCwM3YC|GJo_d0Y zKwu1k=r<1SX-8{v+ELJ+jGPW+bRefQ#T!FEDx`7l0S9=?yGt}tIsgCw07*qoM6N<$ Eg6O-K1^@s6 diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_square_inv.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_glass_table_small_square_inv.png index f768314d4b8f507965e1b35d5a29e09dc70d9e44..aa4079c4bbaf9ae99341e33c3ffffffbe8676255 100644 GIT binary patch literal 334 zcmV-U0kQsxP)kdg0003MNkl z!41MN3`M`A-Wh>0yh*3vngzIa6K3cF8G{875@%!%6(n_SH>kZ-s`|da9e;&p!J%gW zP6zNi1^~EH{WKvrKU^>d_)UQH#eVNUTS}^`WLish2~^V+&jD1lfPOSyWR0^guo%}k zlZPt-%Xq~X<7~|!>bv4>Hq{7ZqZ!+H+tg-=lUQ!pok?0(oFtQfh>P(SZ#FRpcrhv~ zfr`Vx*~I~x<%9?MTX)_ZTpOm>lEyJuTJFh$zwK;ne}{ms8~I2PUQlGOjbxm2wJl70 zQ%HX5AWSgub-0t4IymR9_aS+y>%%ugj61frQ3?EuyNlF|cMEuUr+|-l3UH8Cn&o}q ga(!WV9=qM~0hM-bLdVkU0RR9107*qoM6N<$g5l1NxBvhE literal 3938 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 Dqu`k* literal 0 HcmV?d00001 diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_table_legs_wrought_iron.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_table_legs_wrought_iron.png index 8d7eec55533742ddcdcef2a0d8b7acf9de692782..94e8bc1ae789d5860dbeace45a0cceb66046a6e4 100644 GIT binary patch delta 424 zcmV;Z0ayOT0=EN@8Gi-<001BJ|6u?C0e(qDK~y-)os&hRP%pPtF~d~AMzppamc zagDf|5J@fp1qojC=5O@s#XsOtM3hVt3~Lezo;-*Qo9U_PE)Pl8uiZ)XJrz{-!&`6B zaHg^>wJb~J0{uB>&Wi_k2ingw@+>FGQf$xi;^iv?@MwKSn}0?K8gPx^8ex0?z)S!e z_m{PH4exgLC%|W04|QBshzQ;XUcdb?=`CKpqG_72H##zAmesZ4ZS5x(fUn=av;FbY z)Y)hj;LZCT<3nJ4;$}YX1OWID@F8@D+6fS8X?@!XnCohe>zWYs{~Qc&Evbk)9P0{-X+x?P^p36lqVdL?KZWS`@{FU-?|W&i?=ahOtxv SjYYBm0000EaQpu3@MUvzUM!1g zkq>gH$0~z&7WlyX>V0{(x3RON*9}{d8bN-)J0K*<=xE3N+yJ>CWoH>CXD*g2KF7 zlGCCXp-RKpb1pDdia2Pq_@~%;HnOgyE!N^yc=HVW%ln;29NaXl%g?-<00000NkvXX Hu0mjf+0>ZQ diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_edges.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_edges.png deleted file mode 100644 index c2b3d96e801a7b3608054d7bbfa8af3145c1864b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 465 zcmV;?0WSWDP)h} zCH3$1sek9ZGwnEGq?C3t*aBjO~!^C5+sz=dU15PgR^V z8J6nx*k`CkI@K@1|ew|AdCp~*~|i0e^* z;wmE_*IJRa_wU<*rb)|^JRNm~=<%yNGd*o2{MXVyegBjM03-#rm9Grfznc1huaHf9$>1U(5s=IMiq345`Anf6JqQcWa_Za;Fj>Q)Yis1M)00000NkvXX Hu0mjfYCP3V diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs.png deleted file mode 100644 index 121f2f23c681c4e5259803e4d60132924c481b77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338 zcmV-Y0j>UtP)MG^Lyu0tgL!RLQx>R_P4j6cduUna1KS&{T;BiFgZ5R3yd>9*ta%2 zE`xVPrDec4LaGdsK#}_=w#M}cS7D*!OBP4DQ kpC;0uPuc_LBr1jo|61gJ-l#yVO8@`>07*qoM6N<$f|c`&7XSbN diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs_inv.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_legs_inv.png deleted file mode 100644 index 799477a48f9912cc6ae7642cbe97e1d2a7ae2235..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4371 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 N002ovPDHLkV1lvj0M!5h diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_tb.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_utility_table_tb.png deleted file mode 100644 index b3ba2be505e010b6d950d9143f479a0b9c51ee88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 576 zcmV-G0>AxAGz zKIp|o+}K;&+*n>{I5_!zKAoN%U!2_3N{5FJ<21UZ1;4qsDj{sI^$SZ2pFSQv-k)FG zSY&0LomsiO`KIxE$|SUTu=?%Y4{3c%N~A(W)d=^lCv#m731+222o*+eWZruzIk}lx zX@fc*rvZ)TQ+t|mFf^HiGafloSDI$uQ4JA-WoMnLd0}Ov6hhWC?sD z53Yc_xW1!I+l#H&#>lu+_Bz{0sdi5rQ=CLSgHTf}#(j^+5ijOudsw1et(Nn_a1K%S z9&qWLXN2;2H%_H=jUL@*!?7s(ayyh#tQg3+BqTCSiGom}5JZKG*j%f)M-0^>T_8}h zrDB%L`IubFMP2j%*WeX$FpWEu2w~aAIL1_&82Pv$2B`#|;22WD3w~Pr=KkpjW~mYa z5cCKMPQZeA=-QYv#NeflnVljBRYag7o&af`NX+n&;2{p9SN4txdSyT_>R3G{7{P(= z)l}V(?fdU@@2*ZSrfkE_WiHM6wXH9WCwRo8v-th@Wf^R$<>>DP(*6N?&T8iaOIkqy O0000Zc!dZ!_GyPh7@pCGW&mn-spo9pBuh zifT@sB6Lf7X`RIpVTR~$9}Rt5W=#0qt0mj8ZvTDN{U0j4GFu*W96#|#B!J)H^2`T! xmhEN!_qF!XO-nX|21cF)24;x^3@~O5qy6pps*K->CxFgl@O1TaS?83{1OOyDPB#Dm literal 0 HcmV?d00001 diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_edges.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_edges.png deleted file mode 100644 index c2b3d96e801a7b3608054d7bbfa8af3145c1864b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 465 zcmV;?0WSWDP)h} zCH3$1sek9ZGwnEGq?C3t*aBjO~!^C5+sz=dU15PgR^V z8J6nx*k`CkI@K@1|ew|AdCp~*~|i0e^* z;wmE_*IJRa_wU<*rb)|^JRNm~=<%yNGd*o2{MXVyegBjM03-#rm9Grfznc1huaHf9$>1U(5s=IMiq345`Anf6JqQcWa_Za;Fj>Q)Yis1M)00000NkvXX Hu0mjfYCP3V diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_inv.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_inv.png deleted file mode 100644 index 2c4b3e8e8d96c17c0a1798a2a894b094b354f5c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4095 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 diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_square.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_large_square.png new file mode 100644 index 0000000000000000000000000000000000000000..3c64e3cc193e3c8843907fe0aeda8af87817dfc7 GIT binary patch literal 1217 zcmV;y1U~zTP)f7#J&IAq+5amuuiQxEbyT69+7W!3b$I8iwks%8WSY z#KGv@wl~d{D%^aGR2bhI^p`*XkqJcwfU0^7VQMWRgCN!~9wRer(RFKxasTwR%j;AN zD>Gr5rdpMfw%(JrTIVX76Xh*Eg&^7^;G{sRCDh$u!1Q&M8U2at$}5pV+) z0w9^wB)hx{Q$|u!cnT2{gm?&skCC7uVS|7QW(I)0UZ0-T4FFg%Y{VcD(t_4`_+Vy_ zfq~Z(Bae^!yxu*$Tkh{NlZc4Lt&i|hBqIBIm0H|~GKU*Tkq**bUZ0+xrdfzZK(C+I z%UUNMWBA=&W&)th&AhO9jw-s#YjbO7J1n&gz_ud9O5L19rpkfDKSV=+PspYbEx?V?uxF9`zT-&%Jp8USB@T?2!jWdFapdN9l~(O zb^#J@NXJsq4U1sg_Idroci(!Z5$*SVG!NyBR?t*7~RYX0H*XS=+9 z{&JcNipr|@;raR6w`Lw=ZJ}awL7kWXp4QbehiCX+FTefZ$tuF9)4H|od}&Brt}77^ zv%Z|$dO7vpkih6}-Y@4}Ud#RC0J@ZvZSHqR0}aqC&zGC`3dC+(3;0NY%2)F0aB=QB)LOLc|0i zPCD}?^TvbFw zEN(NyTa$>I>s@+tPh}1_kfI!|#F){0ClrGBdUcy%oyFVzPAK!3^L{#<+TpyW`P`=Y zvMiNhzBWC+p8vU4>|u*XNI0)DSHn z06;=v1sF4qM~R9Iv@SNMG(jRfc6ojGzO^Q(w5%qAN)=v5v?fs{)S@aqvzQ54VB%d~ zeIhNuP~pfDVISF;!fK3Yjk18mve2+vgw|QRy#Dg*&ru~rPaSL0NiYM$YmTiqwJ54k zRkQM#w;3NUZ+3b8a=mqh3J*C&)XQemJfen$uy;l4%h%f&UX@W9d%fPTFL62_5AE~k zD;Vab!rPe4+u^x%KdgMR@9&8(n)slIXm0000E3`M^r+mpySG{A`?4NwvFP!2av^g#~0Gh-_t!k=J;_fDp_Z(gsr?%ck$y?^(i zG<^L$9zCBQJbF}Wn@aum?c3$&*KeQHJYK$farVK}y0rp}U_z~8K~g4g0Wi(7+}Ly= zEC6ufWO$it5f;i42$vFl9P_rWOCy$uL_v}zl1`L$_`0q)8nPZ9dP2J&m#aGjl;Hxi z$YPo%0G!XT*qs1W5&R7yz%H#4iw_qf^JuMPcxaf8RUnd>laL37S`|`t9o;-F2onXV zITztRv>RZawT%GK`_+v0%kHKklyp!Wy=TG4+0EkA0AoK5z_Q9ZukPL^u2o8f6W}j4B> zauB}my%i)=D+!T>iIDcg5E*HencZM!edy>HrWmzN6y^bo$X#hAcW`7>UCn!UH>i8o zoZNBrQc4o8UYqFXc}HhAiYUzg&4KtECa$N(7%@$h^5}-(a3i8)s3i!r%2bKLtrkXT zuGRWE(uPz4FmxwGWdRic%*dp^A1AAN3YTt^kO$zfh+39z&~SvB2LOqXLNNag+nQhg TCY1&p00000NkvXXu0mjf3ccv9 diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_round.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_round.png index 874227c3b615cb462671c382a9b6cb02191feb38..1cfeb9b12a40ab62c7c88f76768a764929b1c373 100644 GIT binary patch literal 2294 zcmV?n2|JBv|Jkl3PNMFA;*03iet5Aeh*{{fHu4dej@ z!XrooNFc}}A_228611-!n1!ovFbjw@}+M*ap2MW zckH=)b7qYXF{Y%d1|~$YOcK?wF@!wNvy4fp@xE!A%k!hZ9zXTVmrkxT;A@9>?A_MS zjExCUh)5E|0CEJts^+-`U@VA8l3GJbiiDWpgS>Zf{`og9-MFD$e%532^~3k<-#$}V zONLTZRUnxdK%mSTXUH1EOq4)G64inX!I2sBhRmjJXGxWtQ{8lCc(a3;vS__gopuuU>i20C?!$t=8zM^-I-Kj3dMFAqptZ ztjn!)RzO*n88$H7#xNK*A%t7={a)wO5AFhBzy0`qhwj}*E*p*N;Nw!&E)EtnLCH03 z7!9kzQUxIRc2p0LG$l!(+u_-?{W9mRQ)YhdiobY1`UD^;0E{|A0~3N+OPujw!9xuI z(SaqhoZlwDxkrqO&J72aHMRgimLw<;j6qpiQAq-q+2Fl(76}qXw7pF}OO7{ea?V+3 z3Q3){(8Si%tvF{z)shp{6jM@T2uWecOvH2aNI_u0)<{xoO>C1hBthF&oTH>bLY`9_ zG`CcHorvd8efD8dwM4xPb)t@i7qn4*+hmS|D5)@W2pYv#US?sBBHsdSi^sTvdA-jgo?l zgGPyI)YcR6%w`>KsSj4=*&0$&Qj(~a$Pg@jUj=F5?UW`lYjNZS^mXK|GMw)**&|rHlq-HhfBuIP4B+K|z9aR5QM!XZXubaB`1${}iZ319x_8rt8}c11@?CE5 z0j==C&HRbebH97@(no5`_ddUC|IUpo@|~{dJFfcxxAXyt>bvLWfA;d}n~T>67nip5 zi`l6%g=7thpsfX}5>*AcqZpAJ@*XLwBv>+QSGZX`XDM2B_RbQF`Pxwx(!v` zwrzO#+?5w!d*_+ozP^6D9M#KD^d|xr?X%ovuu0ZHSUoi_BG{8Zk|8o;8HrF#zXWh;n5qEM6Y0wa+SN@YKUI z2X>abw@w#qo7RVvG^v5{A+j?uB;%|#D9bX>ol&Zqb~LKyM>zh$!t=)#)*0~V6t;H3 zijV+BjF5=nK^XwBqAUTxT982$u!RyJ2njLa!Vt$>tbUUn@K_J`bdg&a3-Qnd6?hK< z3X9x=4V(iB$RGwVUU3m|l*oAE+qJSALN8KO=7=s{yEay8mY(i)O zz&eOug`XB|7~s!yA06DquN5B45Aa97tc7nu*K8Vrllib&}9m-Btp`pk0BRIn>MOvWQ!@yg=K4 zGaw-b#54iVTec$00EHK13@99ajyEb&fb?MrqOdd}e}4xO5Cu#~0%MRotU-)u zDnJnfG@{Jl14@ggnT+QnPale^Of+3!C^W@rBATF0Jt{KSic*T1bFJ49n?W15&u*NE z=eetc!ojhvxhGNQM!so7lvKCEHWUt7QO*zQI;f_o5+~*DW80$|w$=;=b<;M(s)eE& z)kNqNyfkdv4%Ra!e4<_Qd%(IpG zo~W8G`UTsj&6j;J)nC&Gx8UjN*){WhQXj0!GaG0G8N?QBUGW^y7@k-561k3#l}wOX;as%o9~nQV9Xyo zRq+ca>w9MNUES^-_rdwAOTT|Z2*5+LxPLPc?xYVw#OoLF#{BhObTG%P-bo*vTEvO) z(c<;^Hte2RJKuEzADo-V(aS4}*To9c2Ghm=>w~ikcy(_1m$0Hb{^-j)_un%On2+HD zB75xA;xo$!zgGD@@<8vwT~pH~v!!vqkE&)l-;1&w`(SFS=cC4O%?GFdGkWvv($Tl; z+x>s=)WOc7UHuL#sZR1_6AXMvSF3pP%;F0tn^pJuFGX{|*L*`k QJpcdz07*qoM6N<$f_1uMo&W#< delta 561 zcmV-10?z&R5xoSE7k?lK0ssI2{21+{00066Nkl)UaEMuTTEp?C2#X$QCgI8M2Ke184u=YRABfgAI}u5Z`bo3Idp zfedM>>pegBpdgma1VBPe$%LZ4(Uxahao_ikf%;yNHenj?pMOO_KoxFq&-yry1Hi85 zn&tTf0q7$5H-rR-j7}`ELWn$aj8@t8ye!?;Ef6UdBov8d-i6GOW7l&N z)@AB|M}7NB0Dr1~xzqFK6K*0@Iw@b(`q=gSPIb>|3C1(M^mWU9-Vrel?p<0(5D<9Z zcTV5+T$#&tz8+ND%&6(-heRU6J*TG5u)r9@)3^O~mZH(yoVA~=x8X@I|-4ei;(H-$cl{4%;9i%UAFYkU4PG%tB-@yBjK6hXrt900u{3` z57h{VMb!7M=W_3>t+f(i(TCX5<2a@|Wj5yjPcG!Y+4YUMPs?-VanST!>d2nqMD*(N zg23pk2nLV7?HOscZLV`A6QoOtWe*`c3#b8LMrD~l@7(ol78(Ah`XLkv1U$31OC6Sh zG>9C%+Aj4YW0q_D}r%?vn1e<;9v~tT&0b0kwT(X4i6cIG~QuM}g;UR$;nIlt=O%kOi~Ilsp_-y=BY z*gV-;?U&grMP^>=k&{w-7-QP5TYtT3{I$_|e)ZG4lhJYhE1ooA>*CrA zXHP6$URml~T3#x;>w}V&UP)#YMWG2k;ZmZiTjsUr!FbN-V0L(SIKFcC{=r}WwY~r0 zQ#o*|t52NhWv>sq`D-g>Zk7r|#~4JENGp*7G>~PAloCitK;r`Q#;00_WXL2@Qj%+hRf}h>1tNix5+Y1{~b4B=ZOwHdouscxwY;eH%>48^5Xd(tAm2FP?TLw))5qi z#O4B%38aDkipFFLn@c)9g|(oqA}=+AzMobCI_SlNf_$JF+ZF!na%)kZNt2pKup9K zhzNwS%;y!Z^-O0CC@GoE>z}94zV~42?rMOgTwPY})VOJ4ubJ}sYBTQ~ zB9S;3P)eY!W^&L%k^qD>K?#A<8STA0_%;F%zlB#;gPT(*Z8Te4I7kX8+TvARl zc@R<3A(SAv1URIGqELhshyjdMxVA+Z1rdS|gw&vP!Z)9v?C;>EmWWzl(3ehj^c#A$ zZ(ccny3>8;Oo=fHs}!V&R+6d-7^4U&p@bo%MD&rE7Ktb(kV0b2f^jinp1=nmQMSV@ zw%yUpyrQjAFZGNe1%XnM5EDvCd=oKp5lPboj1h~ajgV!6#w9W(sMS^4(0a zTx671zoa)d&usnTS3hEX&}F%hR8i1T&<1FHqHSud(YTNhDWJ8+xr7fbvo^4{y!3g5 zg0AIQd{qZl_7AvS#Vs8|*f1gx+M33egpfF>9j)_(kZ4>$NsrZFY{qof(D+1(ffNJd z$qcI((Ko7dEWT=+HKU7!n~S_V*_s!TE$%lDcV;Qev!OR<(%voR~mJ1IZJ7 zWZqPSPDzoQWAg}u)e(pTEsZ51aDI_WwbCRaN(!{HgcPXigm*1IL{dsv16AEXh;)~i zNi2+VOx_rn&1!t>(Nf5VXtkz{q9}5#)rcgh+m6H9%KcZ+wa zAwGdm5vs;BpR~9XuIa-jT}`$)%=&}w>S_;T%%gg4j3R_Y`;>a%aXbm`4aX#H4x7kT zy)&#v&t7P+95(*UXQUJLYd!5YuF0)!` z9Z@12spsEU4`fDx62zFeJ)E+$d*F8N?f>EaL48*N49E4|!BXCfA-tGrN!tddhvWaN z9+*z1+}hn|`|dv5cSe8u=+g&(JE95CE}IkQ*UG1MXu>-OZYcchZC9nW`7~_}ik!k| zj27QZ4 zfBwde;Zfs9w&1Jd#<2b%>l7b%MD}{A>}xCQ1G6&dvC_4aotzLLM#tPm)|Qv>F(QCM zM-J*hby#t8Z_Lb%-6S>dP6F?IHfn}X)tvtLnZXOER(h9Du5>P~ulBoxZbqlbDXhY3 zfwh*D0!{0wT;lfq3B&!#;qGX9Wp^}v`sVcOY%r1&x_1%X~hOGAV#D%4-;(9 pD|da~wAV)C>gtVq(_^*g{{z8MQgE5BDaDpYM6%2fyMY`+xw-iy(jeZ6C%%wU*t?%c**4?g(R&#YhQ|0Jad zaJ&F=>rZ|fFM*uc7%4D!c#r-#BkyKI{*D&_o5+CQm_C5K(Fh#a3KRg z73LQr=9eeoC)!KPtnAy1suF_IoU4&U5oLI&B?-m~T6PATn_XN{0O*;s8|VM~KOXr+ z7t7zi(Ai*k5iVRjYXGt_t<`z^Ro5Px>s@*D;3qn@K4A6q=?nbVf7~?*UoinRAb5s@ zg0=M=W0+{PY!yBPrO|A%y1JM0>mf~}Dm;KOmNc?h3=xJR%kkbrN%yVHEnk1d!r!be z)PDWpv%O`2>u$cv@Eqh9KJTr0fsz}qzdi@vH;VN8TaEOpcB`R21mf7r6OW$Y{<|K; z$aJb(BvLd05*QAZbLVp=1ftl`-WvfRMoH5e$1gixeO?e+dumJxmWBEpK?CYNVhn4Y zZq)(C3a1`>3=KZyxi{rqrWemZWiL_2Y(v?ANPH;>BD7-}F_#DF8qC-M_g9 z)mxAL@9=x(=kj`*8USN0k3I4@_uq3rCb3{37$AZWKm@W(Ie9Wey%Gw=J7sA#LKVaa zs>;ghDsim_K;b;iR?1w>k{Cl|3`rCdO~RMF_jLOMjI|gW0fz1Mb<`^aFap~fPA)!m zs>s*Ye+>;E3TUel3A@NgT(QKnkYE0pk1${UHGg*CZQkbUyDq=-z~Vx)rpAgGu|!GC zqxU_?`P1jBk@tY}3V;|;52sFM1W);XfTe>8X0)yJW(=-k%*}*%UR#pU_u~?Ql5C=eo$Yn6oamkjiv)30IXbdl(jyG z7w4i2Kmny_UwaOo&R*!P?|;*quKxEoz2(~68ch+wtAh7Dbl;c`yzsel4Wsa1+Nb8J;8ep95_H6#rO~a2*Kit9I*}?8KNj= ztGmsV6~o2zXUUyM#9#n4;G8n0LGcEPtu8A|%fE)mJMG*j$aj6%wd|5EFVAPd6L0wz z*B_s6)~X+*3jg)5cQF|BNM^zdR17Ci^vQFr*7{aEV*lY3RVw@UAI6yJlvUDtN~_gm zr;vj(Wyta&gW(WsEFyv`oO<#pyz@K0ComcWjG?+5oPj*c{hPk+&GtgieH8H9&sYTC z>P@c^AlqE){@a_~a?SBQa}5PBVsOs$Z~uHdo10q{xzg)7f`*y!LE+TN;Y|2uE8_6c zIZ%UO2ns7JtAH>S#S!&d4e$M=h2Rkk2o+V&csxR2@_Fway{%0M0b`^Jla0&p6$@4% zttIy4qbKrX2iiaQFaPyKjq208Sc$*%mYXjBwADi^t|+_}1EXQazx~4<4Elqz&?v+; zAxbR)CJhlf>jk5cCj=%M4a=e9O+rva1VLC_*~dbArL5i}Xz(=Wn^gz^Yt5t%M3KST zvWOc2#X8pCp2pDQ9!J<40;1@{ipw_{xEBxIcI1zBFv8P z-A)z0va~P7t0&7G&UxY}VfDyy)D=u6v0!X9>_`+(3LSxph@n3iu#+_~9&VA=EG7c6 zl!ebTBcON!fq)t%7-eH^liUB}*7xrA#^%xcAF>8upWhRuz20F+P`;Rsw2@Y9W$VZsBm2eJEK2vfZ~Iv2#&cu5z($-tNRaX9WDVagKN$p=q=FhYakoZzGMI(- zLM@oJ&Xxf52HT&AANw<>*UX)_-H(k-Rmrh}iK>E!2z2`e-EPj5s+k;MXDAt;sMFq?#*(#f^I#h_o1W#zOF3ge*%!wly= zC=kjP^1y*ZtK?ZeDc&}fRlv)~zS9)|&G&uF%hy&K#y15~9W+TDGW~Sf`x{mFw z94u68{X#;!9WxbFnVW0TUS0tx_w7+kEs1C~YwV;7qpV;j4W6ydEo>A6ifSOBoOtv} z#26|8I%|2kT0~UKa_&4kC27K&zU_@s{)s>&|U-$00b9MUy#l(p@2YToO>$M8yy?x$+K+ob{s`SX^r(W zYlzu37(EYw_W|#BR7nd45Xzae&~6bWmi4uaCr)HUbuR!>;T7Pp3H*NC)N-nWSM`e*^I3L2q2)O^@N~032!Wu zAffQ654b$Axt8r3DL8b+B>aT2<&2qMTEr^^@2BA>C%!n2X6_dGBH#*-2Awp3;0yZQ z&NO^w&>d23$$j~EjRy{|JP!lbvTy$qwX{Zm)RE?5GSa|f-Uk~QYcRm_z7={;4zXqU z8Lm*eT~FGG%EIFV1m*A>!|zh7&0%eV4;~+wXw+*o8Z~yAgr`)68;wU0S*)1yy7z%1 zFBlKUAi_@LQ9u=R$ABO_O}&<~w9@9>*^4;mY3;H9K$^HlT6XgrM@Iqbtr#S*Q&8yj zJpdXYipssf-orIaXo3L;joVpgNZCQj!7CR zz3tJ{!smtJ95brUsFo}6&U56lg9PWx*=J+2%>N@0iYx>JV6Bz43mqPM_&g@IgdO3x zw>%oCcn|GmOPWG(9#`bJ@emPcwiaeWIqz9nUc?#;fl`3rAnY!DMi>mblkgP-<3UE2 zjWO0%O$-cs0b`gY%n&scnd1#t9wHxS#MXvuuD#07FV5ddNe#dgkDmRvfBDC|i!4`P z6rc))ht8%W=J^1|ao z0E9trNRhjlkb!da0n~%{;EVEgP-Q2VJ1)EY5L;V4Hn;jZ&eax${s~Z25kBUo{SrWd zpV||rpLzMgrV_k3r@NLr;oz}3)CVwCb)P)Qm|xh7YG9{Eqdrr~C$+=cNub?^!y(=7 z*325O0oKp0;qn4w&5lrk&W1w+GlKCT3V<vp>{;ep9DI~YZ2$yH^_2jJoa{!7as~xs1H!G z0LyV218X7hsr9_6PVSV4qJ9Hp$R>_hPgFntlnF-elJn;{@&dIS&@ zV+~uK4t`f6vBLRN7ZBN*3IecxE+-&}VdnF}1a@ogv21Mgh-wYSx&N=;VD!~K1OdYC z8c;M_#!AEoXsUFxLhG#vRaiaPz(&FhV_4q10*2~Bgfm8a#=$SP_IW ze0QUZsx&r(I*Ni4mD;01<)RRF&~?z?3zH*jkKN`r89`)1o|w zV4zZ+0TlI28h|yHY!nz4z8DuFj%(@n1ApW8*4e^ zTw@>jCE&{*zVAT`PiNU>W$!}T+|&LQAM`5~l{iUQTw0=(Vj8TSN6eYOrtrF;@1i;Cw;uM&xct5k>?8wdNep zq}a8w@m|RaPp7kqFA5;cJRt3C_9xf&Zbh!-S%6ZtVmOy$5}`0cZyeal9fREaUgm6f zoc%5EVU&s&^Zx-#>9_mi;%5gr=KT7AjX{Bl7D&^1N{VyY3r}6Rd(}PMv-R( zEe|=q$O$2!zP!_GBEwE1(Cd1P%r1HD3Ej-m9TkiV&(^rG+r#{?f%mw$ zIZAjQmS+)L69IobcCM$G_Y7VMBAh?BMsKT!YM|MiW3jzd-4j%%OQlRIyoj*dc+j2M zG%4lOf8$wX_a;dMiUKw_azL41Y;pLCRc?H%t2lQ3QN{(Vb^4q-)A5<}W-#`napu1S z_yTK*fZ`>001)Qp8V2|ek?7BI=RUbN%G||^7i{5!j7E;$_KkVbp3Y_uL8{LMRRmbOkaOtRUM|1+C`*SIX|`KrUO2nf^jMT; zJ>|f`Hdnl1nKW&X#8J5_SO`D}fnMh#K7^-@a%X)&zdIy~BE%Y!v__-VAgR?!TTO;z zM{k%h&OBM}ktotp;l+8#hU4L#|8w8B$4T@Z)kDu0LB8Wt-ia4L3a_TKx#@v#$%g&U zx7O_GTo^fvku;X~OGg(vqKoKpoXhF-H#`wAoStH2OYUIzJ+_rI1GNk-#QeD1^`r}SBGY#Q{Y zrF}Kh)L=xgMpObC86(yRfXuh&Iex`)ymw4>2jwbIIMu?dI_L4;ncxFdOh3S_zz@&Q zH~*MY0yrS>GRPOc-xa(>a{95J2|+!jcSvgXs>S8x?KJS#z?B*x_&}N8xHygF%4^<$ za|IxXz+jl;6#=cD#ApaT%E12)+yUk>4EIs8wOTCz$}2!V^BoWKDtfcv_yFKtjhI7# zKYHbH;v@#Z0HfUFydP0k?|%aRQN7=SiU7*1L_YGy{k(#ty_gta(pHZg%Xsl(^=*`r0c|tBUz3|00000 LNkvXXu0mjfBdh~b diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_square.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_square.png index 0a0d0722f04dc5c5f9ab7b897ee456e5f3de8e00..c5af8fc76f739c175932c2fcff2e82382a8e2d87 100644 GIT binary patch literal 1467 zcmV;s1w{IZP)_@IA%``z*TfB)ju{!HYN!jzNL5M>T7LlM3A3;C`GXsDyrRP)pL?q0* zeIeVO?r)V9F~WmHNDEr$uwZ8MK;ZFsv;%aWEb01^00LEH`Sg8*qk*TsH5oq0Ot%QVgv(b)YyQ!DGFi6zh zETSi`=QAOPdGF`#ye;!?iD7;1!=`D<@L@~Q&Exey#XlVHeGGj#9JY#Y-!9ezKqLU1 zw?_t#;Uc6}5BD9(06Y&uBs%qX-(B>_!|B6^ML)dnSWl&=H2@$X9|;U*Y&PQQ;V4x` z?@|N-H}`C!m;HyMoer+Mz21FVUf0Q#%1zWDs^=BqDW?<*&MWvke!v zswj1OIJIV(;TitnaH7i{ox4t!x_wNs23`-SWTW97{%W3I!K1YJMAk8h# zZSn1HGndOgM!2ceIYGk`L@JsHVN$7{zN~4Zn@48Wf@N*+*uQ+4z*GErZKDrWl{yuz zI!#lpN=a+)No%ch74D;2L}oI0yK_-;OIBvWMSpwS){viiaQ?@?=*k|@a}S<-@Z5vv z9{jI+@Ta$bo9Eda;Wo@7(9MNN1zKwFqkAGE!@sTfMIb^?@{c|E_MO)v?)MN- zBC17tH^4JNBtWn|j9+`73r}F}f+gEp2 zdEHEviwI-0*-TU6q|@4hPPg;Ttg^OgL}Vm`U)-1$wh>o(`sNM*L_iF4s2~Y&i~tg5 zaKq@J3ILkeY_9XFj5H9#8k8Xf5ro1QM1maFLBI@%0KnD$?hQr*04eYebEu+BSXRUU zGlm2Hu?P6%XV-bXdAZr&-u$%hqN6vrF;y|k_4J_gG`bfN8x2&D15~c^`s&rI%~pv; z!8+GI;&eF98*%q>bMtZE&#hO{kuhtz%FA!RoR@W|(AsSs3!#H(3{U1wRVpmZ-BU{u zAxjyfUFCK31}SUG`S?J{K5ShdUTj~~?ae9rSkG%8o6RQO+Bi;S|9JgR_wrek{i5T!32*DFVSNgBE@BwouAsozz4q=#KJpl+#f(IGqXdi(Fb<6{r5^3OeZ?!j{po_p}zga3;j{0F$@ V^9&(V#+3j7002ovPDHLkV1hN>%PIf> literal 982 zcmV;{11bE8P)hgPnJR=bg3 z!IWROkzc@*Ua^c_hgL6uQ!a;CFMv@lf>bVjPc4L2Fo#(&eo!ueRW5>7E`(Yzhg&g= zT``ARFM?PubVn?7Ni1f%hghb4QkHB!mTf|ra6^@DL78$xoOMW=b4H+hP<>G?gjg_( zU@?hbF?L2QbVMv}KPq%ZEO<#QfKM)cO)Yy$EqhEYdPyv9L@IVmEP72WdQU8SPAzy$ zEO<&Rsf1OgfK;o5SE_|pw2WM?iCVCWT)2^9w~}F~gjSPkKa*`imT*LuaYdkdQlfiO zse)CigI1w?PnObvEdT%kb3b*BjT+Xy-5ph*mcFp$U)xkz{@)<`i;zJy6hgLQE3t}ygPj;x2swaRb`e6O z?QNp6^+KZA_L`Vj2sz4fr?pFMO9`Deu{nbaAtw{kLMSc37A})o&A>v)Sr!AE2q6$^ z<};h{XCdTLg5_>|0+p>*{9XtNF894Fgm3LA%yyN~Z8IVHic|>MnaXY|n>x=xr}|N+ ztA*b*>xS+^$d+8=Gh6G%);e7-guh%OblIGb3L&>xe4{N`={7K&Qpo&v)R+mFMrDxwP0Iw#v_i-}Hp>LeW`&TGRGEOO3L&RRnSe=!kV~{?0;aVP za+#C~m{bS}*?=j8Y-)#0!0b>6x!EU~fcc~la;uaHm{bV4Pn`*vx)Ac9DibhOA>>KD zG6B=85c0H?37Av}*(uv6j}$`e)R0MwN1wpF diff --git a/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_square_inv.png b/mods/homedecor_modpack/homedecor_tables/textures/homedecor_wood_table_small_square_inv.png index a36081d32e7789fff90197c6c628ec4907e7d094..9b84a0f0af9b326172d377cd9962af8fb2ea78bd 100644 GIT binary patch literal 901 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 8 then - y = y_delta + 1.9 + y = yoffs + yspc else - y = y_delta + y = yoffs end - formspec = formspec.."image_button["..x..","..y..";1,2;".. - minetest.formspec_escape(skin:get_preview())..";skins_set$"..i..";]".. + formspec = formspec.. + string.format("image_button[%f,%f;%f,%f;%s;skins_set$%i;]", + x, y, skinwidth, skinheight, + minetest.formspec_escape(skin:get_preview()), i).. "tooltip[skins_set$"..i..";"..minetest.formspec_escape(skin:get_meta_string("name")).."]" end @@ -87,10 +143,13 @@ function skins.get_skin_selection_formspec(player, context, y_delta) if pg > 1 then page_list = page_list.."," end page_list = page_list..pagename end - formspec = formspec - .."button[0,"..(y_delta+4.0)..";1,.5;skins_page$"..page_prev..";<<]" - .."dropdown[0.9,"..(y_delta+3.88)..";6.5,.5;skins_selpg;"..page_list..";"..page.."]" - .."button[7,"..(y_delta+4.0)..";1,.5;skins_page$"..page_next..";>>]" + formspec = formspec.. + string.format("button[%f,%f;%f,%f;skins_page$%i;<<]", + xoffs, btn_y, btn_width, ctrls_height, page_prev).. + string.format("button[%f,%f;%f,%f;skins_page$%i;>>]", + btn_right, btn_y, btn_width, ctrls_height, page_next).. + string.format("dropdown[%f,%f;%f,%f;skins_selpg;%s;%i]", + droppos, drop_y, droplen, ctrls_height, page_list, page) end return formspec end diff --git a/mods/skinsdb/mod.conf b/mods/skinsdb/mod.conf index 51ba162a..b79cd343 100644 --- a/mods/skinsdb/mod.conf +++ b/mods/skinsdb/mod.conf @@ -2,3 +2,4 @@ name = skinsdb description = Player skin mod, supporting unified_inventory, sfinv and smart_inventory depends = player_api optional_depends = unified_inventory,3d_armor,clothing,sfinv +min_minetest_version = 5.4.0 diff --git a/mods/skinsdb/textures/ui_misc_form.png b/mods/skinsdb/textures/ui_misc_form.png deleted file mode 100644 index 2a7edb9d51f4cc3bfeb04861868b8a366ea56d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6177 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 H^WDDyE1|wV diff --git a/mods/skinsdb/unified_inventory_page.lua b/mods/skinsdb/unified_inventory_page.lua index 3bf9575e..d39ee4f4 100644 --- a/mods/skinsdb/unified_inventory_page.lua +++ b/mods/skinsdb/unified_inventory_page.lua @@ -1,10 +1,13 @@ local S = minetest.get_translator("skinsdb") unified_inventory.register_page("skins", { - get_formspec = function(player) + get_formspec = function(player, perplayer_formspec) local skin = skins.get_player_skin(player) - local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]"..skins.get_skin_info_formspec(skin).. - "button[.75,3;6.5,.5;skins_page;"..S("Change").."]" + local boffs = (type(perplayer_formspec) == "table") and 2 or 0.75 + + local formspec = perplayer_formspec.standard_inv_bg.. + skins.get_skin_info_formspec(skin, perplayer_formspec).. + "button["..boffs..",3;6.5,.5;skins_page;"..S("Change").."]" return {formspec=formspec} end, }) @@ -15,16 +18,16 @@ unified_inventory.register_button("skins", { tooltip = S("Skins"), }) -local function get_formspec(player) +local function get_formspec(player, perplayer_formspec) local context = skins.get_formspec_context(player) - local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]".. - skins.get_skin_selection_formspec(player, context, -0.2) + local formspec = perplayer_formspec.standard_inv_bg.. + skins.get_skin_selection_formspec(player, context, perplayer_formspec) return formspec end unified_inventory.register_page("skins_page", { - get_formspec = function(player) - return {formspec=get_formspec(player)} + get_formspec = function(player, perplayer_formspec) + return {formspec=get_formspec(player, perplayer_formspec)} end }) diff --git a/mods/unified_inventory/init.lua b/mods/unified_inventory/init.lua index 231da9e9..ef42533b 100644 --- a/mods/unified_inventory/init.lua +++ b/mods/unified_inventory/init.lua @@ -49,6 +49,8 @@ local ui = unified_inventory ui.style_full = { formspec_x = 1, formspec_y = 1, + formw = 17.75, + formh = 12.25, pagecols = 8, pagerows = 10, page_x = 10.75, @@ -80,6 +82,8 @@ ui.style_full = { ui.style_lite = { formspec_x = 0.6, formspec_y = 0.6, + formw = 14, + formh = 9.75, pagecols = 4, pagerows = 6, page_x = 10.5, diff --git a/mods/unified_inventory/internal.lua b/mods/unified_inventory/internal.lua index d92b932f..215a4f5a 100644 --- a/mods/unified_inventory/internal.lua +++ b/mods/unified_inventory/internal.lua @@ -40,18 +40,15 @@ function ui.get_formspec(player, page) if not pagedef then return "" -- Invalid page name end - + local formspec = { - "formspec_version[4]size[17.75,12.25]", + "formspec_version[4]", + "size["..ui_peruser.formw..","..ui_peruser.formh.."]", pagedef.formspec_prepend and "" or "no_prepend[]", - ui.standard_background -- Background + ui.standard_background } - local n = 4 - if draw_lite_mode then - formspec[1] = "formspec_version[4]size[14,9.75]" - formspec[3] = ui.standard_background - end + local n = 5 local perplayer_formspec = ui.get_per_player_formspec(player_name) local fsdata = pagedef.get_formspec(player, perplayer_formspec) diff --git a/mods/unifieddyes/airbrush.lua b/mods/unifieddyes/airbrush.lua new file mode 100644 index 00000000..44f155f0 --- /dev/null +++ b/mods/unifieddyes/airbrush.lua @@ -0,0 +1,498 @@ +-- This file supplies all the code related to the airbrush + +local S = minetest.get_translator("unifieddyes") + +function unifieddyes.on_airbrush(itemstack, player, pointed_thing) + local player_name = player:get_player_name() + local painting_with = nil + + if unifieddyes.player_current_dye[player_name] then + painting_with = unifieddyes.player_current_dye[player_name] + end + + if not painting_with then + minetest.chat_send_player(player_name, "*** You need to set a color first.") + minetest.chat_send_player(player_name, "*** Right-click any random node to open the color selector,") + minetest.chat_send_player(player_name, "*** or shift+right-click a colorized node to use its color.") + minetest.chat_send_player(player_name, "*** Be sure to click \"Accept\", or the color you select will be ignored.") + return + end + + local pos = minetest.get_pointed_thing_position(pointed_thing) + if not pos then + local look_angle = player:get_look_vertical() + if look_angle > -1.55 then + minetest.chat_send_player(player_name, "*** No node selected") + else + local hexcolor = unifieddyes.get_color_from_dye_name(painting_with) + if hexcolor then + local r = tonumber(string.sub(hexcolor,1,2),16) + local g = tonumber(string.sub(hexcolor,3,4),16) + local b = tonumber(string.sub(hexcolor,5,6),16) + player:set_sky({r=r,g=g,b=b,a=255},"plain") + end + end + return + end + + local node = minetest.get_node(pos) + local def = minetest.registered_items[node.name] + if not def then return end + + if minetest.is_protected(pos, player_name) then + minetest.chat_send_player(player_name, "*** Sorry, someone else owns that node.") + return + end + + if not (def.groups and def.groups.ud_param2_colorable and def.groups.ud_param2_colorable > 0) then + minetest.chat_send_player(player_name, "*** That node can't be colored.") + return + end + + local palette = nil + local fdir = 0 + if not def or not def.palette then + minetest.chat_send_player(player_name, "*** That node can't be colored -- it's either undefined or has no palette.") + return + elseif def.palette == "unifieddyes_palette_extended.png" then + palette = "extended" + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + palette = "wallmounted" + fdir = node.param2 % 8 + elseif def.palette ~= "unifieddyes_palette_extended.png" + and def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(def.palette, "unifieddyes_palette_") then + palette = "split" + fdir = node.param2 % 32 + else + minetest.chat_send_player(player_name, "*** That node can't be colored -- it has an invalid color mode.") + return + end + + local idx, hue = unifieddyes.getpaletteidx(painting_with, palette) + local inv = player:get_inventory() + if (not creative or not creative.is_enabled_for(player_name)) and not inv:contains_item("main", painting_with) then + local suff = "" + if not idx then + suff = " Besides, "..string.sub(painting_with, 5).." can't be applied to that node." + end + minetest.chat_send_player(player_name, "*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff) + return + end + + if not idx then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + + local oldidx = node.param2 - fdir + local name = def.airbrush_replacement_node or node.name + + if palette == "split" then + + local modname = string.sub(name, 1, string.find(name, ":")-1) + local nodename2 = string.sub(name, string.find(name, ":")+1) + local oldcolor = "snozzberry" + local newcolor = "razzberry" -- intentionally misspelled ;-) + + if def.ud_color_start and def.ud_color_end then + oldcolor = string.sub(node.name, def.ud_color_start, def.ud_color_end) + newcolor = string.sub(painting_with, 5) + else + if hue ~= 0 then + newcolor = unifieddyes.HUES_EXTENDED[hue][1] + else + newcolor = "grey" + end + + if def.airbrush_replacement_node then + oldcolor = "grey" + else + local s = string.sub(def.palette, 21) + oldcolor = string.sub(s, 1, string.find(s, "s.png")-1) + end + end + + name = modname..":"..string.gsub(nodename2, oldcolor, newcolor) + + if not minetest.registered_items[name] then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + elseif idx == oldidx then + return + end + minetest.swap_node(pos, {name = name, param2 = fdir + idx}) + if not creative or not creative.is_enabled_for(player_name) then + inv:remove_item("main", painting_with) + return + end +end + +local hps = 0.6 -- horizontal position scale +local vps = 1.3 -- vertical position scale +local vs = 0.1 -- vertical shift/offset + +local color_button_size = ";0.75,0.75;" +local color_square_size = ";0.69,0.69;" + +function unifieddyes.make_readable_color(color) + -- is this a low saturation color? + local has_low_saturtation = string.find(color, "s50"); + + -- remove _s50 tag, we care about that later again + local s = string.gsub(color, "_s50", "") + + -- replace underscores with spaces to make it look nicer + local s = string.gsub(s, "_", " ") + + -- capitalize words, you know, looks nicer ;) + s = string.gsub(s, "(%l)(%w*)", function(a,b) return string.upper(a)..b end) + + -- add the word dye, this is what the translations expect + s = s.." Dye" + + -- if it is a low sat color, append an appropriate string + if has_low_saturtation then + s = s.." (low saturation)" + end + + return s +end + +function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + + local dye = "dye:"..colorname + + local overlay = "" + local colorize = minetest.formspec_escape("^[colorize:#"..hexcolor..":255") + + if not creative and inv:contains_item("main", dye) then + overlay = "^unifieddyes_onhand_overlay.png" + end + + local unavail_overlay = "" + if not showall and not unifieddyes.palette_has_color[nodepalette.."_"..colorname] + or (explist and not explist[colorname]) then + if overlay == "" then + unavail_overlay = "^unifieddyes_unavailable_overlay.png" + else + unavail_overlay = "^unifieddyes_onhand_unavailable_overlay.png" + end + end + + local tooltip = "tooltip["..colorname..";".. + S(unifieddyes.make_readable_color(colorname)).. + "\n(dye:"..colorname..")]" + + if dye == painting_with then + overlay = "^unifieddyes_select_overlay.png" + selindic = "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]"..tooltip + end + + local form + if unavail_overlay == "" then + form = "image_button[".. + (hp*hps)..","..(v2*vps+vs).. + color_button_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay..";".. + colorname..";]".. + tooltip + else + form = "image[".. + (hp*hps)..","..(v2*vps+vs).. + color_square_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]".. + tooltip + end + + return form, selindic +end + +function unifieddyes.show_airbrush_form(player) + if not player then return end + + local t = {} + + local player_name = player:get_player_name() + local painting_with = unifieddyes.player_selected_dye[player_name] or unifieddyes.player_current_dye[player_name] + local creative = creative and creative.is_enabled_for(player_name) + local inv = player:get_inventory() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + t[1] = "size[14.5,8.5]label[7,-0.3;"..S("Select a color:").."]" + local selindic = "unifieddyes_select_overlay.png^unifieddyes_question.png]" + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click then + if last_right_click.def and last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette == "unifieddyes_palette_extended.png" then + t[#t+1] = "label[0.5,8.25;"..S("(Right-clicked a node that supports all 256 colors, showing them all)").."]" + showall = true + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" + and last_right_click.def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(last_right_click.def.palette, "unifieddyes_palette_") then + nodepalette = "split" + end + end + end + + if not last_right_click.def.groups + or not last_right_click.def.groups.ud_param2_colorable + or not last_right_click.def.palette + or not string.find(last_right_click.def.palette, "unifieddyes_palette_") then + t[#t+1] = "label[0.5,8.25;"..S("(Right-clicked a node not supported by the Airbrush, showing all colors)").."]" + end + + local explist = last_right_click.def.explist + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local sat = "" + local v2=(v/2) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 40 + if v > 3 then + factor = 75 + v2 = (v-2) + end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local hexcolor = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + + if v > 3 then + sat = "_s50" + v2 = (v-1.5) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 75 + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local hexcolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + end + end + + local v2=5 + for y = 0, 15 do + + local hp=15-y + + local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + + local f + f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + + end + + if not creative then + t[#t+1] = "image[10," + t[#t+1] = (vps*5.55+vs) + t[#t+1] = color_button_size + t[#t+1] = "unifieddyes_onhand_overlay.png]label[10.7," + t[#t+1] = (vps*5.51+vs) + t[#t+1] = ";"..S("Dyes").."]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.67+vs) + t[#t+1] = ";on hand]" + + end + + t[#t+1] = "image[10," + t[#t+1] = (vps*5+vs) + t[#t+1] = color_button_size + t[#t+1] = selindic + + if painting_with then + t[#t+1] = "label[10.7," + t[#t+1] = (vps*4.90+vs) + t[#t+1] = ";"..S("Your selection:").."]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";" + t[#t+1] = S(unifieddyes.make_readable_color(string.sub(painting_with, 5))) + t[#t+1] = "]label[10.7," + t[#t+1] = (vps*5.24+vs) + t[#t+1] = ";(" + t[#t+1] = painting_with + t[#t+1] = ")]" + else + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";"..S("Your selection").."]" + end + + t[#t+1] = "button_exit[10.5,8;2,1;cancel;"..S("Cancel").."]button_exit[12.5,8;2,1;accept;"..S("Accept").."]" + + + if last_right_click and last_right_click.def and nodepalette ~= "extended" then + if showall then + t[#t+1] = "button[0,8;2,1;show_avail;"..S("Show Available").."]" + t[#t+1] = "label[2,8.25;"..S("(Currently showing all 256 colors)").."]" + else + t[#t+1] = "button[0,8;2,1;show_all;"..S("Show All Colors").."]" + t[#t+1] = "label[2,8.25;"..S("(Currently only showing what the right-clicked node can use)").."]" + end + end + + minetest.show_formspec(player_name, "unifieddyes:dye_select_form", table.concat(t)) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname == "unifieddyes:dye_select_form" then + + local player_name = player:get_player_name() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click and last_right_click.def then + if last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" then + nodepalette = "split" + end + end + end + + if fields.show_all then + unifieddyes.player_showall[player_name] = true + unifieddyes.show_airbrush_form(player) + return + elseif fields.show_avail then + unifieddyes.player_showall[player_name] = false + unifieddyes.show_airbrush_form(player) + return + elseif fields.quit then + if fields.accept then + local dye = unifieddyes.player_selected_dye[player_name] + if not dye then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but no color was selected!") + return + elseif not showall + and not unifieddyes.palette_has_color[nodepalette.."_"..string.sub(dye, 5)] then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but the selected color can't be used on the") + minetest.chat_send_player(player_name, "*** node that was right-clicked (and \"Show All\" wasn't in effect).") + if unifieddyes.player_current_dye[player_name] then + minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "..string.sub(unifieddyes.player_current_dye[player_name], 5)..".") + else + minetest.chat_send_player(player_name, "*** Ignoring it.") + end + return + else + unifieddyes.player_current_dye[player_name] = dye + unifieddyes.player_selected_dye[player_name] = nil + minetest.chat_send_player(player_name, "*** Selected "..string.sub(dye, 5).." for the airbrush.") + return + end + else -- assume "Cancel" or Esc. + unifieddyes.player_selected_dye[player_name] = nil + return + end + else + local s1 = string.sub(minetest.serialize(fields), 11) + local s3 = string.sub(s1,1, string.find(s1, '"')-1) + + local inv = player:get_inventory() + local creative = creative and creative.is_enabled_for(player_name) + local dye = "dye:"..s3 + + if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and + (minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then + unifieddyes.player_selected_dye[player_name] = dye + unifieddyes.show_airbrush_form(player) + end + end + end +end) + +minetest.register_tool("unifieddyes:airbrush", { + description = S("Dye Airbrush"), + inventory_image = "unifieddyes_airbrush.png", + use_texture_alpha = true, + tool_capabilities = { + full_punch_interval=0.1, + }, + range = 12, + on_use = unifieddyes.on_airbrush, + on_place = function(itemstack, placer, pointed_thing) + local keys = placer:get_player_control() + local player_name = placer:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node + local def + + if pos then node = minetest.get_node(pos) end + if node then def = minetest.registered_items[node.name] end + + unifieddyes.player_last_right_clicked[player_name] = {pos = pos, node = node, def = def} + + if not keys.aux1 then + unifieddyes.show_airbrush_form(placer) + elseif keys.aux1 then + if not pos or not def then return end + local newcolor = unifieddyes.color_to_name(node.param2, def) + + if newcolor and string.find(def.paramtype2, "color") then + minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.") + unifieddyes.player_current_dye[player_name] = "dye:"..newcolor + else + minetest.chat_send_player(player_name, "*** That node is uncolored.") + end + elseif def.on_rightclick then + return def.on_rightclick(pos, node, placer, itemstack, pointed_thing) + end + end +}) diff --git a/mods/unifieddyes/aliases.lua b/mods/unifieddyes/aliases.lua new file mode 100644 index 00000000..785eb588 --- /dev/null +++ b/mods/unifieddyes/aliases.lua @@ -0,0 +1,23 @@ +minetest.register_alias("dye:light_red", "dye:pink") +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") +minetest.register_alias("unifieddyes:grey_8", "dye:grey") +minetest.register_alias("unifieddyes:grey_11", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_15", "dye:white") + +minetest.register_alias("unifieddyes:white_paint", "dye:white") +minetest.register_alias("unifieddyes:titanium_dioxide", "dye:white") +minetest.register_alias("unifieddyes:lightgrey_paint", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_paint", "dye:grey") +minetest.register_alias("unifieddyes:darkgrey_paint", "dye:dark_grey") +minetest.register_alias("unifieddyes:carbon_black", "dye:black") + +minetest.register_alias("unifieddyes:brown", "dye:brown") diff --git a/mods/unifieddyes/api.lua b/mods/unifieddyes/api.lua new file mode 100644 index 00000000..8b4eb14f --- /dev/null +++ b/mods/unifieddyes/api.lua @@ -0,0 +1,494 @@ +-- This file supplies the majority of Unified Dyes' API + +local S = minetest.get_translator("unifieddyes") + +unifieddyes.player_current_dye = {} +unifieddyes.player_selected_dye = {} +unifieddyes.player_last_right_clicked = {} +unifieddyes.palette_has_color = {} +unifieddyes.player_showall = {} + +-- if a node with a palette is placed in the world, +-- but the itemstack used to place it has no palette_index (color byte), +-- create something appropriate to make it officially white. + +minetest.register_on_placenode( + function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + local def = minetest.registered_items[newnode.name] + + if not def + or not def.palette + or def.after_place_node + or not placer then + return false + end + + local param2 + if not string.find(itemstack:to_string(), "palette_index") then + if def.palette == "unifieddyes_palette_extended.png" + and def.paramtype2 == "color" then + param2 = 240 + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" + and def.paramtype2 == "colorwallmounted" then + param2 = newnode.param2 % 8 + elseif string.find(def.palette, "unifieddyes_palette_") + and def.paramtype2 == "colorfacedir" then -- it's a split palette + param2 = newnode.param2 % 32 + end + + if param2 then + minetest.swap_node(pos, {name = newnode.name, param2 = param2}) + end + end + + if def.palette ~= "" then + minetest.get_meta(pos):set_int("palette_index", param2 or 240) + end + end +) + +-- The complementary function: strip-off the color if the node being dug is still white/neutral + +local function move_item(item, pos, inv, digger, fix_color) + if not (digger and digger:is_player()) then return end + local creative = creative_mode or minetest.check_player_privs(digger, "creative") + item = unifieddyes.fix_bad_color_info(item, fix_color) + if inv:room_for_item("main", item) + and (not creative or not inv:contains_item("main", item, true)) then + inv:add_item("main", item) + elseif not creative then + minetest.item_drop(ItemStack(item), digger, pos) + end + minetest.remove_node(pos) +end + +function unifieddyes.on_dig(pos, node, digger) + if not digger then return end + local playername = digger:get_player_name() + if minetest.is_protected(pos, playername) then + minetest.record_protection_violation(pos, playername) + return + end + + local oldparam2 = minetest.get_node(pos).param2 + local def = minetest.registered_items[node.name] + local fix_color + + if def.paramtype2 == "color" and oldparam2 == 240 and def.palette == "unifieddyes_palette_extended.png" then + fix_color = 240 + elseif def.paramtype2 == "color" and oldparam2 == 0 and def.palette == "unifieddyes_palette_extended.png" then + fix_color = 0 + elseif def.paramtype2 == "colorwallmounted" and math.floor(oldparam2 / 8) == 0 and def.palette == "unifieddyes_palette_colorwallmounted.png" then + fix_color = 0 + elseif def.paramtype2 == "colorfacedir" and math.floor(oldparam2 / 32) == 0 and string.find(def.palette, "unifieddyes_palette_") then + fix_color = 0 + end + + local inv = digger:get_inventory() + if fix_color then + move_item(node.name, pos, inv, digger, fix_color) + else + return minetest.node_dig(pos, node, digger) + end +end + +-- 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 creates multiple copies of the passed node, +-- for the split palette - one per hue, plus grey - and assigns +-- proper palettes and other attributes + +function unifieddyes.generate_split_palette_nodes(name, def, drop) + for _, color in ipairs(unifieddyes.HUES_WITH_GREY) do + local def2 = table.copy(def) + local desc_color = string.gsub(string.upper(string.sub(color, 1, 1))..string.sub(color, 2), "_", " ") + if string.sub(def2.description, -1) == ")" then + def2.description = string.sub(def2.description, 1, -2)..", "..desc_color.." shades)" + else + def2.description = def2.description.."("..desc_color.." shades)" + end + def2.palette = "unifieddyes_palette_"..color.."s.png" + def2.paramtype2 = "colorfacedir" + def2.groups.ud_param2_colorable = 1 + + if drop then + def2.drop = { + items = { + {items = {drop.."_"..color}, inherit_color = true }, + } + } + end + + minetest.register_node(":"..name.."_"..color, def2) + end +end + +-- This helper function creates a colored itemstack + +function unifieddyes.fix_bad_color_info(item, paletteidx) + local stack=minetest.itemstring_with_color(item, paletteidx) + return string.gsub(stack, "u0001color", "u0001palette_index") +end + +function unifieddyes.make_colored_itemstack(item, palette, color) + local paletteidx = unifieddyes.getpaletteidx(color, palette) + return unifieddyes.fix_bad_color_info(item, paletteidx), paletteidx +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, h, sat, val) + local hue = (type(h) == "table") and h[1] or h + local color = "" + if val then + if craft.palette == "wallmounted" then + color = val..hue..sat + else + color = val..hue..sat + end + else + color = hue -- if val is nil, then it's grey. + end + + local dye = "dye:"..color + local recipe = minetest.serialize(craft.recipe) + recipe = string.gsub(recipe, "MAIN_DYE", dye) + recipe = string.gsub(recipe, "NEUTRAL_NODE", craft.neutral_node) + local newrecipe = minetest.deserialize(recipe) + + local coutput = craft.output or "" + local output = coutput + if craft.output_prefix then + if craft.palette ~= "split" then + output = craft.output_prefix..color..craft.output_suffix..coutput + else + if hue == "white" or hue == "black" or string.find(hue, "grey") then + output = craft.output_prefix.."grey"..craft.output_suffix..coutput + elseif hue == "pink" then + dye = "dye:light_red" + output = craft.output_prefix.."red"..craft.output_suffix..coutput + else + output = craft.output_prefix..hue..craft.output_suffix..coutput + end + end + end + + local colored_itemstack = + unifieddyes.make_colored_itemstack(output, craft.palette, dye) + + minetest.register_craft({ + output = colored_itemstack, + type = craft.type, + recipe = newrecipe + }) + +end + +function unifieddyes.register_color_craft(craft) + local hues_table = unifieddyes.HUES_EXTENDED + local sats_table = unifieddyes.SATS + local vals_table = unifieddyes.VALS_SPLIT + local greys_table = unifieddyes.GREYS + + if craft.palette == "wallmounted" then + register_c(craft, "green", "", "light_") + register_c(craft, "blue", "", "light_") + hues_table = unifieddyes.HUES_WALLMOUNTED + sats_table = {""} + vals_table = unifieddyes.VALS + elseif craft.palette == "extended" then + vals_table = unifieddyes.VALS_EXTENDED + greys_table = unifieddyes.GREYS_EXTENDED + end + + for _, hue in ipairs(hues_table) do + for _, val in ipairs(vals_table) do + for _, sat in ipairs(sats_table) do + + if sat == "_s50" and val ~= "" and val ~= "medium_" and val ~= "dark_" then break end + register_c(craft, hue, sat, val) + + end + end + end + + for _, grey in ipairs(greys_table) do + register_c(craft, grey) + end + + register_c(craft, "pink") + +end + +-- code borrowed from homedecor +-- call this function to reset the rotation of a "wallmounted" object on place + +function unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw) -- -1.5) + local pitch = placer:get_look_vertical() + + local fdir = minetest.dir_to_wallmounted(dir) + + if pitch < -(math.pi/8) then + fdir = 0 + elseif pitch > math.pi/8 then + fdir = 1 + end + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- use this when you have a "wallmounted" node that should never be oriented +-- to floor or ceiling... + +function unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw+1.5) + local fdir = minetest.dir_to_wallmounted(dir) + + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- ... and use this one to force that kind of node off of floor/ceiling +-- orientation after the screwdriver rotates it. + +function unifieddyes.fix_after_screwdriver_nsew(pos, node, user, mode, new_param2) + local new_fdir = new_param2 % 8 + local color = new_param2 - new_fdir + if new_fdir < 2 then + new_fdir = 2 + minetest.swap_node(pos, { name = node.name, param2 = new_fdir + color }) + return true + end +end + +function unifieddyes.is_buildable_to(placer_name, ...) + for _, pos in ipairs({...}) do + local node = minetest.get_node_or_nil(pos) + local def = node and minetest.registered_nodes[node.name] + if not (def and def.buildable_to) or minetest.is_protected(pos, placer_name) then + return false + end + end + return true +end + +function unifieddyes.get_hsv(name) -- expects a node/item name + local hue = "" + local a,b + for _, i in ipairs(unifieddyes.HUES_EXTENDED) do + a,b = string.find(name, "_"..i[1]) + if a then + hue = i[1] + break + end + end + + if string.find(name, "_light_grey") then hue = "light_grey" + elseif string.find(name, "_lightgrey") then hue = "light_grey" + elseif string.find(name, "_dark_grey") then hue = "dark_grey" + elseif string.find(name, "_darkgrey") then hue = "dark_grey" + elseif string.find(name, "_grey") then hue = "grey" + elseif string.find(name, "_white") then hue = "white" + elseif string.find(name, "_black") then hue = "black" + end + + local sat = "" + if string.find(name, "_s50") then sat = "_s50" end + + local val = "" + if string.find(name, "dark_") then val = "dark_" end + if string.find(name, "medium_") then val = "medium_" end + if string.find(name, "light_") then val = "light_" end + + return hue, sat, val +end + +-- code partially borrowed from cheapie's plasticbox mod + +-- in the function below, color is just a color string, while +-- palette_type can be: +-- +-- "extended" = 256 color palette +-- "split" = 200 color palette split into pieces for colorfacedir +-- "wallmounted" = 32-color abridged palette + +function unifieddyes.getpaletteidx(color, palette_type) + + local origcolor = color + + if string.sub(color,1,4) == "dye:" then + color = string.sub(color,5,-1) + elseif string.sub(color,1,12) == "unifieddyes:" then + color = string.sub(color,13,-1) + else + return + end + + if palette_type == "wallmounted" then + if unifieddyes.gpidx_grayscale_wallmounted[color] then + return (unifieddyes.gpidx_grayscale_wallmounted[color] * 8), 0 + end + elseif palette_type == "split" then + if unifieddyes.gpidx_grayscale[color] then + return (unifieddyes.gpidx_grayscale[color] * 32), 0 + end + elseif palette_type == "extended" then + if unifieddyes.gpidx_grayscale_extended[color] then + return unifieddyes.gpidx_grayscale_extended[color]+240, 0 + end + end + + local shade = "" -- assume full + if string.sub(color,1,6) == "faint_" then + shade = "faint" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "pastel_" then + shade = "pastel" + color = string.sub(color,8,-1) + elseif string.sub(color,1,6) == "light_" then + shade = "light" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "bright_" then + shade = "bright" + color = string.sub(color,8,-1) + elseif string.sub(color,1,7) == "medium_" then + shade = "medium" + color = string.sub(color,8,-1) + elseif string.sub(color,1,5) == "dark_" then + shade = "dark" + color = string.sub(color,6,-1) + end + if string.sub(color,-4,-1) == "_s50" then + shade = shade.."s50" + color = string.sub(color,1,-5) + end + + if palette_type == "wallmounted" then + if color == "green" and shade == "light" then return 48,3 + elseif color == "brown" then return 17,1 + elseif color == "pink" then return 56,7 + elseif color == "blue" and shade == "light" then return 40,5 + elseif unifieddyes.gpidx_hues_wallmounted[color] and unifieddyes.gpidx_shades_wallmounted[shade] then + return (unifieddyes.gpidx_shades_wallmounted[shade] * 64 + unifieddyes.gpidx_hues_wallmounted[color] * 8), unifieddyes.gpidx_hues_wallmounted[color] + end + else + if color == "brown" then + color = "orange" + shade = "medium" + elseif color == "pink" then + color = "red" + shade = "light" + end + if palette_type == "split" then -- it's colorfacedir + if unifieddyes.gpidx_hues_extended[color] and unifieddyes.gpidx_shades_split[shade] then + return (unifieddyes.gpidx_shades_split[shade] * 32), unifieddyes.gpidx_hues_extended[color]+1 + end + elseif palette_type == "extended" then + if unifieddyes.gpidx_hues_extended[color] and unifieddyes.gpidx_shades_extended[shade] then + return (unifieddyes.gpidx_hues_extended[color] + unifieddyes.gpidx_shades_extended[shade]*24), unifieddyes.gpidx_hues_extended[color] + end + end + end +end + +function unifieddyes.get_color_from_dye_name(name) + if name == "dye:black" then + return "000000" + elseif name == "dye:white" then + return "ffffff" + end + local item = minetest.registered_items[name] + if not item then return end + local inv_image = item.inventory_image + if not inv_image then return end + return string.match(inv_image,"colorize:#(......):200") +end + +-- get a node's dye color based on its palette and param2 + +function unifieddyes.color_to_name(param2, def) + if not param2 or not def or not def.palette then return end + + if def.palette == "unifieddyes_palette_extended.png" then + local color = param2 + + local v = 0 + local s = 1 + if color < 24 then v = 1 + elseif color > 23 and color < 48 then v = 2 + elseif color > 47 and color < 72 then v = 3 + elseif color > 71 and color < 96 then v = 4 + elseif color > 95 and color < 120 then v = 5 + elseif color > 119 and color < 144 then v = 5 s = 2 + elseif color > 143 and color < 168 then v = 6 + elseif color > 167 and color < 192 then v = 6 s = 2 + elseif color > 191 and color < 216 then v = 7 + elseif color > 215 and color < 240 then v = 7 s = 2 + end + + if color > 239 then + if color == 240 then return "white" + elseif color == 244 then return "light_grey" + elseif color == 247 then return "grey" + elseif color == 251 then return "dark_grey" + elseif color == 255 then return "black" + else return "grey_"..15-(color-240) + end + else + local h = color - math.floor(color/24)*24 + return unifieddyes.VALS_EXTENDED[v]..unifieddyes.HUES_EXTENDED[h+1][1]..unifieddyes.SATS[s] + end + + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + local color = math.floor(param2 / 8) + if color == 0 then return "white" + elseif color == 1 then return "light_grey" + elseif color == 2 then return "grey" + elseif color == 3 then return "dark_grey" + elseif color == 4 then return "black" + elseif color == 5 then return "light_blue" + elseif color == 6 then return "light_green" + elseif color == 7 then return "pink" + end + local v = math.floor(color/8) + local h = color - v * 8 + return unifieddyes.VALS[v]..unifieddyes.HUES_WALLMOUNTED[h+1] + + elseif string.find(def.palette, "unifieddyes_palette") then -- it's the split palette + -- palette names in this mode are always "unifieddyes_palette_COLORs.png" + + local s = string.sub(def.palette, 21) + local color = string.sub(s, 1, string.find(s, "s.png")-1) + + local v = math.floor(param2/32) + if color ~= "grey" then + if v == 0 then return "faint_"..color + elseif v == 1 then return color + elseif v == 2 then return color.."_s50" + elseif v == 3 then return "light_"..color + elseif v == 4 then return "medium_"..color + elseif v == 5 then return "medium_"..color.."_s50" + elseif v == 6 then return "dark_"..color + elseif v == 7 then return "dark_"..color.."_s50" + end + else + if v > 0 and v < 6 then return unifieddyes.GREYS[v] + else return "white" + end + end + end +end diff --git a/mods/unifieddyes/color-tables.lua b/mods/unifieddyes/color-tables.lua new file mode 100644 index 00000000..12eaa325 --- /dev/null +++ b/mods/unifieddyes/color-tables.lua @@ -0,0 +1,237 @@ + +-- the names of the various colors here came from http://www.procato.com/rgb+index/ + +unifieddyes.HUES_EXTENDED = { + { "red", 0xff, 0x00, 0x00 }, + { "vermilion", 0xff, 0x40, 0x00 }, + { "orange", 0xff, 0x80, 0x00 }, + { "amber", 0xff, 0xbf, 0x00 }, + { "yellow", 0xff, 0xff, 0x00 }, + { "lime", 0xbf, 0xff, 0x00 }, + { "chartreuse", 0x80, 0xff, 0x00 }, + { "harlequin", 0x40, 0xff, 0x00 }, + { "green", 0x00, 0xff, 0x00 }, + { "malachite", 0x00, 0xff, 0x40 }, + { "spring", 0x00, 0xff, 0x80 }, + { "turquoise", 0x00, 0xff, 0xbf }, + { "cyan", 0x00, 0xff, 0xff }, + { "cerulean", 0x00, 0xbf, 0xff }, + { "azure", 0x00, 0x80, 0xff }, + { "sapphire", 0x00, 0x40, 0xff }, + { "blue", 0x00, 0x00, 0xff }, + { "indigo", 0x40, 0x00, 0xff }, + { "violet", 0x80, 0x00, 0xff }, + { "mulberry", 0xbf, 0x00, 0xff }, + { "magenta", 0xff, 0x00, 0xff }, + { "fuchsia", 0xff, 0x00, 0xbf }, + { "rose", 0xff, 0x00, 0x80 }, + { "crimson", 0xff, 0x00, 0x40 } +} + +unifieddyes.HUES_WITH_GREY = {} + +for _,i in ipairs(unifieddyes.HUES_EXTENDED) do + table.insert(unifieddyes.HUES_WITH_GREY, i[1]) +end +table.insert(unifieddyes.HUES_WITH_GREY, "grey") + +unifieddyes.HUES_WALLMOUNTED = { + "red", + "orange", + "yellow", + "green", + "cyan", + "blue", + "violet", + "magenta" +} + +unifieddyes.SATS = { + "", + "_s50" +} + +unifieddyes.VALS = { + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_SPLIT = { + "faint_", + "light_", + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_EXTENDED = { + "faint_", + "pastel_", + "light_", + "bright_", + "", + "medium_", + "dark_" +} + +unifieddyes.GREYS = { + "white", + "light_grey", + "grey", + "dark_grey", + "black" +} + +unifieddyes.GREYS_EXTENDED = table.copy(unifieddyes.GREYS) + +for i = 1, 14 do + if i ~= 0 and i ~= 4 and i ~= 8 and i ~= 11 and i ~= 15 then + table.insert(unifieddyes.GREYS_EXTENDED, "grey_"..i) + end +end + +local default_dyes = { + "black", + "blue", + "brown", + "cyan", + "dark_green", + "dark_grey", + "green", + "grey", + "magenta", + "orange", + "pink", + "red", + "violet", + "white", + "yellow" +} + +-- reverse lookups for getpaletteidx() + +unifieddyes.gpidx_aliases = { + ["pink"] = "light_red", + ["brown"] = "medium_orange", + ["azure"] = "light_blue" +} + +unifieddyes.gpidx_grayscale = { + ["white"] = 1, + ["light_grey"] = 2, + ["grey"] = 3, + ["dark_grey"] = 4, + ["black"] = 5, +} + +unifieddyes.gpidx_grayscale_extended = { + ["white"] = 0, + ["grey_14"] = 1, + ["grey_13"] = 2, + ["grey_12"] = 3, + ["light_grey"] = 4, + ["grey_11"] = 4, + ["grey_10"] = 5, + ["grey_9"] = 6, + ["grey_8"] = 7, + ["grey"] = 7, + ["grey_7"] = 8, + ["grey_6"] = 9, + ["grey_5"] = 10, + ["grey_4"] = 11, + ["dark_grey"] = 11, + ["grey_3"] = 12, + ["grey_2"] = 13, + ["grey_1"] = 14, + ["black"] = 15, +} + +unifieddyes.gpidx_grayscale_wallmounted = { + ["white"] = 0, + ["light_grey"] = 1, + ["grey"] = 2, + ["dark_grey"] = 3, + ["black"] = 4, +} + +unifieddyes.gpidx_hues_extended = { + ["red"] = 0, + ["vermilion"] = 1, + ["orange"] = 2, + ["amber"] = 3, + ["yellow"] = 4, + ["lime"] = 5, + ["chartreuse"] = 6, + ["harlequin"] = 7, + ["green"] = 8, + ["malachite"] = 9, + ["spring"] = 10, + ["aqua"] = 10, + ["turquoise"] = 11, + ["cyan"] = 12, + ["cerulean"] = 13, + ["azure"] = 14, + ["skyblue"] = 14, + ["sapphire"] = 15, + ["blue"] = 16, + ["indigo"] = 17, + ["violet"] = 18, + ["mulberry"] = 19, + ["magenta"] = 20, + ["fuchsia"] = 21, + ["rose"] = 22, + ["redviolet"] = 22, + ["crimson"] = 23, +} + +unifieddyes.gpidx_hues_wallmounted = { + ["red"] = 0, + ["orange"] = 1, + ["yellow"] = 2, + ["green"] = 3, + ["cyan"] = 4, + ["blue"] = 5, + ["violet"] = 6, + ["magenta"] = 7 +} + +unifieddyes.gpidx_shades = { + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, +} + +unifieddyes.gpidx_shades_split = { + ["faint"] = 0, + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, +} + +unifieddyes.gpidx_shades_extended = { + ["faint"] = 0, + ["pastel"] = 1, + ["light"] = 2, + ["bright"] = 3, + [""] = 4, + ["s50"] = 5, + ["medium"] = 6, + ["mediums50"] = 7, + ["dark"] = 8, + ["darks50"] = 9 +} + +unifieddyes.gpidx_shades_wallmounted = { + [""] = 1, + ["medium"] = 2, + ["dark"] = 3 +} diff --git a/mods/unifieddyes/dyes-crafting.lua b/mods/unifieddyes/dyes-crafting.lua new file mode 100644 index 00000000..2c11c41b --- /dev/null +++ b/mods/unifieddyes/dyes-crafting.lua @@ -0,0 +1,309 @@ +-- crafting! + +-- Generate all dyes that are not part of the default minetest_game dyes mod + +local S = minetest.get_translator("unifieddyes") + +for _, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local r = h[2] + local g = h[3] + local b = h[4] + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local factor = 40 + if v > 3 then factor = 75 end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + -- full-sat color + + local desc = hue:gsub("%a", string.upper, 1).." Dye" + + if val ~= "" then + desc = val:sub(1, -2):gsub("%a", string.upper, 1) .." "..desc + end + + local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + if minetest.registered_items["dye:"..val..hue] then + minetest.override_item("dye:"..val..hue, { + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + }) + else + if (val..hue) ~= "medium_orange" + and (val..hue) ~= "light_red" then + minetest.register_craftitem(":dye:"..val..hue, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + end + end + minetest.register_alias("unifieddyes:"..val..hue, "dye:"..val..hue) + + if v > 3 then -- also register the low-sat version + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local color = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + + minetest.register_craftitem(":dye:"..val..hue.."_s50", { + description = S(desc.." (low saturation)"), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") + end + end +end + +-- register the greyscales too :P + +for y = 1, 14 do -- colors 0 and 15 are black and white, default dyes + + if y ~= 4 and y ~= 8 and y~= 11 then -- don't register the three greys, they're done separately. + + local rgb = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local name = "grey_"..y + local desc = "Grey Dye #"..y + + minetest.register_craftitem(":dye:"..name, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..name, "dye:"..name) + end +end + +minetest.override_item("dye:grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#888888:200", +}) + +minetest.override_item("dye:dark_grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#444444:200", +}) + +minetest.register_craftitem(":dye:light_grey", { + description = S("Light grey Dye"), + inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200", + groups = { dye=1, not_in_creative_inventory=1 }, +}) + +-- build a table of color <-> palette associations to reduce the need for +-- realtime lookups with getpaletteidx() + +for _, palette in ipairs({"extended", "split", "wallmounted"}) do + local palette2 = palette + + for i in ipairs(unifieddyes.SATS) do + local sat = (palette == "wallmounted") and "" or unifieddyes.SATS[i] + for _, hue in ipairs(unifieddyes.HUES_EXTENDED) do + for _, val in ipairs(unifieddyes.VALS_EXTENDED) do + local color = val..hue[1]..sat + if unifieddyes.getpaletteidx("dye:"..color, palette2) then + unifieddyes.palette_has_color[palette.."_"..color] = true + end + end + end + end + + for y = 0, 15 do + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + if unifieddyes.getpaletteidx("dye:"..grey, palette2) then + unifieddyes.palette_has_color[palette.."_"..grey] = true + end + end +end + +unifieddyes.palette_has_color["wallmounted_light_red"] = true + +unifieddyes.base_color_crafts = { + { "red", "flowers:rose", nil, nil, nil, nil, 4 }, + { "vermilion", "dye:red", "dye:orange", nil, nil, nil, 3 }, + { "orange", "flowers:tulip", nil, nil, nil, nil, 4 }, + { "orange", "dye:red", "dye:yellow", nil, nil, nil, 2 }, + { "amber", "dye:orange", "dye:yellow", nil, nil, nil, 2 }, + { "yellow", "flowers:dandelion_yellow", nil, nil, nil, nil, 4 }, + { "lime", "dye:yellow", "dye:chartreuse", nil, nil, nil, 2 }, + { "lime", "dye:yellow", "dye:yellow", "dye:green", nil, nil, 3 }, + { "chartreuse", "dye:yellow", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:chartreuse", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:yellow", "dye:green", "dye:green", nil, nil, 3 }, + { "green", "default:cactus", nil, nil, nil, nil, 4 }, + { "green", "dye:yellow", "dye:blue", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:spring", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:green", "dye:cyan", nil, nil, 3 }, + { "malachite", "dye:green", "dye:green", "dye:green", "dye:blue", nil, 4 }, + { "spring", "dye:green", "dye:cyan", nil, nil, nil, 2 }, + { "spring", "dye:green", "dye:green", "dye:blue", nil, nil, 3 }, + { "turquoise", "dye:spring", "dye:cyan", nil, nil, nil, 2 }, + { "turquoise", "dye:green", "dye:cyan", "dye:cyan", nil, nil, 3 }, + { "turquoise", "dye:green", "dye:green", "dye:green", "dye:blue", "dye:blue", 5 }, + { "cyan", "dye:green", "dye:blue", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:azure", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:cyan", "dye:blue", nil, nil, 3 }, + { "cerulean", "dye:green", "dye:green", "dye:blue", "dye:blue", "dye:blue", 5 }, + { "azure", "dye:cyan", "dye:blue", nil, nil, nil, 2 }, + { "azure", "dye:green", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:azure", "dye:blue", nil, nil, nil, 2 }, + { "sapphire", "dye:cyan", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:green", "dye:blue", "dye:blue", "dye:blue", nil, 4 }, + { "blue", "flowers:geranium", nil, nil, nil, nil, 4 }, + { "indigo", "dye:blue", "dye:violet", nil, nil, nil, 2 }, + { "violet", "flowers:viola", nil, nil, nil, nil, 4 }, + { "violet", "dye:blue", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:blue", "dye:red", nil, nil, 3 }, + { "magenta", "dye:blue", "dye:red", nil, nil, nil, 2 }, + { "fuchsia", "dye:magenta", "dye:rose", nil, nil, nil, 2 }, + { "fuchsia", "dye:blue", "dye:red", "dye:rose", nil, nil, 3 }, + { "fuchsia", "dye:red", "dye:violet", nil, nil, nil, 2 }, + { "rose", "dye:magenta", "dye:red", nil, nil, nil, 2 }, + { "rose", "dye:red", "dye:red", "dye:blue", nil, nil, 3 }, + { "crimson", "dye:rose", "dye:red", nil, nil, nil, 2 }, + { "crimson", "dye:magenta", "dye:red", "dye:red", nil, nil, 3 }, + { "crimson", "dye:red", "dye:red", "dye:red", "dye:blue", nil, 4 }, + + { "black", "default:coal_lump", nil, nil, nil, nil, 4 }, + { "white", "flowers:dandelion_white", nil, nil, nil, nil, 4 }, +} + +unifieddyes.shade_crafts = { + { "faint_", "", "dye:white", "dye:white", "dye:white", 4 }, + { "pastel_", "", "dye:white", "dye:white", nil, 3 }, + { "light_", "", "dye:white", nil, nil, 2 }, + { "bright_", "", "color", "dye:white", nil, 3 }, + { "", "_s50", "dye:light_grey", nil, nil, 2 }, + { "", "_s50", "dye:black", "dye:white", "dye:white", 3 }, + { "medium_", "", "dye:black", nil, nil, 2 }, + { "medium_", "_s50", "dye:grey", nil, nil, 2 }, + { "medium_", "_s50", "dye:black", "dye:white", nil, 3 }, + { "dark_", "", "dye:black", "dye:black", nil, 3 }, + { "dark_", "_s50", "dye:dark_grey", nil, nil, 2 }, + { "dark_", "_s50", "dye:black", "dye:black", "dye:white", 4 }, +} + +for _,i in ipairs(unifieddyes.base_color_crafts) do + local color = i[1] + local yield = i[7] + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + i[2], + i[3], + i[4], + i[5], + i[6], + }, + }) + + for _,j in ipairs(unifieddyes.shade_crafts) do + local firstdye = j[3] + if firstdye == "color" then firstdye = "dye:"..color end + + -- ignore black, white, anything containing the word "grey" + + if color ~= "black" and color ~= "white" and not string.find(color, "grey") then + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..j[1]..color..j[2].." "..j[6], + recipe = { + "dye:"..color, + firstdye, + j[4], + j[5] + }, + }) + end + end +end + +-- greys + +unifieddyes.greymixes = { + { 1, "dye:black", "dye:black", "dye:black", "dye:dark_grey", 4 }, + { 2, "dye:black", "dye:black", "dye:dark_grey", nil, 3 }, + { 3, "dye:black", "dye:dark_grey", nil, nil, 2 }, + { 4, "dye:white", "dye:black", "dye:black", nil, 3 }, + { 5, "dye:dark_grey", "dye:dark_grey", "dye:grey", nil, 3 }, + { 6, "dye:dark_grey", "dye:grey", nil, nil, 2 }, + { 7, "dye:dark_grey", "dye:grey", "dye:grey", nil, 3 }, + { 8, "dye:white", "dye:black", nil, nil, 2 }, + { 9, "dye:grey", "dye:grey", "dye:light_grey", nil, 3 }, + { 10, "dye:grey", "dye:light_grey", "dye:light_grey", nil, 3 }, + { 11, "dye:white", "dye:white", "dye:black", nil, 3 }, + { 12, "dye:light_grey", "dye:light_grey", "dye:white", nil, 3 }, + { 13, "dye:light_grey", "dye:white", nil, nil, 2 }, + { 14, "dye:white", "dye:white", "dye:light_grey", nil, 3 }, +} + +for _, i in ipairs(unifieddyes.greymixes) do + local shade = i[1] + local dye1 = i[2] + local dye2 = i[3] + local dye3 = i[4] + local dye4 = i[5] + local yield = i[6] + local color = "grey_"..shade + if shade == 4 then + color = "dark_grey" + elseif shade == 8 then + color = "grey" + elseif shade == 11 then + color = "light_grey" + end + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + dye1, + dye2, + dye3, + dye4, + }, + }) +end + +-- other crafts +-- we can't make dark orange anymore because brown/medium orange conflicts + +minetest.register_craft( { + type = "shapeless", + output = "dye:dark_orange", + recipe = { + "dye:brown", + "dye:brown" + }, +}) + +minetest.register_craft( { + output = "unifieddyes:airbrush", + recipe = { + { "basic_materials:brass_ingot", "", "basic_materials:plastic_sheet" }, + { "", "default:steel_ingot", "" }, + { "", "", "default:steel_ingot" } + }, +}) diff --git a/mods/unifieddyes/init.lua b/mods/unifieddyes/init.lua index dcebc786..a8e5092b 100644 --- a/mods/unifieddyes/init.lua +++ b/mods/unifieddyes/init.lua @@ -2,12 +2,12 @@ Unified Dyes -This mod provides an extension to the Minetest 0.4.x dye system +This mod provides an extension to the Minetest dye system ============================================================================== -Copyright (C) 2012-2013, Vanessa Ezekowitz -Email: vanessaezekowitz@gmail.com +Copyright (C) 2012-2013, Vanessa Dannenberg +Email: vanessa.e.dannenberg@gmail.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,1562 +34,12 @@ unifieddyes = {} local creative_mode = minetest.settings:get_bool("creative_mode") local S = minetest.get_translator("unifieddyes") +local modpath=minetest.get_modpath(minetest.get_current_modname()) --- the names of the various colors here came from http://www.procato.com/rgb+index/ - -unifieddyes.HUES_EXTENDED = { - { "red", 0xff, 0x00, 0x00 }, - { "vermilion", 0xff, 0x40, 0x00 }, - { "orange", 0xff, 0x80, 0x00 }, - { "amber", 0xff, 0xbf, 0x00 }, - { "yellow", 0xff, 0xff, 0x00 }, - { "lime", 0xbf, 0xff, 0x00 }, - { "chartreuse", 0x80, 0xff, 0x00 }, - { "harlequin", 0x40, 0xff, 0x00 }, - { "green", 0x00, 0xff, 0x00 }, - { "malachite", 0x00, 0xff, 0x40 }, - { "spring", 0x00, 0xff, 0x80 }, - { "turquoise", 0x00, 0xff, 0xbf }, - { "cyan", 0x00, 0xff, 0xff }, - { "cerulean", 0x00, 0xbf, 0xff }, - { "azure", 0x00, 0x80, 0xff }, - { "sapphire", 0x00, 0x40, 0xff }, - { "blue", 0x00, 0x00, 0xff }, - { "indigo", 0x40, 0x00, 0xff }, - { "violet", 0x80, 0x00, 0xff }, - { "mulberry", 0xbf, 0x00, 0xff }, - { "magenta", 0xff, 0x00, 0xff }, - { "fuchsia", 0xff, 0x00, 0xbf }, - { "rose", 0xff, 0x00, 0x80 }, - { "crimson", 0xff, 0x00, 0x40 } -} - -unifieddyes.HUES_WITH_GREY = {} - -for _,i in ipairs(unifieddyes.HUES_EXTENDED) do - table.insert(unifieddyes.HUES_WITH_GREY, i[1]) -end -table.insert(unifieddyes.HUES_WITH_GREY, "grey") - -unifieddyes.HUES_WALLMOUNTED = { - "red", - "orange", - "yellow", - "green", - "cyan", - "blue", - "violet", - "magenta" -} - -unifieddyes.SATS = { - "", - "_s50" -} - -unifieddyes.VALS = { - "", - "medium_", - "dark_" -} - -unifieddyes.VALS_SPLIT = { - "faint_", - "light_", - "", - "medium_", - "dark_" -} - -unifieddyes.VALS_EXTENDED = { - "faint_", - "pastel_", - "light_", - "bright_", - "", - "medium_", - "dark_" -} - -unifieddyes.GREYS = { - "white", - "light_grey", - "grey", - "dark_grey", - "black" -} - -unifieddyes.GREYS_EXTENDED = table.copy(unifieddyes.GREYS) - -for i = 1, 14 do - if i ~= 0 and i ~= 4 and i ~= 8 and i ~= 11 and i ~= 15 then - table.insert(unifieddyes.GREYS_EXTENDED, "grey_"..i) - end -end - -local default_dyes = { - "black", - "blue", - "brown", - "cyan", - "dark_green", - "dark_grey", - "green", - "grey", - "magenta", - "orange", - "pink", - "red", - "violet", - "white", - "yellow" -} - -unifieddyes.player_current_dye = {} -unifieddyes.player_selected_dye = {} -unifieddyes.player_last_right_clicked = {} -unifieddyes.palette_has_color = {} -unifieddyes.player_showall = {} - --- if a node with a palette is placed in the world, --- but the itemstack used to place it has no palette_index (color byte), --- create something appropriate to make it officially white. - -minetest.register_on_placenode( - function(pos, newnode, placer, oldnode, itemstack, pointed_thing) - local def = minetest.registered_items[newnode.name] - - if not def - or not def.palette - or def.after_place_node - or not placer then - return false - end - - local param2 - if not string.find(itemstack:to_string(), "palette_index") then - if def.palette == "unifieddyes_palette_extended.png" - and def.paramtype2 == "color" then - param2 = 240 - elseif def.palette == "unifieddyes_palette_colorwallmounted.png" - and def.paramtype2 == "colorwallmounted" then - param2 = newnode.param2 % 8 - elseif string.find(def.palette, "unifieddyes_palette_") - and def.paramtype2 == "colorfacedir" then -- it's a split palette - param2 = newnode.param2 % 32 - end - - if param2 then - minetest.swap_node(pos, {name = newnode.name, param2 = param2}) - end - end - - if def.palette ~= "" then - minetest.get_meta(pos):set_int("palette_index", param2 or 240) - end - end -) - --- The complementary function: strip-off the color if the node being dug is still white/neutral - -local function move_item(item, pos, inv, digger, fix_color) - if not (digger and digger:is_player()) then return end - local creative = creative_mode or minetest.check_player_privs(digger, "creative") - item = unifieddyes.fix_bad_color_info(item, fix_color) - if inv:room_for_item("main", item) - and (not creative or not inv:contains_item("main", item, true)) then - inv:add_item("main", item) - elseif not creative then - minetest.item_drop(ItemStack(item), digger, pos) - end - minetest.remove_node(pos) -end - -function unifieddyes.on_dig(pos, node, digger) - if not digger then return end - local playername = digger:get_player_name() - if minetest.is_protected(pos, playername) then - minetest.record_protection_violation(pos, playername) - return - end - - local oldparam2 = minetest.get_node(pos).param2 - local def = minetest.registered_items[node.name] - local fix_color - - if def.paramtype2 == "color" and oldparam2 == 240 and def.palette == "unifieddyes_palette_extended.png" then - fix_color = 240 - elseif def.paramtype2 == "color" and oldparam2 == 0 and def.palette == "unifieddyes_palette_extended.png" then - fix_color = 0 - elseif def.paramtype2 == "colorwallmounted" and math.floor(oldparam2 / 8) == 0 and def.palette == "unifieddyes_palette_colorwallmounted.png" then - fix_color = 0 - elseif def.paramtype2 == "colorfacedir" and math.floor(oldparam2 / 32) == 0 and string.find(def.palette, "unifieddyes_palette_") then - fix_color = 0 - end - - local inv = digger:get_inventory() - if fix_color then - move_item(node.name, pos, inv, digger, fix_color) - else - return minetest.node_dig(pos, node, digger) - end -end - --- 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 creates multiple copies of the passed node, --- for the split palette - one per hue, plus grey - and assigns --- proper palettes and other attributes - -function unifieddyes.generate_split_palette_nodes(name, def, drop) - for _, color in ipairs(unifieddyes.HUES_WITH_GREY) do - local def2 = table.copy(def) - local desc_color = string.gsub(string.upper(string.sub(color, 1, 1))..string.sub(color, 2), "_", " ") - if string.sub(def2.description, -1) == ")" then - def2.description = string.sub(def2.description, 1, -2)..", "..desc_color.." shades)" - else - def2.description = def2.description.."("..desc_color.." shades)" - end - def2.palette = "unifieddyes_palette_"..color.."s.png" - def2.paramtype2 = "colorfacedir" - def2.groups.ud_param2_colorable = 1 - - if drop then - def2.drop = { - items = { - {items = {drop.."_"..color}, inherit_color = true }, - } - } - end - - minetest.register_node(":"..name.."_"..color, def2) - end -end - --- This helper function creates a colored itemstack - -function unifieddyes.fix_bad_color_info(item, paletteidx) - local stack=minetest.itemstring_with_color(item, paletteidx) - return string.gsub(stack, "u0001color", "u0001palette_index") -end - -function unifieddyes.make_colored_itemstack(item, palette, color) - local paletteidx = unifieddyes.getpaletteidx(color, palette) - return unifieddyes.fix_bad_color_info(item, paletteidx), paletteidx -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, h, sat, val) - local hue = (type(h) == "table") and h[1] or h - local color = "" - if val then - if craft.palette == "wallmounted" then - color = val..hue..sat - else - color = val..hue..sat - end - else - color = hue -- if val is nil, then it's grey. - end - - local dye = "dye:"..color - local recipe = minetest.serialize(craft.recipe) - recipe = string.gsub(recipe, "MAIN_DYE", dye) - recipe = string.gsub(recipe, "NEUTRAL_NODE", craft.neutral_node) - local newrecipe = minetest.deserialize(recipe) - - local coutput = craft.output or "" - local output = coutput - if craft.output_prefix then - if craft.palette ~= "split" then - output = craft.output_prefix..color..craft.output_suffix..coutput - else - if hue == "white" or hue == "black" or string.find(hue, "grey") then - output = craft.output_prefix.."grey"..craft.output_suffix..coutput - elseif hue == "pink" then - dye = "dye:light_red" - output = craft.output_prefix.."red"..craft.output_suffix..coutput - else - output = craft.output_prefix..hue..craft.output_suffix..coutput - end - end - end - - local colored_itemstack = - unifieddyes.make_colored_itemstack(output, craft.palette, dye) - - minetest.register_craft({ - output = colored_itemstack, - type = craft.type, - recipe = newrecipe - }) - -end - -function unifieddyes.register_color_craft(craft) - local hues_table = unifieddyes.HUES_EXTENDED - local sats_table = unifieddyes.SATS - local vals_table = unifieddyes.VALS_SPLIT - local greys_table = unifieddyes.GREYS - - if craft.palette == "wallmounted" then - register_c(craft, "green", "", "light_") - register_c(craft, "blue", "", "light_") - hues_table = unifieddyes.HUES_WALLMOUNTED - sats_table = {""} - vals_table = unifieddyes.VALS - elseif craft.palette == "extended" then - vals_table = unifieddyes.VALS_EXTENDED - greys_table = unifieddyes.GREYS_EXTENDED - end - - for _, hue in ipairs(hues_table) do - for _, val in ipairs(vals_table) do - for _, sat in ipairs(sats_table) do - - if sat == "_s50" and val ~= "" and val ~= "medium_" and val ~= "dark_" then break end - register_c(craft, hue, sat, val) - - end - end - end - - for _, grey in ipairs(greys_table) do - register_c(craft, grey) - end - - register_c(craft, "pink") - -end - --- code borrowed from homedecor --- call this function to reset the rotation of a "wallmounted" object on place - -function unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing) - local node = minetest.get_node(pos) - local colorbits = node.param2 - (node.param2 % 8) - - local yaw = placer:get_look_horizontal() - local dir = minetest.yaw_to_dir(yaw) -- -1.5) - local pitch = placer:get_look_vertical() - - local fdir = minetest.dir_to_wallmounted(dir) - - if pitch < -(math.pi/8) then - fdir = 0 - elseif pitch > math.pi/8 then - fdir = 1 - end - minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) -end - --- use this when you have a "wallmounted" node that should never be oriented --- to floor or ceiling... - -function unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) - local node = minetest.get_node(pos) - local colorbits = node.param2 - (node.param2 % 8) - local yaw = placer:get_look_horizontal() - local dir = minetest.yaw_to_dir(yaw+1.5) - local fdir = minetest.dir_to_wallmounted(dir) - - minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) -end - --- ... and use this one to force that kind of node off of floor/ceiling --- orientation after the screwdriver rotates it. - -function unifieddyes.fix_after_screwdriver_nsew(pos, node, user, mode, new_param2) - local new_fdir = new_param2 % 8 - local color = new_param2 - new_fdir - if new_fdir < 2 then - new_fdir = 2 - minetest.swap_node(pos, { name = node.name, param2 = new_fdir + color }) - return true - end -end - -function unifieddyes.is_buildable_to(placer_name, ...) - for _, pos in ipairs({...}) do - local node = minetest.get_node_or_nil(pos) - local def = node and minetest.registered_nodes[node.name] - if not (def and def.buildable_to) or minetest.is_protected(pos, placer_name) then - return false - end - end - return true -end - -function unifieddyes.get_hsv(name) -- expects a node/item name - local hue = "" - local a,b - for _, i in ipairs(unifieddyes.HUES_EXTENDED) do - a,b = string.find(name, "_"..i[1]) - if a then - hue = i[1] - break - end - end - - if string.find(name, "_light_grey") then hue = "light_grey" - elseif string.find(name, "_lightgrey") then hue = "light_grey" - elseif string.find(name, "_dark_grey") then hue = "dark_grey" - elseif string.find(name, "_darkgrey") then hue = "dark_grey" - elseif string.find(name, "_grey") then hue = "grey" - elseif string.find(name, "_white") then hue = "white" - elseif string.find(name, "_black") then hue = "black" - end - - local sat = "" - if string.find(name, "_s50") then sat = "_s50" end - - local val = "" - if string.find(name, "dark_") then val = "dark_" end - if string.find(name, "medium_") then val = "medium_" end - if string.find(name, "light_") then val = "light_" end - - return hue, sat, val -end - --- code partially borrowed from cheapie's plasticbox mod - --- in the function below, color is just a color string, while --- palette_type can be: --- --- "extended" = 256 color palette --- "split" = 200 color palette split into pieces for colorfacedir --- "wallmounted" = 32-color abridged palette - - -function unifieddyes.getpaletteidx(color, palette_type) - - local origcolor = color - local aliases = { - ["pink"] = "light_red", - ["brown"] = "medium_orange", - ["azure"] = "light_blue" - } - - local grayscale = { - ["white"] = 1, - ["light_grey"] = 2, - ["grey"] = 3, - ["dark_grey"] = 4, - ["black"] = 5, - } - - local grayscale_extended = { - ["white"] = 0, - ["grey_14"] = 1, - ["grey_13"] = 2, - ["grey_12"] = 3, - ["light_grey"] = 4, - ["grey_11"] = 4, - ["grey_10"] = 5, - ["grey_9"] = 6, - ["grey_8"] = 7, - ["grey"] = 7, - ["grey_7"] = 8, - ["grey_6"] = 9, - ["grey_5"] = 10, - ["grey_4"] = 11, - ["dark_grey"] = 11, - ["grey_3"] = 12, - ["grey_2"] = 13, - ["grey_1"] = 14, - ["black"] = 15, - } - - local grayscale_wallmounted = { - ["white"] = 0, - ["light_grey"] = 1, - ["grey"] = 2, - ["dark_grey"] = 3, - ["black"] = 4, - } - - local hues_extended = { - ["red"] = 0, - ["vermilion"] = 1, - ["orange"] = 2, - ["amber"] = 3, - ["yellow"] = 4, - ["lime"] = 5, - ["chartreuse"] = 6, - ["harlequin"] = 7, - ["green"] = 8, - ["malachite"] = 9, - ["spring"] = 10, - ["aqua"] = 10, - ["turquoise"] = 11, - ["cyan"] = 12, - ["cerulean"] = 13, - ["azure"] = 14, - ["skyblue"] = 14, - ["sapphire"] = 15, - ["blue"] = 16, - ["indigo"] = 17, - ["violet"] = 18, - ["mulberry"] = 19, - ["magenta"] = 20, - ["fuchsia"] = 21, - ["rose"] = 22, - ["redviolet"] = 22, - ["crimson"] = 23, - } - - local hues_wallmounted = { - ["red"] = 0, - ["orange"] = 1, - ["yellow"] = 2, - ["green"] = 3, - ["cyan"] = 4, - ["blue"] = 5, - ["violet"] = 6, - ["magenta"] = 7 - } - - local shades = { - [""] = 1, - ["s50"] = 2, - ["light"] = 3, - ["medium"] = 4, - ["mediums50"] = 5, - ["dark"] = 6, - ["darks50"] = 7, - } - - local shades_split = { - ["faint"] = 0, - [""] = 1, - ["s50"] = 2, - ["light"] = 3, - ["medium"] = 4, - ["mediums50"] = 5, - ["dark"] = 6, - ["darks50"] = 7, - } - - local shades_extended = { - ["faint"] = 0, - ["pastel"] = 1, - ["light"] = 2, - ["bright"] = 3, - [""] = 4, - ["s50"] = 5, - ["medium"] = 6, - ["mediums50"] = 7, - ["dark"] = 8, - ["darks50"] = 9 - } - - local shades_wallmounted = { - [""] = 1, - ["medium"] = 2, - ["dark"] = 3 - } - - if string.sub(color,1,4) == "dye:" then - color = string.sub(color,5,-1) - elseif string.sub(color,1,12) == "unifieddyes:" then - color = string.sub(color,13,-1) - else - return - end - - if palette_type == "wallmounted" then - if grayscale_wallmounted[color] then - return (grayscale_wallmounted[color] * 8), 0 - end - elseif palette_type == "split" then - if grayscale[color] then - return (grayscale[color] * 32), 0 - end - elseif palette_type == "extended" then - if grayscale_extended[color] then - return grayscale_extended[color]+240, 0 - end - end - - local shade = "" -- assume full - if string.sub(color,1,6) == "faint_" then - shade = "faint" - color = string.sub(color,7,-1) - elseif string.sub(color,1,7) == "pastel_" then - shade = "pastel" - color = string.sub(color,8,-1) - elseif string.sub(color,1,6) == "light_" then - shade = "light" - color = string.sub(color,7,-1) - elseif string.sub(color,1,7) == "bright_" then - shade = "bright" - color = string.sub(color,8,-1) - elseif string.sub(color,1,7) == "medium_" then - shade = "medium" - color = string.sub(color,8,-1) - elseif string.sub(color,1,5) == "dark_" then - shade = "dark" - color = string.sub(color,6,-1) - end - if string.sub(color,-4,-1) == "_s50" then - shade = shade.."s50" - color = string.sub(color,1,-5) - end - - if palette_type == "wallmounted" then - if color == "green" and shade == "light" then return 48,3 - elseif color == "brown" then return 17,1 - elseif color == "pink" then return 56,7 - elseif color == "blue" and shade == "light" then return 40,5 - elseif hues_wallmounted[color] and shades_wallmounted[shade] then - return (shades_wallmounted[shade] * 64 + hues_wallmounted[color] * 8), hues_wallmounted[color] - end - else - if color == "brown" then - color = "orange" - shade = "medium" - elseif color == "pink" then - color = "red" - shade = "light" - end - if palette_type == "split" then -- it's colorfacedir - if hues_extended[color] and shades_split[shade] then - return (shades_split[shade] * 32), hues_extended[color]+1 - end - elseif palette_type == "extended" then - if hues_extended[color] and shades_extended[shade] then - return (hues_extended[color] + shades_extended[shade]*24), hues_extended[color] - end - end - end -end - -function unifieddyes.get_color_from_dye_name(name) - if name == "dye:black" then - return "000000" - elseif name == "dye:white" then - return "ffffff" - end - local item = minetest.registered_items[name] - if not item then return end - local inv_image = item.inventory_image - if not inv_image then return end - return string.match(inv_image,"colorize:#(......):200") -end - --- punch-to-recolor using the airbrush - -function unifieddyes.on_airbrush(itemstack, player, pointed_thing) - local player_name = player:get_player_name() - local painting_with = nil - - if unifieddyes.player_current_dye[player_name] then - painting_with = unifieddyes.player_current_dye[player_name] - end - - if not painting_with then - minetest.chat_send_player(player_name, "*** You need to set a color first.") - minetest.chat_send_player(player_name, "*** Right-click any random node to open the color selector,") - minetest.chat_send_player(player_name, "*** or shift+right-click a colorized node to use its color.") - minetest.chat_send_player(player_name, "*** Be sure to click \"Accept\", or the color you select will be ignored.") - return - end - - local pos = minetest.get_pointed_thing_position(pointed_thing) - if not pos then - local look_angle = player:get_look_vertical() - if look_angle > -1.55 then - minetest.chat_send_player(player_name, "*** No node selected") - else - local hexcolor = unifieddyes.get_color_from_dye_name(painting_with) - if hexcolor then - local r = tonumber(string.sub(hexcolor,1,2),16) - local g = tonumber(string.sub(hexcolor,3,4),16) - local b = tonumber(string.sub(hexcolor,5,6),16) - player:set_sky({r=r,g=g,b=b,a=255},"plain") - end - end - return - end - - local node = minetest.get_node(pos) - local def = minetest.registered_items[node.name] - if not def then return end - - if minetest.is_protected(pos, player_name) then - minetest.chat_send_player(player_name, "*** Sorry, someone else owns that node.") - return - end - - if not (def.groups and def.groups.ud_param2_colorable and def.groups.ud_param2_colorable > 0) then - minetest.chat_send_player(player_name, "*** That node can't be colored.") - return - end - - local palette = nil - local fdir = 0 - if not def or not def.palette then - minetest.chat_send_player(player_name, "*** That node can't be colored -- it's either undefined or has no palette.") - return - elseif def.palette == "unifieddyes_palette_extended.png" then - palette = "extended" - elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then - palette = "wallmounted" - fdir = node.param2 % 8 - elseif def.palette ~= "unifieddyes_palette_extended.png" - and def.palette ~= "unifieddyes_palette_colorwallmounted.png" - and string.find(def.palette, "unifieddyes_palette_") then - palette = "split" - fdir = node.param2 % 32 - else - minetest.chat_send_player(player_name, "*** That node can't be colored -- it has an invalid color mode.") - return - end - - local idx, hue = unifieddyes.getpaletteidx(painting_with, palette) - local inv = player:get_inventory() - if (not creative or not creative.is_enabled_for(player_name)) and not inv:contains_item("main", painting_with) then - local suff = "" - if not idx then - suff = " Besides, "..string.sub(painting_with, 5).." can't be applied to that node." - end - minetest.chat_send_player(player_name, "*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff) - return - end - - if not idx then - minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") - return - end - - local oldidx = node.param2 - fdir - local name = def.airbrush_replacement_node or node.name - - if palette == "split" then - - local modname = string.sub(name, 1, string.find(name, ":")-1) - local nodename2 = string.sub(name, string.find(name, ":")+1) - local oldcolor = "snozzberry" - local newcolor = "razzberry" -- intentionally misspelled ;-) - - if def.ud_color_start and def.ud_color_end then - oldcolor = string.sub(node.name, def.ud_color_start, def.ud_color_end) - newcolor = string.sub(painting_with, 5) - else - if hue ~= 0 then - newcolor = unifieddyes.HUES_EXTENDED[hue][1] - else - newcolor = "grey" - end - - if def.airbrush_replacement_node then - oldcolor = "grey" - else - local s = string.sub(def.palette, 21) - oldcolor = string.sub(s, 1, string.find(s, "s.png")-1) - end - end - - name = modname..":"..string.gsub(nodename2, oldcolor, newcolor) - - if not minetest.registered_items[name] then - minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") - return - end - elseif idx == oldidx then - return - end - minetest.swap_node(pos, {name = name, param2 = fdir + idx}) - if not creative or not creative.is_enabled_for(player_name) then - inv:remove_item("main", painting_with) - return - end -end - --- get a node's dye color based on its palette and param2 - -function unifieddyes.color_to_name(param2, def) - if not param2 or not def or not def.palette then return end - - if def.palette == "unifieddyes_palette_extended.png" then - local color = param2 - - local v = 0 - local s = 1 - if color < 24 then v = 1 - elseif color > 23 and color < 48 then v = 2 - elseif color > 47 and color < 72 then v = 3 - elseif color > 71 and color < 96 then v = 4 - elseif color > 95 and color < 120 then v = 5 - elseif color > 119 and color < 144 then v = 5 s = 2 - elseif color > 143 and color < 168 then v = 6 - elseif color > 167 and color < 192 then v = 6 s = 2 - elseif color > 191 and color < 216 then v = 7 - elseif color > 215 and color < 240 then v = 7 s = 2 - end - - if color > 239 then - if color == 240 then return "white" - elseif color == 244 then return "light_grey" - elseif color == 247 then return "grey" - elseif color == 251 then return "dark_grey" - elseif color == 255 then return "black" - else return "grey_"..15-(color-240) - end - else - local h = color - math.floor(color/24)*24 - return unifieddyes.VALS_EXTENDED[v]..unifieddyes.HUES_EXTENDED[h+1][1]..unifieddyes.SATS[s] - end - - elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then - local color = math.floor(param2 / 8) - if color == 0 then return "white" - elseif color == 1 then return "light_grey" - elseif color == 2 then return "grey" - elseif color == 3 then return "dark_grey" - elseif color == 4 then return "black" - elseif color == 5 then return "light_blue" - elseif color == 6 then return "light_green" - elseif color == 7 then return "pink" - end - local v = math.floor(color/8) - local h = color - v * 8 - return unifieddyes.VALS[v]..unifieddyes.HUES_WALLMOUNTED[h+1] - - elseif string.find(def.palette, "unifieddyes_palette") then -- it's the split palette - -- palette names in this mode are always "unifieddyes_palette_COLORs.png" - - local s = string.sub(def.palette, 21) - local color = string.sub(s, 1, string.find(s, "s.png")-1) - - local v = math.floor(param2/32) - if color ~= "grey" then - if v == 0 then return "faint_"..color - elseif v == 1 then return color - elseif v == 2 then return color.."_s50" - elseif v == 3 then return "light_"..color - elseif v == 4 then return "medium_"..color - elseif v == 5 then return "medium_"..color.."_s50" - elseif v == 6 then return "dark_"..color - elseif v == 7 then return "dark_"..color.."_s50" - end - else - if v > 0 and v < 6 then return unifieddyes.GREYS[v] - else return "white" - end - end - end -end - -local hps = 0.6 -- horizontal position scale -local vps = 1.3 -- vertical position scale -local vs = 0.1 -- vertical shift/offset - -local color_button_size = ";0.75,0.75;" -local color_square_size = ";0.69,0.69;" - -function unifieddyes.make_readable_color(color) - -- is this a low saturation color? - local has_low_saturtation = string.find(color, "s50"); - - -- remove _s50 tag, we care about that later again - local s = string.gsub(color, "_s50", "") - - -- replace underscores with spaces to make it look nicer - local s = string.gsub(s, "_", " ") - - -- capitalize words, you know, looks nicer ;) - s = string.gsub(s, "(%l)(%w*)", function(a,b) return string.upper(a)..b end) - - -- add the word dye, this is what the translations expect - s = s.." Dye" - - -- if it is a low sat color, append an appropriate string - if has_low_saturtation then - s = s.." (low saturation)" - end - - return s -end - -function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) - - local dye = "dye:"..colorname - - local overlay = "" - local colorize = minetest.formspec_escape("^[colorize:#"..hexcolor..":255") - - if not creative and inv:contains_item("main", dye) then - overlay = "^unifieddyes_onhand_overlay.png" - end - - local unavail_overlay = "" - if not showall and not unifieddyes.palette_has_color[nodepalette.."_"..colorname] - or (explist and not explist[colorname]) then - if overlay == "" then - unavail_overlay = "^unifieddyes_unavailable_overlay.png" - else - unavail_overlay = "^unifieddyes_onhand_unavailable_overlay.png" - end - end - - local tooltip = "tooltip["..colorname..";".. - S(unifieddyes.make_readable_color(colorname)).. - "\n(dye:"..colorname..")]" - - if dye == painting_with then - overlay = "^unifieddyes_select_overlay.png" - selindic = "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]"..tooltip - end - - local form - if unavail_overlay == "" then - form = "image_button[".. - (hp*hps)..","..(v2*vps+vs).. - color_button_size.. - "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay..";".. - colorname..";]".. - tooltip - else - form = "image[".. - (hp*hps)..","..(v2*vps+vs).. - color_square_size.. - "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]".. - tooltip - end - - return form, selindic -end - -function unifieddyes.show_airbrush_form(player) - if not player then return end - - local t = {} - - local player_name = player:get_player_name() - local painting_with = unifieddyes.player_selected_dye[player_name] or unifieddyes.player_current_dye[player_name] - local creative = creative and creative.is_enabled_for(player_name) - local inv = player:get_inventory() - local nodepalette = "extended" - local showall = unifieddyes.player_showall[player_name] - - t[1] = "size[14.5,8.5]label[7,-0.3;"..S("Select a color:").."]" - local selindic = "unifieddyes_select_overlay.png^unifieddyes_question.png]" - - local last_right_click = unifieddyes.player_last_right_clicked[player_name] - if last_right_click then - if last_right_click.def and last_right_click.def.palette then - if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then - nodepalette = "wallmounted" - elseif last_right_click.def.palette == "unifieddyes_palette_extended.png" then - t[#t+1] = "label[0.5,8.25;"..S("(Right-clicked a node that supports all 256 colors, showing them all)").."]" - showall = true - elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" - and last_right_click.def.palette ~= "unifieddyes_palette_colorwallmounted.png" - and string.find(last_right_click.def.palette, "unifieddyes_palette_") then - nodepalette = "split" - end - end - end - - if not last_right_click.def.groups - or not last_right_click.def.groups.ud_param2_colorable - or not last_right_click.def.palette - or not string.find(last_right_click.def.palette, "unifieddyes_palette_") then - t[#t+1] = "label[0.5,8.25;"..S("(Right-clicked a node not supported by the Airbrush, showing all colors)").."]" - end - - local explist = last_right_click.def.explist - - for v = 0, 6 do - local val = unifieddyes.VALS_EXTENDED[v+1] - - local sat = "" - local v2=(v/2) - - for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do - local hue = h[1] - local hp=hi-1 - - local r = h[2] - local g = h[3] - local b = h[4] - - local factor = 40 - if v > 3 then - factor = 75 - v2 = (v-2) - end - - local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) - local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) - local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) - - local hexcolor = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) - local f - f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) - t[#t+1] = f - end - - if v > 3 then - sat = "_s50" - v2 = (v-1.5) - - for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do - local hue = h[1] - local hp=hi-1 - - local r = h[2] - local g = h[3] - local b = h[4] - - local factor = 75 - - local pr = 0.299 - local pg = 0.587 - local pb = 0.114 - - local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) - local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) - local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) - - local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) - local r3 = math.floor(p+(r2-p)*0.5) - local g3 = math.floor(p+(g2-p)*0.5) - local b3 = math.floor(p+(b2-p)*0.5) - - local hexcolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) - local f - f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) - t[#t+1] = f - end - end - end - - local v2=5 - for y = 0, 15 do - - local hp=15-y - - local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) - local grey = "grey_"..y - - if y == 0 then grey = "black" - elseif y == 4 then grey = "dark_grey" - elseif y == 8 then grey = "grey" - elseif y == 11 then grey = "light_grey" - elseif y == 15 then grey = "white" - end - - local f - f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) - t[#t+1] = f - - end - - if not creative then - t[#t+1] = "image[10," - t[#t+1] = (vps*5.55+vs) - t[#t+1] = color_button_size - t[#t+1] = "unifieddyes_onhand_overlay.png]label[10.7," - t[#t+1] = (vps*5.51+vs) - t[#t+1] = ";"..S("Dyes").."]" - t[#t+1] = "label[10.7," - t[#t+1] = (vps*5.67+vs) - t[#t+1] = ";on hand]" - - end - - t[#t+1] = "image[10," - t[#t+1] = (vps*5+vs) - t[#t+1] = color_button_size - t[#t+1] = selindic - - if painting_with then - t[#t+1] = "label[10.7," - t[#t+1] = (vps*4.90+vs) - t[#t+1] = ";"..S("Your selection:").."]" - t[#t+1] = "label[10.7," - t[#t+1] = (vps*5.07+vs) - t[#t+1] = ";" - t[#t+1] = S(unifieddyes.make_readable_color(string.sub(painting_with, 5))) - t[#t+1] = "]label[10.7," - t[#t+1] = (vps*5.24+vs) - t[#t+1] = ";(" - t[#t+1] = painting_with - t[#t+1] = ")]" - else - t[#t+1] = "label[10.7," - t[#t+1] = (vps*5.07+vs) - t[#t+1] = ";"..S("Your selection").."]" - end - - t[#t+1] = "button_exit[10.5,8;2,1;cancel;"..S("Cancel").."]button_exit[12.5,8;2,1;accept;"..S("Accept").."]" - - - if last_right_click and last_right_click.def and nodepalette ~= "extended" then - if showall then - t[#t+1] = "button[0,8;2,1;show_avail;"..S("Show Available").."]" - t[#t+1] = "label[2,8.25;"..S("(Currently showing all 256 colors)").."]" - else - t[#t+1] = "button[0,8;2,1;show_all;"..S("Show All Colors").."]" - t[#t+1] = "label[2,8.25;"..S("(Currently only showing what the right-clicked node can use)").."]" - end - end - - minetest.show_formspec(player_name, "unifieddyes:dye_select_form", table.concat(t)) -end - -minetest.register_tool("unifieddyes:airbrush", { - description = S("Dye Airbrush"), - inventory_image = "unifieddyes_airbrush.png", - use_texture_alpha = true, - tool_capabilities = { - full_punch_interval=0.1, - }, - range = 12, - on_use = unifieddyes.on_airbrush, - on_place = function(itemstack, placer, pointed_thing) - local keys = placer:get_player_control() - local player_name = placer:get_player_name() - local pos = minetest.get_pointed_thing_position(pointed_thing) - local node - local def - - if pos then node = minetest.get_node(pos) end - if node then def = minetest.registered_items[node.name] end - - unifieddyes.player_last_right_clicked[player_name] = {pos = pos, node = node, def = def} - - if (not keys.sneak) and def.on_rightclick then - return def.on_rightclick(pos, node, placer, itemstack, pointed_thing) - elseif not keys.sneak then - unifieddyes.show_airbrush_form(placer) - elseif keys.sneak then - if not pos or not def then return end - local newcolor = unifieddyes.color_to_name(node.param2, def) - - if not newcolor then - minetest.chat_send_player(player_name, "*** That node is uncolored.") - return - end - minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.") - unifieddyes.player_current_dye[player_name] = "dye:"..newcolor - end - end -}) - -minetest.register_craft( { - output = "unifieddyes:airbrush", - recipe = { - { "basic_materials:brass_ingot", "", "basic_materials:plastic_sheet" }, - { "", "default:steel_ingot", "" }, - { "", "", "default:steel_ingot" } - }, -}) - -minetest.register_on_player_receive_fields(function(player, formname, fields) - - if formname == "unifieddyes:dye_select_form" then - - local player_name = player:get_player_name() - local nodepalette = "extended" - local showall = unifieddyes.player_showall[player_name] - - local last_right_click = unifieddyes.player_last_right_clicked[player_name] - if last_right_click and last_right_click.def then - if last_right_click.def.palette then - if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then - nodepalette = "wallmounted" - elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" then - nodepalette = "split" - end - end - end - - if fields.show_all then - unifieddyes.player_showall[player_name] = true - unifieddyes.show_airbrush_form(player) - return - elseif fields.show_avail then - unifieddyes.player_showall[player_name] = false - unifieddyes.show_airbrush_form(player) - return - elseif fields.quit then - if fields.accept then - local dye = unifieddyes.player_selected_dye[player_name] - if not dye then - minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but no color was selected!") - return - elseif not showall - and not unifieddyes.palette_has_color[nodepalette.."_"..string.sub(dye, 5)] then - minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but the selected color can't be used on the") - minetest.chat_send_player(player_name, "*** node that was right-clicked (and \"Show All\" wasn't in effect).") - if unifieddyes.player_current_dye[player_name] then - minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "..string.sub(unifieddyes.player_current_dye[player_name], 5)..".") - else - minetest.chat_send_player(player_name, "*** Ignoring it.") - end - return - else - unifieddyes.player_current_dye[player_name] = dye - unifieddyes.player_selected_dye[player_name] = nil - minetest.chat_send_player(player_name, "*** Selected "..string.sub(dye, 5).." for the airbrush.") - return - end - else -- assume "Cancel" or Esc. - unifieddyes.player_selected_dye[player_name] = nil - return - end - else - local s1 = string.sub(minetest.serialize(fields), 11) - local s3 = string.sub(s1,1, string.find(s1, '"')-1) - - local inv = player:get_inventory() - local creative = creative and creative.is_enabled_for(player_name) - local dye = "dye:"..s3 - - if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and - (minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then - unifieddyes.player_selected_dye[player_name] = dye - unifieddyes.show_airbrush_form(player) - end - end - end -end) - --- Generate all dyes that are not part of the default minetest_game dyes mod - -for _, h in ipairs(unifieddyes.HUES_EXTENDED) do - local hue = h[1] - local r = h[2] - local g = h[3] - local b = h[4] - - for v = 0, 6 do - local val = unifieddyes.VALS_EXTENDED[v+1] - - local factor = 40 - if v > 3 then factor = 75 end - - local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) - local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) - local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) - - -- full-sat color - - local desc = hue:gsub("%a", string.upper, 1).." Dye" - - if val ~= "" then - desc = val:sub(1, -2):gsub("%a", string.upper, 1) .." "..desc - end - - local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) - if minetest.registered_items["dye:"..val..hue] then - minetest.override_item("dye:"..val..hue, { - inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", - }) - else - if (val..hue) ~= "medium_orange" - and (val..hue) ~= "light_red" then - minetest.register_craftitem(":dye:"..val..hue, { - description = S(desc), - inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", - groups = { dye=1, not_in_creative_inventory=1 }, - }) - end - end - minetest.register_alias("unifieddyes:"..val..hue, "dye:"..val..hue) - - if v > 3 then -- also register the low-sat version - - local pr = 0.299 - local pg = 0.587 - local pb = 0.114 - - local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) - local r3 = math.floor(p+(r2-p)*0.5) - local g3 = math.floor(p+(g2-p)*0.5) - local b3 = math.floor(p+(b2-p)*0.5) - - local color = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) - - minetest.register_craftitem(":dye:"..val..hue.."_s50", { - description = S(desc.." (low saturation)"), - inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", - groups = { dye=1, not_in_creative_inventory=1 }, - }) - minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") - end - end -end - --- register the greyscales too :P - -for y = 1, 14 do -- colors 0 and 15 are black and white, default dyes - - if y ~= 4 and y ~= 8 and y~= 11 then -- don't register the three greys, they're done separately. - - local rgb = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) - local name = "grey_"..y - local desc = "Grey Dye #"..y - - minetest.register_craftitem(":dye:"..name, { - description = S(desc), - inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":200", - groups = { dye=1, not_in_creative_inventory=1 }, - }) - minetest.register_alias("unifieddyes:"..name, "dye:"..name) - end -end - -minetest.override_item("dye:grey", { - inventory_image = "unifieddyes_dye.png^[colorize:#888888:200", -}) - -minetest.override_item("dye:dark_grey", { - inventory_image = "unifieddyes_dye.png^[colorize:#444444:200", -}) - -minetest.register_craftitem(":dye:light_grey", { - description = S("Light grey Dye"), - inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200", - groups = { dye=1, not_in_creative_inventory=1 }, -}) - --- build a table of color <-> palette associations to reduce the need for --- realtime lookups with getpaletteidx() - -for _, palette in ipairs({"extended", "split", "wallmounted"}) do - local palette2 = palette - - for i in ipairs(unifieddyes.SATS) do - local sat = (palette == "wallmounted") and "" or unifieddyes.SATS[i] - for _, hue in ipairs(unifieddyes.HUES_EXTENDED) do - for _, val in ipairs(unifieddyes.VALS_EXTENDED) do - local color = val..hue[1]..sat - if unifieddyes.getpaletteidx("dye:"..color, palette2) then - unifieddyes.palette_has_color[palette.."_"..color] = true - end - end - end - end - - for y = 0, 15 do - local grey = "grey_"..y - - if y == 0 then grey = "black" - elseif y == 4 then grey = "dark_grey" - elseif y == 8 then grey = "grey" - elseif y == 11 then grey = "light_grey" - elseif y == 15 then grey = "white" - end - if unifieddyes.getpaletteidx("dye:"..grey, palette2) then - unifieddyes.palette_has_color[palette.."_"..grey] = true - end - end -end - -unifieddyes.palette_has_color["wallmounted_light_red"] = true - --- crafting! - -unifieddyes.base_color_crafts = { - { "red", "flowers:rose", nil, nil, nil, nil, 4 }, - { "vermilion", "dye:red", "dye:orange", nil, nil, nil, 3 }, - { "orange", "flowers:tulip", nil, nil, nil, nil, 4 }, - { "orange", "dye:red", "dye:yellow", nil, nil, nil, 2 }, - { "amber", "dye:orange", "dye:yellow", nil, nil, nil, 2 }, - { "yellow", "flowers:dandelion_yellow", nil, nil, nil, nil, 4 }, - { "lime", "dye:yellow", "dye:chartreuse", nil, nil, nil, 2 }, - { "lime", "dye:yellow", "dye:yellow", "dye:green", nil, nil, 3 }, - { "chartreuse", "dye:yellow", "dye:green", nil, nil, nil, 2 }, - { "harlequin", "dye:chartreuse", "dye:green", nil, nil, nil, 2 }, - { "harlequin", "dye:yellow", "dye:green", "dye:green", nil, nil, 3 }, - { "green", "default:cactus", nil, nil, nil, nil, 4 }, - { "green", "dye:yellow", "dye:blue", nil, nil, nil, 2 }, - { "malachite", "dye:green", "dye:spring", nil, nil, nil, 2 }, - { "malachite", "dye:green", "dye:green", "dye:cyan", nil, nil, 3 }, - { "malachite", "dye:green", "dye:green", "dye:green", "dye:blue", nil, 4 }, - { "spring", "dye:green", "dye:cyan", nil, nil, nil, 2 }, - { "spring", "dye:green", "dye:green", "dye:blue", nil, nil, 3 }, - { "turquoise", "dye:spring", "dye:cyan", nil, nil, nil, 2 }, - { "turquoise", "dye:green", "dye:cyan", "dye:cyan", nil, nil, 3 }, - { "turquoise", "dye:green", "dye:green", "dye:green", "dye:blue", "dye:blue", 5 }, - { "cyan", "dye:green", "dye:blue", nil, nil, nil, 2 }, - { "cerulean", "dye:cyan", "dye:azure", nil, nil, nil, 2 }, - { "cerulean", "dye:cyan", "dye:cyan", "dye:blue", nil, nil, 3 }, - { "cerulean", "dye:green", "dye:green", "dye:blue", "dye:blue", "dye:blue", 5 }, - { "azure", "dye:cyan", "dye:blue", nil, nil, nil, 2 }, - { "azure", "dye:green", "dye:blue", "dye:blue", nil, nil, 3 }, - { "sapphire", "dye:azure", "dye:blue", nil, nil, nil, 2 }, - { "sapphire", "dye:cyan", "dye:blue", "dye:blue", nil, nil, 3 }, - { "sapphire", "dye:green", "dye:blue", "dye:blue", "dye:blue", nil, 4 }, - { "blue", "flowers:geranium", nil, nil, nil, nil, 4 }, - { "indigo", "dye:blue", "dye:violet", nil, nil, nil, 2 }, - { "violet", "flowers:viola", nil, nil, nil, nil, 4 }, - { "violet", "dye:blue", "dye:magenta", nil, nil, nil, 2 }, - { "mulberry", "dye:violet", "dye:magenta", nil, nil, nil, 2 }, - { "mulberry", "dye:violet", "dye:blue", "dye:red", nil, nil, 3 }, - { "magenta", "dye:blue", "dye:red", nil, nil, nil, 2 }, - { "fuchsia", "dye:magenta", "dye:rose", nil, nil, nil, 2 }, - { "fuchsia", "dye:blue", "dye:red", "dye:rose", nil, nil, 3 }, - { "fuchsia", "dye:red", "dye:violet", nil, nil, nil, 2 }, - { "rose", "dye:magenta", "dye:red", nil, nil, nil, 2 }, - { "rose", "dye:red", "dye:red", "dye:blue", nil, nil, 3 }, - { "crimson", "dye:rose", "dye:red", nil, nil, nil, 2 }, - { "crimson", "dye:magenta", "dye:red", "dye:red", nil, nil, 3 }, - { "crimson", "dye:red", "dye:red", "dye:red", "dye:blue", nil, 4 }, - - { "black", "default:coal_lump", nil, nil, nil, nil, 4 }, - { "white", "flowers:dandelion_white", nil, nil, nil, nil, 4 }, -} - -unifieddyes.shade_crafts = { - { "faint_", "", "dye:white", "dye:white", "dye:white", 4 }, - { "pastel_", "", "dye:white", "dye:white", nil, 3 }, - { "light_", "", "dye:white", nil, nil, 2 }, - { "bright_", "", "color", "dye:white", nil, 3 }, - { "", "_s50", "dye:light_grey", nil, nil, 2 }, - { "", "_s50", "dye:black", "dye:white", "dye:white", 3 }, - { "medium_", "", "dye:black", nil, nil, 2 }, - { "medium_", "_s50", "dye:grey", nil, nil, 2 }, - { "medium_", "_s50", "dye:black", "dye:white", nil, 3 }, - { "dark_", "", "dye:black", "dye:black", nil, 3 }, - { "dark_", "_s50", "dye:dark_grey", nil, nil, 2 }, - { "dark_", "_s50", "dye:black", "dye:black", "dye:white", 4 }, -} - -for _,i in ipairs(unifieddyes.base_color_crafts) do - local color = i[1] - local yield = i[7] - - minetest.register_craft( { - type = "shapeless", - output = "dye:"..color.." "..yield, - recipe = { - i[2], - i[3], - i[4], - i[5], - i[6], - }, - }) - - for _,j in ipairs(unifieddyes.shade_crafts) do - local firstdye = j[3] - if firstdye == "color" then firstdye = "dye:"..color end - - -- ignore black, white, anything containing the word "grey" - - if color ~= "black" and color ~= "white" and not string.find(color, "grey") then - - minetest.register_craft( { - type = "shapeless", - output = "dye:"..j[1]..color..j[2].." "..j[6], - recipe = { - "dye:"..color, - firstdye, - j[4], - j[5] - }, - }) - end - end -end - --- greys - -unifieddyes.greymixes = { - { 1, "dye:black", "dye:black", "dye:black", "dye:dark_grey", 4 }, - { 2, "dye:black", "dye:black", "dye:dark_grey", nil, 3 }, - { 3, "dye:black", "dye:dark_grey", nil, nil, 2 }, - { 4, "dye:white", "dye:black", "dye:black", nil, 3 }, - { 5, "dye:dark_grey", "dye:dark_grey", "dye:grey", nil, 3 }, - { 6, "dye:dark_grey", "dye:grey", nil, nil, 2 }, - { 7, "dye:dark_grey", "dye:grey", "dye:grey", nil, 3 }, - { 8, "dye:white", "dye:black", nil, nil, 2 }, - { 9, "dye:grey", "dye:grey", "dye:light_grey", nil, 3 }, - { 10, "dye:grey", "dye:light_grey", "dye:light_grey", nil, 3 }, - { 11, "dye:white", "dye:white", "dye:black", nil, 3 }, - { 12, "dye:light_grey", "dye:light_grey", "dye:white", nil, 3 }, - { 13, "dye:light_grey", "dye:white", nil, nil, 2 }, - { 14, "dye:white", "dye:white", "dye:light_grey", nil, 3 }, -} - -for _, i in ipairs(unifieddyes.greymixes) do - local shade = i[1] - local dye1 = i[2] - local dye2 = i[3] - local dye3 = i[4] - local dye4 = i[5] - local yield = i[6] - local color = "grey_"..shade - if shade == 4 then - color = "dark_grey" - elseif shade == 8 then - color = "grey" - elseif shade == 11 then - color = "light_grey" - end - - minetest.register_craft( { - type = "shapeless", - output = "dye:"..color.." "..yield, - recipe = { - dye1, - dye2, - dye3, - dye4, - }, - }) -end - --- we can't make dark orange anymore because brown/medium orange conflicts - -minetest.register_craft( { - type = "shapeless", - output = "dye:dark_orange", - recipe = { - "dye:brown", - "dye:brown" - }, -}) - --- aliases - -minetest.register_alias("dye:light_red", "dye:pink") -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") -minetest.register_alias("unifieddyes:grey_8", "dye:grey") -minetest.register_alias("unifieddyes:grey_11", "dye:light_grey") -minetest.register_alias("unifieddyes:grey_15", "dye:white") - -minetest.register_alias("unifieddyes:white_paint", "dye:white") -minetest.register_alias("unifieddyes:titanium_dioxide", "dye:white") -minetest.register_alias("unifieddyes:lightgrey_paint", "dye:light_grey") -minetest.register_alias("unifieddyes:grey_paint", "dye:grey") -minetest.register_alias("unifieddyes:darkgrey_paint", "dye:dark_grey") -minetest.register_alias("unifieddyes:carbon_black", "dye:black") - -minetest.register_alias("unifieddyes:brown", "dye:brown") +dofile(modpath.."/color-tables.lua") +dofile(modpath.."/api.lua") +dofile(modpath.."/airbrush.lua") +dofile(modpath.."/dyes-crafting.lua") +dofile(modpath.."/aliases.lua") print(S("[UnifiedDyes] Loaded!")) -