improved and completed color calculator
This commit is contained in:
parent
f6b4be1485
commit
9ca2ea7e1d
16
res/color_overrides.json
Normal file
16
res/color_overrides.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"minecraft:seagrass": [97, 113, 54],
|
||||||
|
"minecraft:chest": [171, 121, 45],
|
||||||
|
"minecraft:ender_chest": [48, 67, 71],
|
||||||
|
"minecraft:lily_pad": [32, 128, 48],
|
||||||
|
"minecraft:redstone_wire": [189, 32, 8],
|
||||||
|
"minecraft:cocoa": [150, 87, 26],
|
||||||
|
"minecraft:wheat": [220, 187, 101],
|
||||||
|
"minecraft:carrots": [227, 138, 29],
|
||||||
|
"minecraft:potatoes": [200, 162, 75],
|
||||||
|
"minecraft:beetroots": [191, 37,41],
|
||||||
|
"minecraft:nether_wart": [131, 28, 32],
|
||||||
|
"minecraft:sweet_berry_bush": [60, 110, 66],
|
||||||
|
"minecraft:torchflower_crop": [130, 158, 85],
|
||||||
|
"minecraft:pitcher_crop": [112, 134, 181]
|
||||||
|
}
|
@ -1,44 +1,242 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
import zipfile
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
|
from src.utils.paths import get_project_path, CACHE_DIR
|
||||||
|
|
||||||
|
# Textures with these parts will be excluded
|
||||||
EXCLUDE = {
|
EXCLUDE = {
|
||||||
"bottom", "side", "front", "cracked", "on", "stem", "tip", "lit", "inner"
|
"bottom", "side", "front", "destroy", "on", "tip", "lit", "inner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Textures with these names will be copied to their variants (variants listed in `VARIANTS`)
|
||||||
|
# Tuples indicate a change of name for variants
|
||||||
|
TO_VARIANT = [
|
||||||
|
("nether_bricks", "nether_brick"),
|
||||||
|
("nether_bricks", "nether_brick"),
|
||||||
|
("oak_planks", "oak"),
|
||||||
|
("spruce_planks", "spruce"),
|
||||||
|
("birch_planks", "birch"),
|
||||||
|
("jungle_planks", "jungle"),
|
||||||
|
("acacia_planks", "acacia"),
|
||||||
|
("dark_oak_planks", "dark_oak"),
|
||||||
|
("mangrove_planks", "mangrove"),
|
||||||
|
("cherry_planks", "cherry"),
|
||||||
|
("bamboo_mosaic", "bamboo"),
|
||||||
|
("crimson_planks", "crimson"),
|
||||||
|
("warped_planks", "warped"),
|
||||||
|
"stone",
|
||||||
|
"cobblestone",
|
||||||
|
"mossy_cobblestone",
|
||||||
|
"smooth_stone",
|
||||||
|
("stone_bricks", "stone_brick"),
|
||||||
|
("mossy_stone_bricks", "mossy_stone_brick"),
|
||||||
|
"granite",
|
||||||
|
"polished_granite",
|
||||||
|
"diorite",
|
||||||
|
"polished_diorite",
|
||||||
|
"andesite",
|
||||||
|
"polished_andesite",
|
||||||
|
"cobbled_deepslate",
|
||||||
|
"polished_deepslate",
|
||||||
|
("deepslate_bricks", "deepslate_brick"),
|
||||||
|
("deepslate_tiles", "deepslate_tile"),
|
||||||
|
("bricks", "brick"),
|
||||||
|
("mud_bricks", "mud_brick"),
|
||||||
|
"sandstone",
|
||||||
|
"smooth_sandstone",
|
||||||
|
"cut_sandstone",
|
||||||
|
"red_sandstone",
|
||||||
|
"smooth_red_sandstone",
|
||||||
|
"cut_red_sandstone",
|
||||||
|
"prismarine",
|
||||||
|
("prismarine_bricks", "prismarine_brick"),
|
||||||
|
"dark_prismarine",
|
||||||
|
("red_nether_bricks", "red_nether_brick"),
|
||||||
|
"blackstone",
|
||||||
|
"polished_blackstone",
|
||||||
|
("polished_blackstone_bricks", "polished_blackstone_brick"),
|
||||||
|
("end_stone_bricks", "end_stone_brick"),
|
||||||
|
("purpur_block", "purpur"),
|
||||||
|
("quartz_block", "quartz"),
|
||||||
|
"smooth_quartz",
|
||||||
|
"cut_copper",
|
||||||
|
"exposed_cut_copper",
|
||||||
|
"weathered_cut_copper",
|
||||||
|
"oxidized_cut_copper",
|
||||||
|
"waxed_cut_copper",
|
||||||
|
"waxed_exposed_cut_copper",
|
||||||
|
"waxed_weathered_cut_copper",
|
||||||
|
"waxed_oxidized_cut_copper",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Variants of the textures in `TO_VARIANT`
|
||||||
|
VARIANTS = [
|
||||||
|
"slab", "stairs",
|
||||||
|
"wall", "fence", "fence_gate",
|
||||||
|
"pressure_plate", "button",
|
||||||
|
"sign", "wall_sign", "hanging_sign", "wall_hanging_sign"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Colors to copy
|
||||||
|
TO_COPY = [
|
||||||
|
("minecraft:furnace", "minecraft:dropper"),
|
||||||
|
("minecraft:furnace", "minecraft:dispenser"),
|
||||||
|
("minecraft:furnace", "minecraft:piston"),
|
||||||
|
("minecraft:furnace", "minecraft:sticky_piston"),
|
||||||
|
("minecraft:oak_planks", "minecraft:piston_head"),
|
||||||
|
("minecraft:oak_planks", "minecraft:sticky_piston_head"),
|
||||||
|
("minecraft:torch", "minecraft:wall_torch"),
|
||||||
|
("minecraft:soul_torch", "minecraft:soul_wall_torch"),
|
||||||
|
("minecraft:redstone_torch", "minecraft:redstone_wall_torch"),
|
||||||
|
("minecraft:snow", "minecraft:snow_block"),
|
||||||
|
("minecraft:water", "minecraft:bubble_column"),
|
||||||
|
("minecraft:sandstone", "minecraft:smooth_sandstone"),
|
||||||
|
("minecraft:red_sandstone", "minecraft:smooth_red_sandstone"),
|
||||||
|
("minecraft:quartz_block", "minecraft:smooth_quartz"),
|
||||||
|
("minecraft:dripstone_block", "minecraft:pointed_dripstone"),
|
||||||
|
("minecraft:oak_log", "minecraft:oak_wood"),
|
||||||
|
("minecraft:spruce_log", "minecraft:spruce_wood"),
|
||||||
|
("minecraft:birch_log", "minecraft:birch_wood"),
|
||||||
|
("minecraft:acacia_log", "minecraft:acacia_wood"),
|
||||||
|
("minecraft:jungle_log", "minecraft:jungle_wood"),
|
||||||
|
("minecraft:cherry_log", "minecraft:cherry_wood"),
|
||||||
|
("minecraft:mangrove_log", "minecraft:mangrove_wood"),
|
||||||
|
("minecraft:dark_oak_log", "minecraft:dark_oak_wood"),
|
||||||
|
("minecraft:stripped_oak_log", "minecraft:stripped_oak_wood"),
|
||||||
|
("minecraft:stripped_spruce_log", "minecraft:stripped_spruce_wood"),
|
||||||
|
("minecraft:stripped_birch_log", "minecraft:stripped_birch_wood"),
|
||||||
|
("minecraft:stripped_acacia_log", "minecraft:stripped_acacia_wood"),
|
||||||
|
("minecraft:stripped_jungle_log", "minecraft:stripped_jungle_wood"),
|
||||||
|
("minecraft:stripped_cherry_log", "minecraft:stripped_cherry_wood"),
|
||||||
|
("minecraft:stripped_mangrove_log", "minecraft:stripped_mangrove_wood"),
|
||||||
|
("minecraft:stripped_dark_oak_log", "minecraft:stripped_dark_oak_wood"),
|
||||||
|
("minecraft:magma", "minecraft:magma_block"),
|
||||||
|
("minecraft:cut_copper", "minecraft:waxed_cut_copper"),
|
||||||
|
("minecraft:exposed_cut_copper", "minecraft:waxed_exposed_cut_copper"),
|
||||||
|
("minecraft:weathered_cut_copper", "minecraft:waxed_weathered_cut_copper"),
|
||||||
|
("minecraft:oxidized_cut_copper", "minecraft:waxed_oxidized_cut_copper"),
|
||||||
|
("minecraft:iron_block", "minecraft:heavy_weighted_pressure_plate"),
|
||||||
|
("minecraft:gold_block", "minecraft:light_weighted_pressure_plate"),
|
||||||
|
("minecraft:bricks", "minecraft:flower_pot"),
|
||||||
|
("minecraft:oak_log", "minecraft:campfire"),
|
||||||
|
("minecraft:oak_log", "minecraft:soul_campfire"),
|
||||||
|
("minecraft:moss_block", "minecraft:moss_carpet"),
|
||||||
|
("minecraft:stone", "minecraft:infested_stone"),
|
||||||
|
("minecraft:cobblestone", "minecraft:infested_cobblestone"),
|
||||||
|
("minecraft:stone_bricks", "minecraft:infested_stone_bricks"),
|
||||||
|
("minecraft:mossy_stone_bricks", "minecraft:infested_mossy_stone_bricks"),
|
||||||
|
("minecraft:chiseled_stone_bricks", "minecraft:infested_chiseled_stone_bricks"),
|
||||||
|
("minecraft:deepslate", "minecraft:infested_deepslate"),
|
||||||
|
("minecraft:infested_stone_bricks", "minecraft:cracked_infested_stone_bricks"),
|
||||||
|
("minecraft:cauldron", "minecraft:water_cauldron"),
|
||||||
|
("minecraft:cauldron", "minecraft:lava_cauldron"),
|
||||||
|
("minecraft:cauldron", "minecraft:powder_snow_cauldron"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Wool colors
|
||||||
|
WOOLS = [
|
||||||
|
"red", "blue", "cyan", "gray",
|
||||||
|
"lime", "pink", "black", "brown",
|
||||||
|
"green", "white", "orange", "purple",
|
||||||
|
"yellow", "magenta", "light_blue", "light_gray"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Wool variants
|
||||||
|
WOOL_VARIANTS = [
|
||||||
|
"carpet", "bed", "banner", "wall_banner"
|
||||||
|
]
|
||||||
|
|
||||||
|
# These will be removed from the textures' names
|
||||||
|
TO_STRIP = ["_top", "_stalk", "_end", "_round", "_still"]
|
||||||
|
|
||||||
|
# Minecraft version
|
||||||
|
MC_VERSION = "1.20.1"
|
||||||
|
|
||||||
|
# Minecraft root directory (platform dependent)
|
||||||
|
MC_ROOT = os.path.expanduser({
|
||||||
|
"Linux": r"~/.minecraft",
|
||||||
|
"Darwin": r"~/Library/Application Support/minecraft",
|
||||||
|
"Windows": r"%APPDATA%\.minecraft"
|
||||||
|
}[platform.system()])
|
||||||
|
|
||||||
|
|
||||||
|
def extract_textures(jar_path: str, outdir: str) -> None:
|
||||||
|
with zipfile.ZipFile(jar_path) as f:
|
||||||
|
for info in f.infolist():
|
||||||
|
path = info.filename
|
||||||
|
if not re.match(r"^assets/minecraft/textures/block/[^/]+\.png$", path):
|
||||||
|
continue
|
||||||
|
info.filename = os.path.basename(path)
|
||||||
|
f.extract(info, outdir)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
print(f"[1/5] Extracting Minecraft {MC_VERSION} textures")
|
||||||
|
jar_path = os.path.join(MC_ROOT, "versions", MC_VERSION, f"{MC_VERSION}.jar")
|
||||||
|
|
||||||
|
if not os.path.exists(jar_path):
|
||||||
|
print(f"Couldn't find Minecraft {MC_VERSION} JAR file")
|
||||||
|
print(f"Not at {jar_path}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
workdir = tempfile.TemporaryDirectory()
|
||||||
|
extract_textures(jar_path, workdir.name)
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
win = pygame.display.set_mode((1, 1))
|
pygame.display.set_mode((1, 1), pygame.NOFRAME | pygame.HIDDEN)
|
||||||
path = "/tmp/minecraft/textures/block"
|
|
||||||
with open("/tmp/overrides.json", "r") as f:
|
|
||||||
overrides = json.load(f)
|
|
||||||
colors = {}
|
colors = {}
|
||||||
paths = os.listdir(path)
|
paths = os.listdir(workdir.name)
|
||||||
total = len(paths)
|
total = len(paths)
|
||||||
skipped = 0
|
skipped = 0
|
||||||
|
print("[2/5] Averaging textures")
|
||||||
for i, filename in enumerate(paths):
|
for i, filename in enumerate(paths):
|
||||||
print(f"\r{i+1}/{total} ({i/total*100:.2f}%) {filename}", end="")
|
print(f"\r{i+1}/{total} ({i/total*100:.2f}%) {filename}", end="")
|
||||||
block, ext = filename.rsplit(".", 1)
|
block, ext = filename.rsplit(".", 1)
|
||||||
if ext != "png":
|
|
||||||
skipped += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
parts = set(block.split("_"))
|
parts = set(block.split("_"))
|
||||||
if not parts.isdisjoint(EXCLUDE):
|
if not parts.isdisjoint(EXCLUDE):
|
||||||
skipped += 1
|
skipped += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
block = block.replace("_top", "")
|
for s in TO_STRIP:
|
||||||
img = pygame.image.load(os.path.join(path, filename)).convert_alpha()
|
block = block.replace(s, "")
|
||||||
|
img = pygame.image.load(os.path.join(workdir.name, filename)).convert_alpha()
|
||||||
color = pygame.transform.average_color(img, consider_alpha=True)
|
color = pygame.transform.average_color(img, consider_alpha=True)
|
||||||
colors[f"minecraft:{block}"] = color[:3]
|
color = color[:3]
|
||||||
|
colors[f"minecraft:{block}"] = color
|
||||||
|
|
||||||
print(f"\r{total}/{total} (100%) Finished")
|
print(f"\r{total}/{total} (100%) Finished")
|
||||||
print(f"Skipped {skipped} files")
|
print(f"Skipped {skipped} files")
|
||||||
|
|
||||||
|
print("[3/5] Applying overrides")
|
||||||
|
with open(get_project_path("res", "color_overrides.json"), "r") as f:
|
||||||
|
overrides = json.load(f)
|
||||||
colors.update(overrides)
|
colors.update(overrides)
|
||||||
with open("/tmp/colors.json", "w") as f:
|
|
||||||
|
print("[4/5] Generating variants")
|
||||||
|
for to_variant in TO_VARIANT:
|
||||||
|
src = to_variant[0] if isinstance(to_variant, tuple) else to_variant
|
||||||
|
dst = to_variant[1] if isinstance(to_variant, tuple) else to_variant
|
||||||
|
|
||||||
|
for variant in VARIANTS:
|
||||||
|
TO_COPY.append((f"minecraft:{src}", f"minecraft:{dst}_{variant}"))
|
||||||
|
|
||||||
|
for color in WOOLS:
|
||||||
|
for variant in WOOL_VARIANTS:
|
||||||
|
TO_COPY.append((f"minecraft:{color}_wool", f"minecraft:{color}_{variant}"))
|
||||||
|
|
||||||
|
for src, dst in TO_COPY:
|
||||||
|
colors[dst] = colors[src]
|
||||||
|
|
||||||
|
print("[5/5] Exporting colors")
|
||||||
|
outpath = os.path.join(CACHE_DIR, "colors.json")
|
||||||
|
with open(outpath, "w") as f:
|
||||||
json.dump(colors, f, indent=4)
|
json.dump(colors, f, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
14
src/utils/paths.py
Normal file
14
src/utils/paths.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import os.path
|
||||||
|
|
||||||
|
import platformdirs
|
||||||
|
|
||||||
|
|
||||||
|
APP_NAME = "lycacraft-paths"
|
||||||
|
APP_AUTHOR = "lycacraft"
|
||||||
|
CACHE_DIR = platformdirs.user_cache_dir(appname=APP_NAME, appauthor=APP_AUTHOR, ensure_exists=True)
|
||||||
|
CONFIG_DIR = platformdirs.user_config_dir(appname=APP_NAME, appauthor=APP_AUTHOR, ensure_exists=True)
|
||||||
|
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_path(*elmts: str) -> str:
|
||||||
|
return os.path.join(ROOT, *elmts)
|
Loading…
Reference in New Issue
Block a user