Search in sources :

Example 1 with PaletteExtractor

use of io.github.lukebemish.dynamic_asset_generator.client.api.PaletteExtractor in project excavated_variants by lukebemish.

the class BlockStateAssembler method getMap.

private static Map<ResourceLocation, Supplier<InputStream>> getMap(Collection<Pair<BaseOre, BaseStone>> original_pairs, List<Pair<BaseOre, BaseStone>> to_make) {
    BlockModelDefinition.Context ctx = new BlockModelDefinition.Context();
    Map<ResourceLocation, Supplier<InputStream>> resources = new HashMap<>();
    Map<String, Pair<BlockModelDefinition, List<ResourceLocation>>> oreInfoMap = new HashMap<>();
    Map<String, Pair<BlockModelDefinition, List<ResourceLocation>>> stoneInfoMap = new HashMap<>();
    Map<String, ArrayList<Triple<PaletteExtractor, ResourceLocation, Boolean>>> extractorMap = new HashMap<>();
    for (Pair<BaseOre, BaseStone> p : to_make) {
        var ore = p.first();
        var stone = p.last();
        try {
            if (!oreInfoMap.containsKey(ore.id)) {
                ResourceLocation oreRl = ore.block_id.get(0);
                oreInfoMap.put(ore.id, getInfoFromBlockstate(oreRl, ctx));
            }
            if (!stoneInfoMap.containsKey(stone.id)) {
                ResourceLocation stoneRl = stone.block_id;
                stoneInfoMap.put(stone.id, getInfoFromBlockstate(stoneRl, ctx));
            }
        } catch (IOException e) {
            // TODO: add stuff here
            // Potentially ignore this; it could be we're running too early.
            ExcavatedVariants.LOGGER.info(e);
        // throw new RuntimeException(e);
        }
    }
    for (Pair<BaseOre, BaseStone> p : original_pairs) {
        var ore = p.first();
        var base = p.last();
        try {
            if (!oreInfoMap.containsKey(ore.id)) {
                ResourceLocation oreRl = ore.block_id.get(0);
                oreInfoMap.put(ore.id, getInfoFromBlockstate(oreRl, ctx));
            }
            if (!stoneInfoMap.containsKey(base.id)) {
                ResourceLocation stoneRl = base.block_id;
                stoneInfoMap.put(base.id, getInfoFromBlockstate(stoneRl, ctx));
            }
            var stoneInfo = stoneInfoMap.get(base.id);
            var oreInfo = oreInfoMap.get(ore.id);
            if (stoneInfo != null && oreInfo != null && stoneInfo.last().size() >= 1 && oreInfo.last().size() >= 1) {
                ArrayList<Triple<PaletteExtractor, ResourceLocation, Boolean>> extractors = new ArrayList<>();
                extractorMap.put(ore.id, extractors);
                for (ResourceLocation rl : oreInfo.last()) {
                    var is = ClientPrePackRepository.getResource(rl);
                    var img = NativeImage.read(is);
                    boolean isTransparent = false;
                    outer: for (int x = 0; x < img.getWidth(); x++) {
                        for (int y = 0; y < img.getHeight(); y++) {
                            int c = img.getPixelRGBA(x, y);
                            float alpha = (c >> 24 & 255) / 255.0F;
                            if (alpha < 0.5f) {
                                isTransparent = true;
                                break outer;
                            }
                        }
                    }
                    PaletteExtractor extractor = isTransparent ? null : new PaletteExtractor(stoneInfo.last().get(0), rl, 6, true, true, 0.2).fillHoles(true);
                    extractors.add(new Triple<>(extractor, rl, !isTransparent));
                }
            } else {
                ExcavatedVariants.LOGGER.warn("Bad info while extracting from blocks {} and {}:{}", ore.block_id.get(0).toString(), base.block_id.toString(), (stoneInfo == null ? "\nMissing stone block model info" : "") + (oreInfo == null ? "\nMissing ore block model info" : "") + (stoneInfo != null && (stoneInfo.last().size() < 1) ? "\nNo stone textures found" : "") + (oreInfo != null && (oreInfo.last().size() < 1) ? "\nNo ore textures found" : ""));
            }
        } catch (IOException e) {
            // TODO: add stuff here
            // Potentially ignore this; it could be we're running too early.
            ExcavatedVariants.LOGGER.info(e);
        // throw new RuntimeException(e);
        } catch (JsonSyntaxException e) {
            // TODO: add other stuff here
            ExcavatedVariants.LOGGER.error(e);
        // throw new RuntimeException(e);
        }
    }
    for (Pair<BaseOre, BaseStone> p : to_make) {
        var oreInfo = oreInfoMap.get(p.first().id);
        var stoneInfo = stoneInfoMap.get(p.last().id);
        var extractorPair = extractorMap.get(p.first().id);
        var stone = p.last();
        var ore = p.first();
        var full_id = stone.id + "_" + ore.id;
        var outBlock = ExcavatedVariants.getBlocks().get(full_id);
        if (oreInfo != null && stoneInfo != null && extractorPair != null && outBlock != null) {
            // stone, ore -> new
            Map<Pair<ResourceLocation, ResourceLocation>, ResourceLocation> texMap = new HashMap<>();
            // First, create new textures:
            int index = 0;
            for (ResourceLocation stoneBG : stoneInfo.last()) {
                for (Triple<PaletteExtractor, ResourceLocation, Boolean> exp : extractorPair) {
                    if (exp.last()) {
                        IPalettePlan plan = new ForegroundTransferType(exp.first(), stoneBG, true, false);
                        ResourceLocation outRL = new ResourceLocation(ExcavatedVariants.MOD_ID, "textures/block/" + full_id + index + ".png");
                        index++;
                        resources.put(outRL, plan.getStream(outRL));
                        texMap.put(new Pair<>(stoneBG, exp.second()), outRL);
                    } else {
                        texMap.put(new Pair<>(stoneBG, exp.second()), exp.second());
                    }
                }
            }
            HashMap<Pair<ResourceLocation, ResourceLocation>, ResourceLocation> newTexMap = new HashMap<>();
            for (Pair<ResourceLocation, ResourceLocation> pair : texMap.keySet()) {
                var p1 = pair.first().getPath().substring(9);
                p1 = p1.substring(0, p1.length() - 4);
                var rl1 = new ResourceLocation(pair.first().getNamespace(), p1);
                p1 = pair.last().getPath().substring(9);
                p1 = p1.substring(0, p1.length() - 4);
                var rl2 = new ResourceLocation(pair.last().getNamespace(), p1);
                p1 = texMap.get(pair).getPath().substring(9);
                p1 = p1.substring(0, p1.length() - 4);
                var rl3 = new ResourceLocation(texMap.get(pair).getNamespace(), p1);
                newTexMap.put(new Pair<>(rl1, rl2), rl3);
            }
            // Next, process the models:
            var defaultModels = oreInfo.first().getMultiVariants().stream().findFirst().get().getVariants().stream().map(Variant::getModelLocation).toList();
            var stoneModel = stoneInfo.first().getMultiVariants().stream().findFirst().get().getVariants().stream().map(Variant::getModelLocation).findFirst().get();
            var outModelRLs = new ArrayList<ResourceLocation>();
            try {
                InputStream read;
                try {
                    read = ClientPrePackRepository.getResource(new ResourceLocation(stoneModel.getNamespace(), "models/" + stoneModel.getPath() + ".json"));
                } catch (IOException e) {
                    read = BackupFetcher.provideBlockModelFile(stoneModel);
                }
                BlockModelParser parentModel = GSON.fromJson(new BufferedReader(new InputStreamReader(read, StandardCharsets.UTF_8)), BlockModelParser.class);
                List<ResourceLocation> stoneLocs = parentModel.textures.values().stream().map(x -> ResourceLocation.of(x, ':')).toList();
                int i2 = 0;
                for (ResourceLocation m : defaultModels) {
                    InputStream stoneRead;
                    try {
                        stoneRead = ClientPrePackRepository.getResource(new ResourceLocation(stoneModel.getNamespace(), "models/" + stoneModel.getPath() + ".json"));
                    } catch (IOException e) {
                        stoneRead = BackupFetcher.provideBlockModelFile(stoneModel);
                    }
                    BlockModelParser outputModel = GSON.fromJson(new BufferedReader(new InputStreamReader(stoneRead, StandardCharsets.UTF_8)), BlockModelParser.class);
                    try {
                        stoneRead = ClientPrePackRepository.getResource(new ResourceLocation(stoneModel.getNamespace(), "models/" + stoneModel.getPath() + ".json"));
                    } catch (IOException e) {
                        stoneRead = BackupFetcher.provideBlockModelFile(stoneModel);
                    }
                    JsonObject outputMap = GSON.fromJson(new BufferedReader(new InputStreamReader(stoneRead, StandardCharsets.UTF_8)), JsonObject.class);
                    InputStream oreRead;
                    try {
                        oreRead = ClientPrePackRepository.getResource(new ResourceLocation(m.getNamespace(), "models/" + m.getPath() + ".json"));
                    } catch (IOException e) {
                        oreRead = BackupFetcher.provideBlockModelFile(m);
                    }
                    StringBuilder oreTextBuilder = new StringBuilder();
                    Reader oreReader = new BufferedReader(new InputStreamReader(oreRead, Charset.forName(StandardCharsets.UTF_8.name())));
                    int oreC = 0;
                    while ((oreC = oreReader.read()) != -1) {
                        oreTextBuilder.append((char) oreC);
                    }
                    BlockModelParser oreModel = GSON.fromJson(oreTextBuilder.toString(), BlockModelParser.class);
                    String maybeTex = oreModel.textures.values().stream().filter(x -> !stoneLocs.contains(ResourceLocation.of(x, ':')) && newTexMap.keySet().stream().anyMatch(y -> {
                        var rl = ResourceLocation.of(x, ':');
                        return y.last().equals(rl);
                    })).findFirst().orElse(null);
                    ResourceLocation mainOreTex = maybeTex == null ? null : ResourceLocation.of(maybeTex, ':');
                    var overlayTextures = oreModel.textures.values().stream().filter(x -> newTexMap.entrySet().stream().anyMatch(e -> {
                        var y = e.getKey();
                        var rl = ResourceLocation.of(x, ':');
                        return y.last().equals(rl) && y.last().equals(e.getValue());
                    })).toList();
                    for (String s : outputModel.textures.keySet()) {
                        String val = outputModel.textures.get(s);
                        ResourceLocation old = ResourceLocation.of(val, ':');
                        ResourceLocation lookup = newTexMap.get(new Pair<>(old, mainOreTex));
                        if (lookup != null)
                            outputModel.replaceTexture(old, lookup);
                    }
                    int i = 0;
                    for (String s : overlayTextures) {
                        var rl = ResourceLocation.of(s, ':');
                        outputModel.addOverlay(i, rl);
                        i++;
                    }
                    outputMap.add("textures", GSON.toJsonTree(outputModel.textures));
                    if (outputModel.elements != null && outputModel.elements.size() != 0)
                        outputMap.add("elements", outputModel.elements);
                    var outModelRL = new ResourceLocation(ExcavatedVariants.MOD_ID, "block/" + full_id + i2);
                    outModelRLs.add(outModelRL);
                    String finalJson = GSON.toJson(outputMap);
                    resources.put(new ResourceLocation(ExcavatedVariants.MOD_ID, "models/" + outModelRL.getPath() + ".json"), () -> new ByteArrayInputStream(finalJson.getBytes()));
                    i2++;
                }
                // Create output BS
                var assembler = BlockstateModelParser.create(outBlock, outModelRLs);
                String bs = GSON.toJson(assembler);
                resources.put(new ResourceLocation(ExcavatedVariants.MOD_ID, "blockstates/" + full_id + ".json"), () -> new ByteArrayInputStream(bs.getBytes()));
            } catch (IOException e) {
                // TODO: add stuff here
                ExcavatedVariants.LOGGER.error(e);
            // throw new RuntimeException(e);
            }
        } else {
            ExcavatedVariants.LOGGER.warn("Missing {}for ore {}", "" + (oreInfo == null ? "ore model info, " : "") + (stoneInfo == null ? "stone model info, " : "") + (extractorPair == null ? "texture extractor info, " : "") + (outBlock == null ? "registered block, " : ""), full_id);
        }
    }
    return resources;
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) JsonObject(com.google.gson.JsonObject) MultiVariant(net.minecraft.client.renderer.block.model.MultiVariant) java.util(java.util) BaseStone(io.github.lukebemish.excavated_variants.data.BaseStone) PaletteExtractor(io.github.lukebemish.dynamic_asset_generator.client.api.PaletteExtractor) JsonSyntaxException(com.google.gson.JsonSyntaxException) Pair(io.github.lukebemish.excavated_variants.util.Pair) ExcavatedVariants(io.github.lukebemish.excavated_variants.ExcavatedVariants) Supplier(java.util.function.Supplier) GsonBuilder(com.google.gson.GsonBuilder) StandardCharsets(java.nio.charset.StandardCharsets) ForegroundTransferType(io.github.lukebemish.dynamic_asset_generator.client.api.ForegroundTransferType) IPalettePlan(io.github.lukebemish.dynamic_asset_generator.client.util.IPalettePlan) BlockModelDefinition(net.minecraft.client.renderer.block.model.BlockModelDefinition) Variant(net.minecraft.client.renderer.block.model.Variant) java.io(java.io) Charset(java.nio.charset.Charset) Gson(com.google.gson.Gson) Triple(io.github.lukebemish.excavated_variants.util.Triple) DynAssetGeneratorClientAPI(io.github.lukebemish.dynamic_asset_generator.client.api.DynAssetGeneratorClientAPI) NativeImage(com.mojang.blaze3d.platform.NativeImage) ClientPrePackRepository(io.github.lukebemish.dynamic_asset_generator.client.api.ClientPrePackRepository) BaseOre(io.github.lukebemish.excavated_variants.data.BaseOre) ForegroundTransferType(io.github.lukebemish.dynamic_asset_generator.client.api.ForegroundTransferType) JsonObject(com.google.gson.JsonObject) BaseOre(io.github.lukebemish.excavated_variants.data.BaseOre) ResourceLocation(net.minecraft.resources.ResourceLocation) IPalettePlan(io.github.lukebemish.dynamic_asset_generator.client.util.IPalettePlan) Supplier(java.util.function.Supplier) Pair(io.github.lukebemish.excavated_variants.util.Pair) BlockModelDefinition(net.minecraft.client.renderer.block.model.BlockModelDefinition) BaseStone(io.github.lukebemish.excavated_variants.data.BaseStone) Triple(io.github.lukebemish.excavated_variants.util.Triple) MultiVariant(net.minecraft.client.renderer.block.model.MultiVariant) Variant(net.minecraft.client.renderer.block.model.Variant) JsonSyntaxException(com.google.gson.JsonSyntaxException) PaletteExtractor(io.github.lukebemish.dynamic_asset_generator.client.api.PaletteExtractor)

Aggregations

Gson (com.google.gson.Gson)1 GsonBuilder (com.google.gson.GsonBuilder)1 JsonObject (com.google.gson.JsonObject)1 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 NativeImage (com.mojang.blaze3d.platform.NativeImage)1 ClientPrePackRepository (io.github.lukebemish.dynamic_asset_generator.client.api.ClientPrePackRepository)1 DynAssetGeneratorClientAPI (io.github.lukebemish.dynamic_asset_generator.client.api.DynAssetGeneratorClientAPI)1 ForegroundTransferType (io.github.lukebemish.dynamic_asset_generator.client.api.ForegroundTransferType)1 PaletteExtractor (io.github.lukebemish.dynamic_asset_generator.client.api.PaletteExtractor)1 IPalettePlan (io.github.lukebemish.dynamic_asset_generator.client.util.IPalettePlan)1 ExcavatedVariants (io.github.lukebemish.excavated_variants.ExcavatedVariants)1 BaseOre (io.github.lukebemish.excavated_variants.data.BaseOre)1 BaseStone (io.github.lukebemish.excavated_variants.data.BaseStone)1 Pair (io.github.lukebemish.excavated_variants.util.Pair)1 Triple (io.github.lukebemish.excavated_variants.util.Triple)1 java.io (java.io)1 Charset (java.nio.charset.Charset)1 StandardCharsets (java.nio.charset.StandardCharsets)1 java.util (java.util)1 Supplier (java.util.function.Supplier)1