361 lines
12 KiB
TypeScript
361 lines
12 KiB
TypeScript
import { encodeBase64 } from "@std/encoding/base64";
|
|
import { readDirFiles } from "../util/readDir.ts";
|
|
import { createIsometricCube } from "./renderer.ts";
|
|
|
|
export const readBlocks = async (path: string, read?: (b: BlockItem, i: number) => void) => {
|
|
const blocks: BlockItem[] =
|
|
(await readDirFiles(path + "/assets/minecraft/blockstates"))
|
|
.map((b) => ({
|
|
name: b.replace(".json", ""),
|
|
resourceLocation: "minecraft:" + b.replace(".json", ""),
|
|
images: [],
|
|
}));
|
|
|
|
const blockTextures = await readDirFiles(
|
|
path + "/assets/minecraft/textures/block",
|
|
);
|
|
|
|
const modelPath = path + "/assets/minecraft/models/block";
|
|
for (const block of blocks) {
|
|
let name = block.name;
|
|
if (
|
|
block.name.startsWith("air") ||
|
|
block.name.startsWith("void_air") ||
|
|
block.name.startsWith("cave_air") ||
|
|
block.name.startsWith("end_gateway") ||
|
|
block.name.endsWith("_door") ||
|
|
block.name.endsWith("_trapdoor") ||
|
|
block.name.endsWith("_banner") ||
|
|
block.name.endsWith("_fence_gate") ||
|
|
block.name.endsWith("_pressure_plate") ||
|
|
block.name.endsWith("_button") ||
|
|
block.name.endsWith("lever") ||
|
|
block.name.endsWith("_sign") ||
|
|
block.name.endsWith("torch") ||
|
|
block.name.endsWith("_fence") ||
|
|
block.name.endsWith("_wall") ||
|
|
block.name.endsWith("_skull") ||
|
|
block.name.endsWith("_head") ||
|
|
block.name.includes("bubble_column") ||
|
|
block.name.includes("tripwire_hook") ||
|
|
block.name.includes("tripwire") ||
|
|
block.name == undefined ||
|
|
block.name.includes("chest") ||
|
|
block.name.includes("command")
|
|
) continue;
|
|
if (block.name.includes("water") || block.name.includes("lava")) {
|
|
const what = block.name.includes("water") ? "water" : "lava";
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/block/${what}_still.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name === "nether_portal") {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/block/nether_portal.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (["fire", "soul_fire"].includes(block.name)) {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/block/${block.name}_0.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name.includes("cake")) {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/item/cake.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name.endsWith("_bed")) {
|
|
const itemTexLoc = path + "/assets/minecraft/textures/entity/bed/" +
|
|
block.name.replace(/_bed$/, "") + ".png";
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name === "nether_portal") {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/block/nether_portal.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name.includes("dripleaf") && !block.name.includes("stem")) {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/block/${block.name}_top.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (
|
|
[
|
|
"carrots",
|
|
"potatoes",
|
|
"wheat",
|
|
"beetroots",
|
|
"grass",
|
|
"kelp",
|
|
"light",
|
|
"bell",
|
|
"redstone_wire",
|
|
"sweet_berry_bush",
|
|
"cocoa",
|
|
"nether_wart",
|
|
"repeater",
|
|
"bamboo",
|
|
"pitcher_plant",
|
|
"campfire",
|
|
"soul_campfire",
|
|
].includes(block.name)
|
|
) {
|
|
const itemTexLoc = path + "/assets/minecraft/textures/item/" +
|
|
block.name
|
|
.replace("large_fern", "fern")
|
|
.replace("tall_seagrass", "seagrass")
|
|
.replace(/ss$/, "?")
|
|
.replace(/e?s$/, "")
|
|
.replace("?", "ss")
|
|
.replace("_bush", "")
|
|
.replace("berry", "berries")
|
|
.replace("cocoa", "cocoa_beans")
|
|
.replace("_wire", "") +
|
|
".png";
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (
|
|
[
|
|
"melon_stem",
|
|
"pumpkin_stem",
|
|
"fern",
|
|
"large_fern",
|
|
"lilac",
|
|
"azure_bluet",
|
|
"red_tulip",
|
|
"orange_tulip",
|
|
"pink_tulip",
|
|
"white_tulip",
|
|
"oxeye_daisy",
|
|
"cornflower",
|
|
"lily_of_the_valley",
|
|
"wither_rose",
|
|
"rose_bush",
|
|
"peony",
|
|
"sunflower",
|
|
"torchflower_crop",
|
|
"suspicious_sand",
|
|
"suspicious_gravel",
|
|
"scaffolding",
|
|
"respawn_anchor",
|
|
"short_grass",
|
|
"tall_grass",
|
|
"seagrass",
|
|
"tall_seagrass",
|
|
"frosted_ice",
|
|
"pitcher_crop",
|
|
"iron_bars",
|
|
].includes(block.name)
|
|
) {
|
|
const textures = blockTextures.filter((t) => t.includes(block.name))
|
|
.reverse().filter((t) => !t.endsWith("mcmeta"));
|
|
const itemTexLoc = path + "/assets/minecraft/textures/block/" +
|
|
textures[0];
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name.startsWith("waxed")) {
|
|
name = block.name.replace(/^waxed_?/, "");
|
|
}
|
|
if (block.name.startsWith("infested")) {
|
|
name = block.name.replace(/^infested_?/, "");
|
|
}
|
|
if (block.name.endsWith("_pane")) {
|
|
name = block.name.replace(/_pane$/, "");
|
|
}
|
|
if (block.name === "pink_petals") {
|
|
name = "pink_petals_4";
|
|
}
|
|
if (block.name.includes("candle")) {
|
|
const itemTexLoc = path +
|
|
`/assets/minecraft/textures/item/${block.name}.png`;
|
|
const itemImage = await Deno.readFile(itemTexLoc);
|
|
block.images.push("data:image/png;base64," + encodeBase64(itemImage));
|
|
continue;
|
|
}
|
|
if (block.name.includes("cauldron")) {
|
|
const textures = blockTextures.filter((t) => t.includes("cauldron"));
|
|
for (const texture of textures) {
|
|
const texLoc = texture.replace("minecraft:", "");
|
|
const image = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/block/" + texLoc,
|
|
);
|
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
|
}
|
|
continue;
|
|
}
|
|
if (block.name === "snow") {
|
|
name = "snow_height2";
|
|
}
|
|
const data = await Deno.readTextFile(
|
|
modelPath + "/" + name + ".json",
|
|
);
|
|
const modelJson = JSON.parse(data);
|
|
if (modelJson.textures && !modelJson.elements) {
|
|
if (modelJson.textures.all) {
|
|
const texLoc = modelJson.textures.all;
|
|
const image = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" + texLoc.replace(
|
|
"minecraft:",
|
|
"",
|
|
) + ".png",
|
|
);
|
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
|
continue;
|
|
}
|
|
if (modelJson.textures.front) {
|
|
const frontImage = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" +
|
|
modelJson.textures.front.replace(
|
|
"minecraft:",
|
|
"",
|
|
) + ".png",
|
|
);
|
|
|
|
const frontB64 = "data:image/png;base64," + encodeBase64(frontImage);
|
|
|
|
const topImage = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" +
|
|
(modelJson.textures.top ?? modelJson.textures.side).replace(
|
|
"minecraft:",
|
|
"",
|
|
) + ".png",
|
|
);
|
|
|
|
const topB64 = "data:image/png;base64," + encodeBase64(topImage);
|
|
|
|
const sideImage = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" +
|
|
modelJson.textures.side.replace(
|
|
"minecraft:",
|
|
"",
|
|
) + ".png",
|
|
);
|
|
|
|
const sideB64 = "data:image/png;base64," + encodeBase64(sideImage);
|
|
block.images.push(await createIsometricCube(frontB64, sideB64, topB64));
|
|
continue;
|
|
}
|
|
if (modelJson.textures.side) {
|
|
const sideImage = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" +
|
|
modelJson.textures.side.replace(
|
|
"minecraft:",
|
|
"",
|
|
) + ".png",
|
|
);
|
|
|
|
const sideB64 = "data:image/png;base64," + encodeBase64(sideImage);
|
|
|
|
const topImage = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/" +
|
|
(modelJson.textures.top ?? modelJson.textures.bottom ??
|
|
modelJson.textures.side).replace(
|
|
"minecraft:",
|
|
"",
|
|
) +
|
|
".png",
|
|
);
|
|
|
|
const topB64 = "data:image/png;base64," + encodeBase64(topImage);
|
|
block.images.push(await createIsometricCube(sideB64, sideB64, topB64));
|
|
continue;
|
|
}
|
|
}
|
|
const textures = blockTextures.filter((t) =>
|
|
t.includes(block.name) && !t.includes("mcmeta")
|
|
);
|
|
|
|
for (const texture of textures) {
|
|
const texLoc = texture.replace("minecraft:", "");
|
|
const image = await Deno.readFile(
|
|
path + "/assets/minecraft/textures/block/" + texLoc,
|
|
);
|
|
const b64 = "data:image/png;base64," + encodeBase64(image);
|
|
block.images.push(await createIsometricCube(b64, b64, b64));
|
|
}
|
|
}
|
|
|
|
let i = 0;
|
|
for (const block of blocks) {
|
|
read?.(block, i);
|
|
i++;
|
|
}
|
|
return blocks;
|
|
};
|
|
|
|
export const readItems = async (path: string, read?: (b: BlockItem) => void) => {
|
|
const items: BlockItem[] =
|
|
(await readDirFiles(path + "/assets/minecraft/models/item")).map((i) => ({
|
|
name: i.replace(".json", ""),
|
|
resourceLocation: "minecraft:" + i.replace(".json", ""),
|
|
images: [],
|
|
}));
|
|
|
|
for (const item of items) {
|
|
let name = item.name;
|
|
if (item.name.startsWith("air")) continue;
|
|
if (item.name.startsWith("waxed")) name = item.name.replace(/^waxed_?/, "");
|
|
|
|
const data = await Deno.readFile(
|
|
path + "/assets/minecraft/models/item/" + name + ".json",
|
|
);
|
|
const json = JSON.parse(new TextDecoder().decode(data));
|
|
const texDir = path + "/assets/minecraft/textures/";
|
|
if (json.textures) {
|
|
const texLoc = json.textures.layer0;
|
|
if (texLoc) {
|
|
const data = await Deno.readFile(
|
|
texDir + texLoc.replace("minecraft:", "") + ".png",
|
|
);
|
|
item.images.push("data:image/png;base64," + encodeBase64(data));
|
|
}
|
|
} else if (json.parent) {
|
|
const parent = await Deno.readFile(
|
|
path + "/assets/minecraft/models/" +
|
|
json.parent.replace("minecraft:", "") + ".json",
|
|
);
|
|
const parentJson = JSON.parse(new TextDecoder().decode(parent));
|
|
if (parentJson.textures) {
|
|
let texLoc = parentJson.textures.all;
|
|
if (!texLoc) texLoc = parentJson.textures.side;
|
|
if (!texLoc) texLoc = parentJson.textures.top;
|
|
if (!texLoc) texLoc = parentJson.textures.bottom;
|
|
if (texLoc) {
|
|
const data = await Deno.readFile(
|
|
texDir + texLoc.replace("minecraft:", "") + ".png",
|
|
);
|
|
item.images.push("data:image/png;base64," + encodeBase64(data));
|
|
}
|
|
}
|
|
}
|
|
read?.(item);
|
|
}
|
|
|
|
return items;
|
|
};
|
|
|
|
if (import.meta.main) {
|
|
const path = "./resources/1.21.1";
|
|
console.log(await readItems(path));
|
|
}
|