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 os
|
||||
import platform
|
||||
import re
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
import pygame
|
||||
|
||||
from src.utils.paths import get_project_path, CACHE_DIR
|
||||
|
||||
# Textures with these parts will be excluded
|
||||
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:
|
||||
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()
|
||||
win = pygame.display.set_mode((1, 1))
|
||||
path = "/tmp/minecraft/textures/block"
|
||||
with open("/tmp/overrides.json", "r") as f:
|
||||
overrides = json.load(f)
|
||||
pygame.display.set_mode((1, 1), pygame.NOFRAME | pygame.HIDDEN)
|
||||
|
||||
colors = {}
|
||||
paths = os.listdir(path)
|
||||
paths = os.listdir(workdir.name)
|
||||
total = len(paths)
|
||||
skipped = 0
|
||||
print("[2/5] Averaging textures")
|
||||
for i, filename in enumerate(paths):
|
||||
print(f"\r{i+1}/{total} ({i/total*100:.2f}%) {filename}", end="")
|
||||
block, ext = filename.rsplit(".", 1)
|
||||
if ext != "png":
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
parts = set(block.split("_"))
|
||||
if not parts.isdisjoint(EXCLUDE):
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
block = block.replace("_top", "")
|
||||
img = pygame.image.load(os.path.join(path, filename)).convert_alpha()
|
||||
for s in TO_STRIP:
|
||||
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)
|
||||
colors[f"minecraft:{block}"] = color[:3]
|
||||
color = color[:3]
|
||||
colors[f"minecraft:{block}"] = color
|
||||
|
||||
print(f"\r{total}/{total} (100%) Finished")
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
|
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