diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricBlockModelSupplier.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricBlockModelSupplier.java new file mode 100644 index 0000000000..26ab7417e8 --- /dev/null +++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricBlockModelSupplier.java @@ -0,0 +1,83 @@ +package net.fabricmc.fabric.api.datagen.v1; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.util.Identifier; +import java.util.HashMap; +import java.util.function.Supplier; +import java.util.Map; + +/** + * Acceptable class for {@link net.minecraft.data.client.BlockStateModelGenerator}'s modelCollector. + * makes generating more specific block models easier for modders. + */ + +public class FabricBlockModelSupplier implements Supplier { + protected final JsonObject jsonObject; + + /** + * Constructor for vanilla parent types. + * + * @param type The parent type for the model. + */ + public FabricBlockModelSupplier(String type) + { + this.jsonObject = new JsonObject(); + this.jsonObject.addProperty("parent", "minecraft:block/" + type); + } + + /** + * Have an acceptable parameter in case of custom model parents. + * + * @param modID The modID as the prefix to the parent type in the Identifier. + * @param type The parent type for the model. + */ + public FabricBlockModelSupplier(String modID, String type) + { + this.jsonObject = new JsonObject(); + this.jsonObject.addProperty("parent", modID + ":block/" + type); + } + + /** + * Add HashMap textures to the model's JsonObject. + * + * @param fabricTextureMap {@link FabricTextureMap} containing the data for the textures. + */ + public FabricBlockModelSupplier addTextureData(FabricTextureMap fabricTextureMap) + { + HashMap textureMap = fabricTextureMap.get(); + JsonObject textureData = new JsonObject(); + for (Map.Entry entry : textureMap.entrySet()) { + String key = entry.getKey(); + Identifier identifier = entry.getValue(); + textureData.addProperty(key, identifier.getNamespace() + ":" + identifier.getPath()); + } + + this.jsonObject.add("textures", textureData); + return this; + } + + /** + * Add a sample texture as 'all' of the textures. Can only be used on the cube_all parent. + * + * @param texture {@link Identifier} for the location of the texture. + */ + public FabricBlockModelSupplier simpleCubeAllTextures(Identifier texture) + { + JsonObject textureData = new JsonObject(); + textureData.addProperty("all", texture.getNamespace() + ":" + texture.getPath()); + + this.jsonObject.add("textures", textureData); + return this; + } + + /** + * Returns the {@link JsonObject} for the Model. + * + * @return the supplier's {@link JsonObject} + */ + @Override + public JsonElement get() { + return this.jsonObject; + } +} diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricTextureMap.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricTextureMap.java new file mode 100644 index 0000000000..4f467b6ee2 --- /dev/null +++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/FabricTextureMap.java @@ -0,0 +1,58 @@ +package net.fabricmc.fabric.api.datagen.v1; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import net.minecraft.util.Identifier; + +/** + * Constructor class for making Maps for BlockModel textures. + * {@see FabricBlockModelSupplier} + */ + +public class FabricTextureMap { + private final HashMap map; + private final List bufferNames; + + /** + * Constructor for the FabricTextureMap. Sets the private variables for later accession. + * + * @param textureNames Different texture names. + */ + public FabricTextureMap(String... textureNames) { + this.map = new HashMap<>(); + this.bufferNames = Arrays.stream(textureNames).toList(); + } + + /** + * Link the texture names to the locations of their textures. + * + * @param textureLocations Identifiers for the location of each texture. + */ + public FabricTextureMap set(Identifier... textureLocations) { + List textureList = Arrays.stream(textureLocations).toList(); + int difference = textureList.size() - this.bufferNames.size(); + if (difference > 0) { + throw new IllegalStateException(String.format("You need to provide %s more texture names to allocate to texture locations!", difference)); + } + if (difference < 0) { + throw new IllegalStateException(String.format("You need to provide %s more texture locations to link to texture names!", -difference)); + } + + for (int i = 0; i < bufferNames.size(); i++) { + map.put(bufferNames.get(i), textureList.get(i)); + } + + return this; + } + + /** + * Return the resulting {@link HashMap}. + * + * @return this HashMap. + */ + public HashMap get() { + return this.map; + } +} diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/SimpleBlockStateSupplier.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/SimpleBlockStateSupplier.java new file mode 100644 index 0000000000..e5cab198e4 --- /dev/null +++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/SimpleBlockStateSupplier.java @@ -0,0 +1,57 @@ +package net.fabricmc.fabric.api.datagen.v1; + +import com.google.gson.JsonElement; + +import com.google.gson.JsonObject; + +import net.minecraft.block.Block; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.util.Identifier; + +/** + * Basic constructor class for generating non-variant aligned blockstates, + * since there is no built-in class for non-variant blockstates. + */ +public class SimpleBlockStateSupplier implements BlockStateSupplier { + private final Block block; + private final JsonObject jsonObject; + + /** + * Constructor for the SimpleBlockStateSupplier. Generates the entire jsonObject. + * + * @param block Block to be applied to. + * @param modelLocation Location of the block's default model. + */ + public SimpleBlockStateSupplier(Block block, Identifier modelLocation) + { + this.block=block; + this.jsonObject=new JsonObject(); + + JsonObject variants = new JsonObject(); + JsonObject defaultVariant = new JsonObject(); + defaultVariant.addProperty("model", modelLocation.getNamespace() + ":" + modelLocation.getPath()); + variants.add("", defaultVariant); + + this.jsonObject.add("variants", variants); + } + + /** + * Returns the block this is being applied to. + * + * @return this block + */ + @Override + public Block getBlock() { + return this.block; + } + + /** + * Returns the resulting {@link JsonElement} from the class. + * + * @return this jsonObject + */ + @Override + public JsonElement get() { + return this.jsonObject; + } +} diff --git a/fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java b/fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java index d42da15181..c4d52603ef 100644 --- a/fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java +++ b/fabric-data-generation-api-v1/src/testmod/java/net/fabricmc/fabric/test/datagen/DataGeneratorTestEntrypoint.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; +import java.util.HashMap; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; @@ -36,6 +37,13 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.fabricmc.fabric.api.datagen.v1.FabricBlockModelSupplier; + +import net.fabricmc.fabric.api.datagen.v1.FabricTextureMap; + +import net.fabricmc.fabric.api.datagen.v1.SimpleBlockStateSupplier; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -294,11 +302,29 @@ private TestModelProvider(FabricDataOutput output) { @Override public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) { - blockStateModelGenerator.registerSimpleCubeAll(SIMPLE_BLOCK); + // blockStateModelGenerator.registerSimpleCubeAll(SIMPLE_BLOCK); blockStateModelGenerator.registerSimpleCubeAll(BLOCK_WITHOUT_ITEM); blockStateModelGenerator.registerSimpleCubeAll(BLOCK_WITHOUT_LOOT_TABLE); blockStateModelGenerator.registerSimpleCubeAll(BLOCK_WITH_VANILLA_LOOT_TABLE); blockStateModelGenerator.registerSimpleCubeAll(BLOCK_THAT_DROPS_NOTHING); + + // registerSimpleCubeAll() -> FabricBlockModelSupplier::new + blockStateModelGenerator.blockStateCollector.accept(new SimpleBlockStateSupplier(SIMPLE_BLOCK, new Identifier(MOD_ID, "simple_block"))); + blockStateModelGenerator.modelCollector.accept(new Identifier(MOD_ID, "simple_block"), + () -> new FabricBlockModelSupplier("cube_all") + .addTextureData(new FabricTextureMap("all") + .set(new Identifier(MOD_ID, "block/simple_block"))) + .get()); + + /* In reality, for cube_all textures you'd want to try and do a .registerSimpleCubeAll() from + the blockStateModelGenerator. You could also do something like this if you needed to access + it using the FabricBlockModelSupplier: + + blockStateModelGenerator.modelCollector.accept(new Identifier(MOD_ID, "simple_block"), + () -> new FabricBlockModelSupplier("cube_all") + .simpleCubeAllTextures(new Identifier(MOD_ID, "block/simple_block")) + .get()); + */ } @Override