167 lines
7 KiB
Java
167 lines
7 KiB
Java
package net.minecraft.client.data.models;
|
|
|
|
import com.google.common.collect.Maps;
|
|
import com.google.gson.JsonElement;
|
|
import java.nio.file.Path;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.function.BiConsumer;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Stream;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.data.models.blockstates.BlockModelDefinitionGenerator;
|
|
import net.minecraft.client.data.models.model.ItemModelUtils;
|
|
import net.minecraft.client.data.models.model.ModelInstance;
|
|
import net.minecraft.client.data.models.model.ModelLocationUtils;
|
|
import net.minecraft.client.renderer.block.model.BlockModelDefinition;
|
|
import net.minecraft.client.renderer.item.ClientItem;
|
|
import net.minecraft.client.renderer.item.ItemModel;
|
|
import net.minecraft.core.Holder.Reference;
|
|
import net.minecraft.core.registries.BuiltInRegistries;
|
|
import net.minecraft.data.CachedOutput;
|
|
import net.minecraft.data.DataProvider;
|
|
import net.minecraft.data.PackOutput;
|
|
import net.minecraft.data.PackOutput.PathProvider;
|
|
import net.minecraft.data.PackOutput.Target;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.world.item.BlockItem;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.level.block.Block;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class ModelProvider implements DataProvider {
|
|
private final PathProvider blockStatePathProvider;
|
|
private final PathProvider itemInfoPathProvider;
|
|
private final PathProvider modelPathProvider;
|
|
|
|
public ModelProvider(PackOutput output) {
|
|
this.blockStatePathProvider = output.createPathProvider(Target.RESOURCE_PACK, "blockstates");
|
|
this.itemInfoPathProvider = output.createPathProvider(Target.RESOURCE_PACK, "items");
|
|
this.modelPathProvider = output.createPathProvider(Target.RESOURCE_PACK, "models");
|
|
}
|
|
|
|
@Override
|
|
public CompletableFuture<?> run(CachedOutput output) {
|
|
ModelProvider.ItemInfoCollector itemInfoCollector = new ModelProvider.ItemInfoCollector();
|
|
ModelProvider.BlockStateGeneratorCollector blockStateGeneratorCollector = new ModelProvider.BlockStateGeneratorCollector();
|
|
ModelProvider.SimpleModelCollector simpleModelCollector = new ModelProvider.SimpleModelCollector();
|
|
new BlockModelGenerators(blockStateGeneratorCollector, itemInfoCollector, simpleModelCollector).run();
|
|
new ItemModelGenerators(itemInfoCollector, simpleModelCollector).run();
|
|
blockStateGeneratorCollector.validate();
|
|
itemInfoCollector.finalizeAndValidate();
|
|
return CompletableFuture.allOf(
|
|
blockStateGeneratorCollector.save(output, this.blockStatePathProvider),
|
|
simpleModelCollector.save(output, this.modelPathProvider),
|
|
itemInfoCollector.save(output, this.itemInfoPathProvider)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public final String getName() {
|
|
return "Model Definitions";
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
static class BlockStateGeneratorCollector implements Consumer<BlockModelDefinitionGenerator> {
|
|
private final Map<Block, BlockModelDefinitionGenerator> generators = new HashMap();
|
|
|
|
public void accept(BlockModelDefinitionGenerator blockModelDefinitionGenerator) {
|
|
Block block = blockModelDefinitionGenerator.block();
|
|
BlockModelDefinitionGenerator blockModelDefinitionGenerator2 = (BlockModelDefinitionGenerator)this.generators.put(block, blockModelDefinitionGenerator);
|
|
if (blockModelDefinitionGenerator2 != null) {
|
|
throw new IllegalStateException("Duplicate blockstate definition for " + block);
|
|
}
|
|
}
|
|
|
|
public void validate() {
|
|
Stream<Reference<Block>> stream = BuiltInRegistries.BLOCK.listElements().filter(reference -> true);
|
|
List<ResourceLocation> list = stream.filter(reference -> !this.generators.containsKey(reference.value()))
|
|
.map(reference -> reference.key().location())
|
|
.toList();
|
|
if (!list.isEmpty()) {
|
|
throw new IllegalStateException("Missing blockstate definitions for: " + list);
|
|
}
|
|
}
|
|
|
|
public CompletableFuture<?> save(CachedOutput output, PathProvider pathProvider) {
|
|
Map<Block, BlockModelDefinition> map = Maps.transformValues(this.generators, BlockModelDefinitionGenerator::create);
|
|
Function<Block, Path> function = block -> pathProvider.json(block.builtInRegistryHolder().key().location());
|
|
return DataProvider.saveAll(output, BlockModelDefinition.CODEC, function, map);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
static class ItemInfoCollector implements ItemModelOutput {
|
|
private final Map<Item, ClientItem> itemInfos = new HashMap();
|
|
private final Map<Item, Item> copies = new HashMap();
|
|
|
|
@Override
|
|
public void accept(Item item, ItemModel.Unbaked model) {
|
|
this.register(item, new ClientItem(model, ClientItem.Properties.DEFAULT));
|
|
}
|
|
|
|
private void register(Item item, ClientItem clientItem) {
|
|
ClientItem clientItem2 = (ClientItem)this.itemInfos.put(item, clientItem);
|
|
if (clientItem2 != null) {
|
|
throw new IllegalStateException("Duplicate item model definition for " + item);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void copy(Item item1, Item item2) {
|
|
this.copies.put(item2, item1);
|
|
}
|
|
|
|
public void finalizeAndValidate() {
|
|
BuiltInRegistries.ITEM.forEach(item -> {
|
|
if (!this.copies.containsKey(item)) {
|
|
if (item instanceof BlockItem blockItem && !this.itemInfos.containsKey(blockItem)) {
|
|
ResourceLocation resourceLocation = ModelLocationUtils.getModelLocation(blockItem.getBlock());
|
|
this.accept(blockItem, ItemModelUtils.plainModel(resourceLocation));
|
|
}
|
|
}
|
|
});
|
|
this.copies.forEach((item, item2) -> {
|
|
ClientItem clientItem = (ClientItem)this.itemInfos.get(item2);
|
|
if (clientItem == null) {
|
|
throw new IllegalStateException("Missing donor: " + item2 + " -> " + item);
|
|
} else {
|
|
this.register(item, clientItem);
|
|
}
|
|
});
|
|
List<ResourceLocation> list = BuiltInRegistries.ITEM
|
|
.listElements()
|
|
.filter(reference -> !this.itemInfos.containsKey(reference.value()))
|
|
.map(reference -> reference.key().location())
|
|
.toList();
|
|
if (!list.isEmpty()) {
|
|
throw new IllegalStateException("Missing item model definitions for: " + list);
|
|
}
|
|
}
|
|
|
|
public CompletableFuture<?> save(CachedOutput output, PathProvider pathProvider) {
|
|
return DataProvider.saveAll(output, ClientItem.CODEC, item -> pathProvider.json(item.builtInRegistryHolder().key().location()), this.itemInfos);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
static class SimpleModelCollector implements BiConsumer<ResourceLocation, ModelInstance> {
|
|
private final Map<ResourceLocation, ModelInstance> models = new HashMap();
|
|
|
|
public void accept(ResourceLocation resourceLocation, ModelInstance modelInstance) {
|
|
Supplier<JsonElement> supplier = (Supplier<JsonElement>)this.models.put(resourceLocation, modelInstance);
|
|
if (supplier != null) {
|
|
throw new IllegalStateException("Duplicate model definition for " + resourceLocation);
|
|
}
|
|
}
|
|
|
|
public CompletableFuture<?> save(CachedOutput output, PathProvider pathProvider) {
|
|
return DataProvider.saveAll(output, Supplier::get, pathProvider::json, this.models);
|
|
}
|
|
}
|
|
}
|