diff --git a/build.gradle b/build.gradle index 1cb252f6..52b3c99c 100644 --- a/build.gradle +++ b/build.gradle @@ -3,17 +3,19 @@ plugins { id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +sourceCompatibility = JavaVersion.VERSION_21 +targetCompatibility = JavaVersion.VERSION_21 archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group repositories { - maven { url = "https://maven.terraformersmc.com/" } - maven { url = "https://ueaj.dev/maven/" } - maven { url = "https://api.modrinth.com/maven/" } + maven { url = 'https://maven.terraformersmc.com/' } + maven { url = 'https://ueaj.dev/maven/' } + maven { url = 'https://api.modrinth.com/maven/' } + + maven { url = 'https://jitpack.io' } } dependencies { @@ -25,10 +27,6 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - // ARRP. This is for generating a runtime resource pack (conditionally, as well) - modImplementation "net.devtech:arrp:${project.arrp_version}" - include "net.devtech:arrp:${project.arrp_version}" - // Mod Menu because config screen access from another place modApi "com.terraformersmc:modmenu:${project.modmenu_version}" diff --git a/gradle.properties b/gradle.properties index b0712ebd..016d3afd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,16 +1,16 @@ org.gradle.jvmargs=-Xmx2G -minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.3 +minecraft_version=1.20.6 +yarn_mappings=1.20.6+build.3 loader_version=0.15.11 -fabric_version=0.97.0+1.20.4 +fabric_version=0.99.4+1.20.6 -mod_version = 0.10+1.20.4 +mod_version = 0.10+1.20.6 maven_group = foundationgames archives_base_name = enhancedblockentities -arrp_version=0.8.1 -modmenu_version=9.2.0-beta.2 +arrp_version=0.8.2 +modmenu_version=10.0.0-beta.1 -sodium_version=mc1.20.4-0.5.8 +sodium_version=mc1.20.6-0.5.8 diff --git a/src/main/java/foundationgames/enhancedblockentities/EBESetup.java b/src/main/java/foundationgames/enhancedblockentities/EBESetup.java index 63ffd097..c02c2d4a 100644 --- a/src/main/java/foundationgames/enhancedblockentities/EBESetup.java +++ b/src/main/java/foundationgames/enhancedblockentities/EBESetup.java @@ -18,7 +18,6 @@ import foundationgames.enhancedblockentities.util.EBEUtil; import foundationgames.enhancedblockentities.util.ResourceUtil; import foundationgames.enhancedblockentities.util.duck.BakedModelManagerAccess; -import net.devtech.arrp.json.models.JModel; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin; import net.minecraft.block.Block; @@ -32,7 +31,6 @@ import net.minecraft.client.render.model.BakedModel; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKey; -import net.minecraft.resource.ResourceType; import net.minecraft.state.property.Properties; import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; @@ -50,19 +48,17 @@ public static void setupRRPChests() { p = ResourceUtil.getBasePack(); - ResourceUtil.addSingleChestModels("entity/chest/normal", "chest", p); - ResourceUtil.addDoubleChestModels("entity/chest/normal_left", "entity/chest/normal_right","chest", p); - ResourceUtil.addSingleChestModels("entity/chest/trapped", "trapped_chest", p); - ResourceUtil.addDoubleChestModels("entity/chest/trapped_left", "entity/chest/trapped_right","trapped_chest", p); - ResourceUtil.addSingleChestModels("entity/chest/christmas", "christmas_chest", p); - ResourceUtil.addDoubleChestModels("entity/chest/christmas_left", "entity/chest/christmas_right","christmas_chest", p); - ResourceUtil.addSingleChestModels("entity/chest/ender", "ender_chest", p); + ResourceUtil.addSingleChestModels("normal", "chest", p); + ResourceUtil.addDoubleChestModels("normal_left", "normal_right","chest", p); + ResourceUtil.addSingleChestModels("trapped", "trapped_chest", p); + ResourceUtil.addDoubleChestModels("trapped_left", "trapped_right","trapped_chest", p); + ResourceUtil.addSingleChestModels("christmas", "christmas_chest", p); + ResourceUtil.addDoubleChestModels("christmas_left", "christmas_right","christmas_chest", p); + ResourceUtil.addSingleChestModels("ender", "ender_chest", p); - p.addResource(ResourceType.CLIENT_RESOURCES, new Identifier("models/item/chest.json"), - ResourceUtil.createChestItemModelResource("chest_center").getBytes()); - p.addResource(ResourceType.CLIENT_RESOURCES, new Identifier("models/item/trapped_chest.json"), - ResourceUtil.createChestItemModelResource("trapped_chest_center").getBytes()); - p.addModel(JModel.model("block/ender_chest_center"), new Identifier("item/ender_chest")); + ResourceUtil.addChestItemModel(new Identifier("models/item/chest.json"), "chest_center", p); + ResourceUtil.addChestItemModel(new Identifier("models/item/trapped_chest.json"), "trapped_chest_center", p); + ResourceUtil.addParentModel("block/ender_chest_center", new Identifier("item/ender_chest"), p); p.addDirBlockSprites("entity/chest", "entity/chest/"); } @@ -139,7 +135,7 @@ public static void setupRRPShulkerBoxes() { var id = color != null ? color.getName()+"_shulker_box" : "shulker_box"; ResourceUtil.addShulkerBoxBlockStates(color, pCompat); ResourceUtil.addShulkerBoxModels(color, p); - p.addModel(JModel.model("block/"+id), new Identifier("item/"+id)); + ResourceUtil.addParentModel("block/"+id, new Identifier("item/"+id), p); } p.addDirBlockSprites("entity/shulker", "entity/shulker/"); diff --git a/src/main/java/foundationgames/enhancedblockentities/EnhancedBlockEntities.java b/src/main/java/foundationgames/enhancedblockentities/EnhancedBlockEntities.java index 4657e868..c3f67eca 100644 --- a/src/main/java/foundationgames/enhancedblockentities/EnhancedBlockEntities.java +++ b/src/main/java/foundationgames/enhancedblockentities/EnhancedBlockEntities.java @@ -2,6 +2,7 @@ import foundationgames.enhancedblockentities.client.model.ModelIdentifiers; import foundationgames.enhancedblockentities.client.render.SignRenderManager; +import foundationgames.enhancedblockentities.client.resource.template.TemplateLoader; import foundationgames.enhancedblockentities.config.EBEConfig; import foundationgames.enhancedblockentities.util.DateUtil; import foundationgames.enhancedblockentities.util.EBEUtil; @@ -10,6 +11,7 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.item.ModelPredicateProviderRegistry; import org.apache.logging.log4j.LogManager; @@ -21,8 +23,18 @@ public final class EnhancedBlockEntities implements ClientModInitializer { public static final Logger LOG = LogManager.getLogger("Enhanced Block Entities"); public static final EBEConfig CONFIG = new EBEConfig(); + public static final TemplateLoader TEMPLATE_LOADER = new TemplateLoader(); + @Override public void onInitializeClient() { + FabricLoader.getInstance().getModContainer(ID).ifPresent(mod -> { + var roots = mod.getRootPaths(); + + if (roots.size() > 0) { + TEMPLATE_LOADER.setRoot(roots.get(0).resolve("templates")); + } + }); + WorldRenderEvents.END.register(SignRenderManager::endFrame); ClientTickEvents.END_WORLD_TICK.register(WorldUtil.EVENT_LISTENER); diff --git a/src/main/java/foundationgames/enhancedblockentities/client/model/misc/DecoratedPotModelSelector.java b/src/main/java/foundationgames/enhancedblockentities/client/model/misc/DecoratedPotModelSelector.java index 03d9e634..6aee38d2 100644 --- a/src/main/java/foundationgames/enhancedblockentities/client/model/misc/DecoratedPotModelSelector.java +++ b/src/main/java/foundationgames/enhancedblockentities/client/model/misc/DecoratedPotModelSelector.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.function.Supplier; public class DecoratedPotModelSelector extends ModelSelector { @@ -81,7 +82,7 @@ public void writeModelIndices(BlockRenderView view, BlockState state, BlockPos p } } - private int getPatternIndex(Item sherd, int max) { - return MathHelper.clamp(this.potteryPatterns.indexOf(DecoratedPotPatterns.fromSherd(sherd)), 0, max - 1); + private int getPatternIndex(Optional sherd, int max) { + return MathHelper.clamp(this.potteryPatterns.indexOf(sherd.map(DecoratedPotPatterns::fromSherd).orElse(DecoratedPotPatterns.DECORATED_POT_SIDE_KEY)), 0, max - 1); } } diff --git a/src/main/java/foundationgames/enhancedblockentities/client/render/entity/DecoratedPotBlockEntityRendererOverride.java b/src/main/java/foundationgames/enhancedblockentities/client/render/entity/DecoratedPotBlockEntityRendererOverride.java index f75c8938..42c75624 100644 --- a/src/main/java/foundationgames/enhancedblockentities/client/render/entity/DecoratedPotBlockEntityRendererOverride.java +++ b/src/main/java/foundationgames/enhancedblockentities/client/render/entity/DecoratedPotBlockEntityRendererOverride.java @@ -87,13 +87,21 @@ public void render(BlockEntityRenderer renderer, BlockEntity blockE EBEUtil.renderBakedModel(vertexConsumers, blockEntity.getCachedState(), matrices, this.baseModel, light, overlay); EBEUtil.renderBakedModel(vertexConsumers, blockEntity.getCachedState(), matrices, - this.potPatternModels.get(DecoratedPotPatterns.fromSherd(sherds.back()))[0], light, overlay); + this.potPatternModels.get( + sherds.back().map(DecoratedPotPatterns::fromSherd).orElse(DecoratedPotPatterns.DECORATED_POT_SIDE_KEY) + )[0], light, overlay); EBEUtil.renderBakedModel(vertexConsumers, blockEntity.getCachedState(), matrices, - this.potPatternModels.get(DecoratedPotPatterns.fromSherd(sherds.left()))[1], light, overlay); + this.potPatternModels.get( + sherds.left().map(DecoratedPotPatterns::fromSherd).orElse(DecoratedPotPatterns.DECORATED_POT_SIDE_KEY) + )[1], light, overlay); EBEUtil.renderBakedModel(vertexConsumers, blockEntity.getCachedState(), matrices, - this.potPatternModels.get(DecoratedPotPatterns.fromSherd(sherds.right()))[2], light, overlay); + this.potPatternModels.get( + sherds.right().map(DecoratedPotPatterns::fromSherd).orElse(DecoratedPotPatterns.DECORATED_POT_SIDE_KEY) + )[2], light, overlay); EBEUtil.renderBakedModel(vertexConsumers, blockEntity.getCachedState(), matrices, - this.potPatternModels.get(DecoratedPotPatterns.fromSherd(sherds.front()))[3], light, overlay); + this.potPatternModels.get( + sherds.front().map(DecoratedPotPatterns::fromSherd).orElse(DecoratedPotPatterns.DECORATED_POT_SIDE_KEY) + )[3], light, overlay); matrices.pop(); } diff --git a/src/main/java/foundationgames/enhancedblockentities/client/resource/AtlasResourceBuilder.java b/src/main/java/foundationgames/enhancedblockentities/client/resource/AtlasResourceBuilder.java index 6500623a..1d4cc185 100644 --- a/src/main/java/foundationgames/enhancedblockentities/client/resource/AtlasResourceBuilder.java +++ b/src/main/java/foundationgames/enhancedblockentities/client/resource/AtlasResourceBuilder.java @@ -3,7 +3,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.mojang.serialization.JsonOps; -import foundationgames.enhancedblockentities.EnhancedBlockEntities; import net.minecraft.client.texture.atlas.AtlasSource; import net.minecraft.client.texture.atlas.AtlasSourceManager; @@ -21,7 +20,7 @@ public void put(AtlasSource source) { public byte[] toBytes() { return GSON.toJson(AtlasSourceManager.LIST_CODEC.encode(this.sources, JsonOps.INSTANCE, new JsonObject()) - .getOrThrow(false, EnhancedBlockEntities.LOG::error)) + .getOrThrow()) .getBytes(StandardCharsets.UTF_8); } } diff --git a/src/main/java/foundationgames/enhancedblockentities/client/resource/EBEPack.java b/src/main/java/foundationgames/enhancedblockentities/client/resource/EBEPack.java index b9f723ad..87e33edd 100644 --- a/src/main/java/foundationgames/enhancedblockentities/client/resource/EBEPack.java +++ b/src/main/java/foundationgames/enhancedblockentities/client/resource/EBEPack.java @@ -1,56 +1,62 @@ package foundationgames.enhancedblockentities.client.resource; -import net.devtech.arrp.api.RuntimeResourcePack; -import net.devtech.arrp.json.animation.JAnimation; -import net.devtech.arrp.json.blockstate.JState; -import net.devtech.arrp.json.lang.JLang; -import net.devtech.arrp.json.loot.JLootTable; -import net.devtech.arrp.json.models.JModel; -import net.devtech.arrp.json.recipe.JRecipe; -import net.devtech.arrp.json.tags.JTag; -import net.devtech.arrp.util.CallableFunction; +import com.google.gson.JsonObject; +import foundationgames.enhancedblockentities.client.resource.template.TemplateLoader; +import foundationgames.enhancedblockentities.client.resource.template.TemplateProvider; +import net.minecraft.SharedConstants; import net.minecraft.client.texture.atlas.AtlasSource; import net.minecraft.client.texture.atlas.DirectoryAtlasSource; import net.minecraft.client.texture.atlas.SingleAtlasSource; import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ResourcePackInfo; +import net.minecraft.resource.ResourcePackSource; import net.minecraft.resource.ResourceType; import net.minecraft.resource.metadata.ResourceMetadataReader; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; -import java.awt.image.BufferedImage; -import java.io.File; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Optional; +import java.util.Properties; import java.util.Set; -import java.util.concurrent.Future; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.IntUnaryOperator; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -public class EBEPack implements RuntimeResourcePack { + +public class EBEPack implements ResourcePack { public static final Identifier BLOCK_ATLAS = new Identifier("blocks"); - private final RuntimeResourcePack resourcePack; private final Map atlases = new HashMap<>(); + private final Map> resources = new HashMap<>(); + private final Set namespaces = new HashSet<>(); + + private final TemplateLoader templates; + + private final JsonObject packMeta; + private final ResourcePackInfo packInfo; + + public EBEPack(Identifier id, TemplateLoader templates) { + this.templates = templates; - public EBEPack(Identifier id) { - this.resourcePack = RuntimeResourcePack.create(id); + this.packMeta = new JsonObject(); + this.packMeta.addProperty("pack_format", SharedConstants.getGameVersion().getResourceVersion(ResourceType.CLIENT_RESOURCES)); + this.packMeta.addProperty("description", "Enhanced Block Entities Resources"); + + this.packInfo = new ResourcePackInfo(id.toString(), Text.literal(id.toString()), ResourcePackSource.BUILTIN, Optional.empty()); } public void addAtlasSprite(Identifier atlas, AtlasSource source) { var resource = this.atlases.computeIfAbsent(atlas, id -> new AtlasResourceBuilder()); resource.put(source); - this.addLazyResource(ResourceType.CLIENT_RESOURCES, - new Identifier(atlas.getNamespace(), "atlases/" + atlas.getPath() + ".json"), - (pack, id) -> resource.toBytes()); + this.addResource(new Identifier(atlas.getNamespace(), "atlases/" + atlas.getPath() + ".json"), resource::toBytes); } public void addSingleBlockSprite(Identifier path) { @@ -61,166 +67,137 @@ public void addDirBlockSprites(String dir, String prefix) { this.addAtlasSprite(BLOCK_ATLAS, new DirectoryAtlasSource(dir, prefix)); } - @Override - public void addRecoloredImage(Identifier identifier, InputStream target, IntUnaryOperator pixel) { - this.resourcePack.addRecoloredImage(identifier, target, pixel); + public void addResource(Identifier id, InputSupplier resource) { + this.namespaces.add(id.getNamespace()); + this.resources.put(id, new LazyBufferedResource(resource)); } - @Override - public byte[] addLang(Identifier identifier, JLang lang) { - return this.resourcePack.addLang(identifier, lang); + public void addResource(Identifier id, byte[] resource) { + this.namespaces.add(id.getNamespace()); + this.resources.put(id, () -> new ByteArrayInputStream(resource)); } - @Override - public void mergeLang(Identifier identifier, JLang lang) { - this.resourcePack.mergeLang(identifier, lang); + public void addPlainTextResource(Identifier id, String plainText) { + this.addResource(id, plainText.getBytes(StandardCharsets.UTF_8)); } - @Override - public byte[] addLootTable(Identifier identifier, JLootTable table) { - return this.resourcePack.addLootTable(identifier, table); + public void addTemplateResource(Identifier id, TemplateProvider.TemplateApplyingFunction template) { + this.addResource(id, () -> template.getAndApplyTemplate(new TemplateProvider(this.templates)).getBytes(StandardCharsets.UTF_8)); } - @Override - public Future addAsyncResource(ResourceType type, Identifier identifier, CallableFunction data) { - return this.resourcePack.addAsyncResource(type, identifier, data); + public void addTemplateResource(Identifier id, String templatePath) { + this.addTemplateResource(id, t -> t.load(templatePath, d -> {})); } + @Nullable @Override - public void addLazyResource(ResourceType type, Identifier path, BiFunction data) { - this.resourcePack.addLazyResource(type, path, data); + public InputSupplier openRoot(String... segments) { + return null; // Provide no root resources } + @Nullable @Override - public byte[] addResource(ResourceType type, Identifier path, byte[] data) { - return this.resourcePack.addResource(type, path, data); - } + public InputSupplier open(ResourceType type, Identifier id) { + if (type != ResourceType.CLIENT_RESOURCES) return null; - @Override - public Future addAsyncRootResource(String path, CallableFunction data) { - return this.resourcePack.addAsyncRootResource(path, data); + return this.resources.get(id); } @Override - public void addLazyRootResource(String path, BiFunction data) { - this.resourcePack.addLazyRootResource(path, data); - } + public void findResources(ResourceType type, String namespace, String prefix, ResultConsumer consumer) { + if (type != ResourceType.CLIENT_RESOURCES) return; - @Override - public byte[] addRootResource(String path, byte[] data) { - return this.resourcePack.addRootResource(path, data); - } + for (var entry : this.resources.entrySet()) { + var id = entry.getKey(); - @Override - public byte[] addAsset(Identifier path, byte[] data) { - return this.resourcePack.addAsset(path, data); + if (id.getNamespace().startsWith(namespace) && id.getPath().startsWith(prefix)) { + consumer.accept(id, entry.getValue()); + } + } } @Override - public byte[] addData(Identifier path, byte[] data) { - return this.resourcePack.addData(path, data); - } + public Set getNamespaces(ResourceType type) { + if (type != ResourceType.CLIENT_RESOURCES) return Set.of(); - @Override - public byte[] addModel(JModel model, Identifier path) { - return this.resourcePack.addModel(model, path); + return this.namespaces; } + @Nullable @Override - public byte[] addBlockState(JState state, Identifier path) { - return this.resourcePack.addBlockState(state, path); - } + public T parseMetadata(ResourceMetadataReader meta) throws IOException { + if ("pack".equals(meta.getKey())) { + return meta.fromJson(this.packMeta); + } - @Override - public byte[] addTexture(Identifier id, BufferedImage image) { - return this.resourcePack.addTexture(id, image); + return null; } @Override - public byte[] addAnimation(Identifier id, JAnimation animation) { - return this.resourcePack.addAnimation(id, animation); + public ResourcePackInfo getInfo() { + return this.packInfo; } @Override - public byte[] addTag(Identifier id, JTag tag) { - return this.resourcePack.addTag(id, tag); + public void close() { } - @Override - public byte[] addRecipe(Identifier id, JRecipe recipe) { - return this.resourcePack.addRecipe(id, recipe); - } + public void dump(Path dir) throws IOException { + dir = dir.resolve("assets"); - @Override - public Future async(Consumer action) { - return this.resourcePack.async(action); - } + for (var entry : this.resources.entrySet()) { + var id = entry.getKey(); + var file = dir.resolve(id.getNamespace()).resolve(id.getPath()); - @Override - public void dumpDirect(Path path) { - this.resourcePack.dumpDirect(path); - } + Files.createDirectories(file.getParent()); - @Override - public void load(Path path) throws IOException { - this.resourcePack.load(path); - } + try (var out = Files.newOutputStream(file)) { + var in = entry.getValue().get(); - @Override - public void dump(File file) { - this.resourcePack.dump(file); + int i; + while ((i = in.read()) >= 0) { + out.write(i); + } + } + } } - @Override - public void dump(ZipOutputStream stream) throws IOException { - this.resourcePack.dump(stream); - } + public static class PropertyBuilder { + private Properties properties = new Properties(); - @Override - public void load(ZipInputStream stream) throws IOException { - this.resourcePack.load(stream); - } + private PropertyBuilder() {} - @Override - public Identifier getId() { - return this.resourcePack.getId(); - } + public PropertyBuilder def(String k, String v) { + if (this.properties != null) { + this.properties.setProperty(k, v); + } - @Nullable - @Override - public InputSupplier openRoot(String... segments) { - return this.resourcePack.openRoot(segments); - } + return this; + } - @Nullable - @Override - public InputSupplier open(ResourceType type, Identifier id) { - return this.resourcePack.open(type, id); - } + private Properties build() { + var properties = this.properties; + this.properties = null; - @Override - public void findResources(ResourceType type, String namespace, String prefix, ResultConsumer consumer) { - this.resourcePack.findResources(type, namespace, prefix, consumer); + return properties; + } } - @Override - public Set getNamespaces(ResourceType type) { - return this.resourcePack.getNamespaces(type); - } + public static class LazyBufferedResource implements InputSupplier { + private final InputSupplier backing; + private byte[] buffer = null; - @Nullable - @Override - public T parseMetadata(ResourceMetadataReader metaReader) throws IOException { - return this.resourcePack.parseMetadata(metaReader); - } + public LazyBufferedResource(InputSupplier backing) { + this.backing = backing; + } - @Override - public String getName() { - return this.resourcePack.getName(); - } + @Override + public InputStream get() throws IOException { + if (buffer == null) { + buffer = backing.get(); + } - @Override - public void close() { - this.resourcePack.close(); + return new ByteArrayInputStream(buffer); + } } } diff --git a/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateDefinitions.java b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateDefinitions.java new file mode 100644 index 00000000..1af64867 --- /dev/null +++ b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateDefinitions.java @@ -0,0 +1,45 @@ +package foundationgames.enhancedblockentities.client.resource.template; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public interface TemplateDefinitions { + default TemplateDefinitions def(String k, Object v) { + return this.def(k, templates -> String.valueOf(v)); + } + + TemplateDefinitions def(String k, TemplateProvider.TemplateApplyingFunction v); + + class Impl implements TemplateDefinitions, Iterable> { + private final Deque> stack = new ArrayDeque<>(); + + public void push() { + this.stack.addLast(new HashMap<>()); + } + + public void pop() { + this.stack.removeLast(); + } + + public TemplateDefinitions def(String k, String v) { + return this.def(k, templates -> v); + } + + public TemplateDefinitions def(String k, TemplateProvider.TemplateApplyingFunction v) { + this.stack.getLast().put(k, v); + + return this; + } + + @NotNull + @Override + public Iterator> iterator() { + return this.stack.getLast().entrySet().iterator(); + } + } +} diff --git a/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateLoader.java b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateLoader.java new file mode 100644 index 00000000..b3fc5e23 --- /dev/null +++ b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateLoader.java @@ -0,0 +1,39 @@ +package foundationgames.enhancedblockentities.client.resource.template; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +public class TemplateLoader { + private Path rootPath; + + private final Map loadedTemplates = new HashMap<>(); + + public TemplateLoader() { + } + + public void setRoot(Path path) { + this.rootPath = path; + } + + public String getOrLoadRaw(String path) throws IOException { + if (this.rootPath == null) { + return ""; + } + + if (this.loadedTemplates.containsKey(path)) { + return this.loadedTemplates.get(path); + } + + var file = rootPath.resolve(path); + try (var in = Files.newInputStream(file)) { + var templateRaw = new String(in.readAllBytes(), StandardCharsets.UTF_8); + this.loadedTemplates.put(path, templateRaw); + + return templateRaw; + } + } +} diff --git a/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateProvider.java b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateProvider.java new file mode 100644 index 00000000..0545af29 --- /dev/null +++ b/src/main/java/foundationgames/enhancedblockentities/client/resource/template/TemplateProvider.java @@ -0,0 +1,51 @@ +package foundationgames.enhancedblockentities.client.resource.template; + +import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.function.Consumer; +import java.util.regex.Pattern; + +public class TemplateProvider { + private final TemplateLoader loader; + private final TemplateDefinitions.Impl definitions = new TemplateDefinitions.Impl(); + private final Deque loaded = new ArrayDeque<>(); + + public TemplateProvider(TemplateLoader loader) { + this.loader = loader; + } + + public String load(String templatePath, Consumer definitions) throws IOException { + this.definitions.push(); + definitions.accept(this.definitions); + + try { + var substitutions = new HashMap(); + for (var entry : this.definitions) { + substitutions.put(entry.getKey(), entry.getValue().getAndApplyTemplate(this)); + } + + var templateRaw = this.loader.getOrLoadRaw(templatePath); + var matcher = Pattern.compile("!\\[(" + String.join("|", substitutions.keySet()) + ")]") + .matcher(templateRaw); + + var result = new StringBuilder(); + while (matcher.find()) { + matcher.appendReplacement(result, substitutions.get(matcher.group(1))); + } + matcher.appendTail(result); + + this.definitions.pop(); + return result.toString(); + } catch (IOException ex) { + this.definitions.pop(); + throw ex; + } + } + + @FunctionalInterface + public interface TemplateApplyingFunction { + String getAndApplyTemplate(TemplateProvider templates) throws IOException; + } +} diff --git a/src/main/java/foundationgames/enhancedblockentities/config/gui/screen/EBEConfigScreen.java b/src/main/java/foundationgames/enhancedblockentities/config/gui/screen/EBEConfigScreen.java index 07ae704e..419863a7 100644 --- a/src/main/java/foundationgames/enhancedblockentities/config/gui/screen/EBEConfigScreen.java +++ b/src/main/java/foundationgames/enhancedblockentities/config/gui/screen/EBEConfigScreen.java @@ -1,7 +1,6 @@ package foundationgames.enhancedblockentities.config.gui.screen; import com.google.common.collect.ImmutableList; -import com.mojang.blaze3d.systems.RenderSystem; import foundationgames.enhancedblockentities.EnhancedBlockEntities; import foundationgames.enhancedblockentities.ReloadType; import foundationgames.enhancedblockentities.config.EBEConfig; @@ -12,13 +11,10 @@ import foundationgames.enhancedblockentities.util.EBEUtil; import foundationgames.enhancedblockentities.util.GuiUtil; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.GridWidget; -import net.minecraft.client.render.GameRenderer; import net.minecraft.client.resource.language.I18n; import net.minecraft.screen.ScreenTexts; import net.minecraft.text.Text; @@ -39,7 +35,7 @@ public class EBEConfigScreen extends Screen { private static final ImmutableList ALLOWED_FORCED_DISABLED = ImmutableList.of("allowed", "forced", "disabled"); private static final ImmutableList SIGN_TEXT_OPTIONS = ImmutableList.of("smart", "all", "most", "some", "few"); - private static final Text HOLD_SHIFT = Text.translatable("text.ebe.descriptions").formatted(Formatting.DARK_GRAY, Formatting.ITALIC); + private static final Text HOLD_SHIFT = Text.translatable("text.ebe.descriptions").formatted(Formatting.GRAY, Formatting.ITALIC); private static final Text CHEST_OPTIONS_TITLE = Text.translatable("text.ebe.chest_options"); private static final Text SIGN_OPTIONS_TITLE = Text.translatable("text.ebe.sign_options"); private static final Text BELL_OPTIONS_TITLE = Text.translatable("text.ebe.bell_options"); @@ -51,7 +47,6 @@ public class EBEConfigScreen extends Screen { private static final Text DUMP_LABEL = Text.translatable("option.ebe.dump"); private final Text dumpTooltip = GuiUtil.shorten(I18n.translate("option.ebe.dump.comment"), 20); - private final RotatingCubeMapRenderer background = new RotatingCubeMapRenderer(TitleScreen.PANORAMA_CUBE_MAP); public EBEConfigScreen(Screen screen) { super(Text.translatable("screen.ebe.config")); @@ -63,8 +58,8 @@ protected void init() { super.init(); this.optionsWidget = new WidgetRowListWidget(this.client, this.width, this.height - 69, 34, 316, 20); + //this.optionsWidget.bac this.options.clear(); - this.optionsWidget.setRenderBackground(false); addOptions(); this.addDrawableChild(optionsWidget); @@ -94,30 +89,13 @@ protected void init() { } @Override - public void renderBackgroundTexture(DrawContext context) { - } - - @Override - public void renderInGameBackground(DrawContext context) { - } - - private void drawDirtTexture(DrawContext context, int x, int y, int w, int h) { - context.setShaderColor(0.25F, 0.25F, 0.25F, 1.0F); - context.drawTexture(OPTIONS_BACKGROUND_TEXTURE, x, y, 0, 0.0F, 0.0F, w, h, 32, 32); - context.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + protected void renderDarkening(DrawContext context) { + renderDarkening(context, 0, 0, this.width, 34); + renderDarkening(context, 0, this.height - 35, this.width, 35); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (this.client.world == null) { - this.background.render(delta, 1); - RenderSystem.setShader(GameRenderer::getPositionTexProgram); - } - - context.fillGradient(0, 0, width, height, 0x4F141414, 0x4F141414); - drawDirtTexture(context, 0, 0, this.width, 34); - drawDirtTexture(context, 0, this.height - 35, this.width, 35); - super.render(context, mouseX, mouseY, delta); context.drawCenteredTextWithShadow(this.textRenderer, this.title, (int)(this.width * 0.5), 8, 0xFFFFFF); diff --git a/src/main/java/foundationgames/enhancedblockentities/config/gui/widget/WidgetRowListWidget.java b/src/main/java/foundationgames/enhancedblockentities/config/gui/widget/WidgetRowListWidget.java index 6edb75f1..a92d3757 100644 --- a/src/main/java/foundationgames/enhancedblockentities/config/gui/widget/WidgetRowListWidget.java +++ b/src/main/java/foundationgames/enhancedblockentities/config/gui/widget/WidgetRowListWidget.java @@ -7,7 +7,6 @@ import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.gui.widget.ElementListWidget; import net.minecraft.client.gui.widget.GridWidget; -import net.minecraft.client.render.RenderLayer; import java.util.ArrayList; import java.util.List; @@ -49,16 +48,12 @@ public int getRowWidth() { } @Override - protected int getScrollbarPositionX() { + protected int getScrollbarX() { return this.width - 6; } @Override - public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - super.renderWidget(context, mouseX, mouseY, delta); - - context.fillGradient(RenderLayer.getGuiOverlay(), this.getX(), this.getY(), this.getRight(), this.getY() + 4, -16777216, 0, 0); - context.fillGradient(RenderLayer.getGuiOverlay(), this.getX(), this.getBottom() - 4, this.getRight(), this.getBottom(), 0, -16777216, 0); + protected void drawMenuListBackground(DrawContext context) { } public static class Entry extends ElementListWidget.Entry { diff --git a/src/main/java/foundationgames/enhancedblockentities/mixin/DecoratedPotBlockEntityMixin.java b/src/main/java/foundationgames/enhancedblockentities/mixin/DecoratedPotBlockEntityMixin.java index 9c3d4584..aecc91d9 100644 --- a/src/main/java/foundationgames/enhancedblockentities/mixin/DecoratedPotBlockEntityMixin.java +++ b/src/main/java/foundationgames/enhancedblockentities/mixin/DecoratedPotBlockEntityMixin.java @@ -4,6 +4,7 @@ import foundationgames.enhancedblockentities.util.duck.AppearanceStateHolder; import net.minecraft.block.entity.DecoratedPotBlockEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -17,7 +18,7 @@ public class DecoratedPotBlockEntityMixin implements AppearanceStateHolder { @Unique private int enhanced_bes$renderState = 0; @Inject(method = "readNbt", at = @At("TAIL")) - private void enhanced_bes$updateChunkOnPatternsLoaded(NbtCompound nbt, CallbackInfo ci) { + private void enhanced_bes$updateChunkOnPatternsLoaded(NbtCompound nbt, RegistryWrapper.WrapperLookup rwl, CallbackInfo ci) { var self = (DecoratedPotBlockEntity)(Object)this; if (self.getWorld() != null && self.getWorld().isClient()) { diff --git a/src/main/java/foundationgames/enhancedblockentities/util/EBEUtil.java b/src/main/java/foundationgames/enhancedblockentities/util/EBEUtil.java index 0d161f83..38c27531 100644 --- a/src/main/java/foundationgames/enhancedblockentities/util/EBEUtil.java +++ b/src/main/java/foundationgames/enhancedblockentities/util/EBEUtil.java @@ -40,7 +40,7 @@ public static void renderBakedModel(VertexConsumerProvider vertexConsumers, Bloc VertexConsumer vertices = vertexConsumers.getBuffer(RenderLayers.getEntityBlockLayer(state, false)); for (int i = 0; i <= 6; i++) { for (BakedQuad q : model.getQuads(null, ModelHelper.faceFromIndex(i), dummy)) { - vertices.quad(matrices.peek(), q, 1, 1, 1, light, overlay); + vertices.quad(matrices.peek(), q, 1, 1, 1, 1, light, overlay); } } } diff --git a/src/main/java/foundationgames/enhancedblockentities/util/ResourceUtil.java b/src/main/java/foundationgames/enhancedblockentities/util/ResourceUtil.java index 8f35bd45..a42991e1 100644 --- a/src/main/java/foundationgames/enhancedblockentities/util/ResourceUtil.java +++ b/src/main/java/foundationgames/enhancedblockentities/util/ResourceUtil.java @@ -2,10 +2,7 @@ import foundationgames.enhancedblockentities.EnhancedBlockEntities; import foundationgames.enhancedblockentities.client.resource.EBEPack; -import net.devtech.arrp.json.blockstate.JState; -import net.devtech.arrp.json.blockstate.JVariant; -import net.devtech.arrp.json.models.JModel; -import net.devtech.arrp.json.models.JTextures; +import foundationgames.enhancedblockentities.client.resource.template.TemplateProvider; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.minecraft.block.DecoratedPotPatterns; @@ -28,111 +25,174 @@ public enum ResourceUtil {; private static EBEPack BASE_PACK; private static EBEPack TOP_LEVEL_PACK; - public static String createChestItemModelResource(String centerChest) { - return "{\"parent\":\"block/"+centerChest+"\",\"overrides\":[{\"predicate\":{\"ebe:is_christmas\":1},\"model\": \"item/christmas_chest\"}]}"; + public static void addChestItemModel(Identifier id, String centerChest, EBEPack pack) { + pack.addTemplateResource(id, t -> t.load("chest_item_model.json", d -> d.def("chest", centerChest))); } - private static JVariant variantRotation16(JVariant variant, String keyPrefix, String modelPrefix) { - return variant - .put(keyPrefix+"0", JState.model(modelPrefix+"_0").y(180)) - .put(keyPrefix+"1", JState.model(modelPrefix+"_67_5").y(270)) - .put(keyPrefix+"2", JState.model(modelPrefix+"_45").y(270)) - .put(keyPrefix+"3", JState.model(modelPrefix+"_22_5").y(270)) - .put(keyPrefix+"4", JState.model(modelPrefix+"_0").y(270)) - .put(keyPrefix+"5", JState.model(modelPrefix+"_67_5")) - .put(keyPrefix+"6", JState.model(modelPrefix+"_45")) - .put(keyPrefix+"7", JState.model(modelPrefix+"_22_5")) - .put(keyPrefix+"8", JState.model(modelPrefix+"_0")) - .put(keyPrefix+"9", JState.model(modelPrefix+"_67_5").y(90)) - .put(keyPrefix+"10", JState.model(modelPrefix+"_45").y(90)) - .put(keyPrefix+"11", JState.model(modelPrefix+"_22_5").y(90)) - .put(keyPrefix+"12", JState.model(modelPrefix+"_0").y(90)) - .put(keyPrefix+"13", JState.model(modelPrefix+"_67_5").y(180)) - .put(keyPrefix+"14", JState.model(modelPrefix+"_45").y(180)) - .put(keyPrefix+"15", JState.model(modelPrefix+"_22_5").y(180)); + private static String list(String ... els) { + return String.join(",", els); } - private static JVariant variantHFacing(JVariant variant, String keyPrefix, String model) { - return variant - .put(keyPrefix+"north", JState.model(model)) - .put(keyPrefix+"west", JState.model(model).y(270)) - .put(keyPrefix+"south", JState.model(model).y(180)) - .put(keyPrefix+"east", JState.model(model).y(90)); + private static String kv(String k, String v) { + return String.format("\""+k+"\":\""+v+"\""); } - public static void addSingleChestModels(String texture, String chestName, EBEPack pack) { - pack.addModel(JModel.model().parent("block/template_chest_center").textures(withChestParticle(JModel.textures().var("chest", texture), chestName)), new Identifier("block/" + chestName + "_center")); - pack.addModel(JModel.model().parent("block/template_chest_center_lid").textures(withChestParticle(JModel.textures().var("chest", texture), chestName)), new Identifier("block/" + chestName + "_center_lid")); - pack.addModel(JModel.model().parent("block/template_chest_center_trunk").textures(withChestParticle(JModel.textures().var("chest", texture), chestName)), new Identifier("block/" + chestName + "_center_trunk")); + private static String kv(String k, int v) { + return String.format("\""+k+"\":"+v+""); + } + + private static String variant(TemplateProvider t, String state, String model) throws IOException { + return t.load("blockstate/var.json", d -> d + .def("state", state) + .def("model", model) + .def("extra", "")); + } + + private static String variantY(TemplateProvider t, String state, String model, int y) throws IOException { + return t.load("blockstate/var.json", d -> d + .def("state", state) + .def("model", model) + .def("extra", kv("y", y) + ",")); + } + + private static String variantXY(TemplateProvider t, String state, String model, int x, int y) throws IOException { + return t.load("blockstate/var.json", d -> d + .def("state", state) + .def("model", model) + .def("extra", list( + kv("x", x), + kv("y", y) + ) + ",")); + } + + private static String variantRotation16(TemplateProvider t, String keyPrefix, String modelPrefix) throws IOException { + return list( + variantY(t, keyPrefix+"0", modelPrefix+"_0", 180), + variantY(t, keyPrefix+"1", modelPrefix+"_67_5", 270), + variantY(t, keyPrefix+"2", modelPrefix+"_45", 270), + variantY(t, keyPrefix+"3", modelPrefix+"_22_5", 270), + variantY(t, keyPrefix+"4", modelPrefix+"_0", 270), + variant(t, keyPrefix+"5", modelPrefix+"_67_5"), + variant(t, keyPrefix+"6", modelPrefix+"_45"), + variant(t, keyPrefix+"7", modelPrefix+"_22_5"), + variant(t, keyPrefix+"8", modelPrefix+"_0"), + variantY(t, keyPrefix+"9", modelPrefix+"_67_5", 90), + variantY(t, keyPrefix+"10", modelPrefix+"_45", 90), + variantY(t, keyPrefix+"11", modelPrefix+"_22_5", 90), + variantY(t, keyPrefix+"12", modelPrefix+"_0", 90), + variantY(t, keyPrefix+"13", modelPrefix+"_67_5", 180), + variantY(t, keyPrefix+"14", modelPrefix+"_45", 180), + variantY(t, keyPrefix+"15", modelPrefix+"_22_5", 180) + ); + } + + private static String variantHFacing(TemplateProvider t, String keyPrefix, String model) throws IOException { + return list( + variant(t, keyPrefix+"north", model), + variantY(t, keyPrefix+"west", model, 270), + variantY(t, keyPrefix+"south", model, 180), + variantY(t, keyPrefix+"east", model, 90) + ); + } + + private static void addChestLikeModel(String parent, String chestTex, String chestName, Identifier id, EBEPack pack) { + pack.addTemplateResource(new Identifier(id.getNamespace(), "models/" + id.getPath() + ".json"), + t -> t.load("model/chest_like.json", d -> d + .def("parent", parent) + .def("chest_tex", chestTex) + .def("particle", chestParticle(chestName)) + ) + ); + } + + public static void addSingleChestModels(String chestTex, String chestName, EBEPack pack) { + addChestLikeModel("template_chest_center", chestTex, chestName, new Identifier("block/" + chestName + "_center"), pack); + addChestLikeModel("template_chest_center_lid", chestTex, chestName, new Identifier("block/" + chestName + "_center_lid"), pack); + addChestLikeModel("template_chest_center_trunk", chestTex, chestName, new Identifier("block/" + chestName + "_center_trunk"), pack); } public static void addDoubleChestModels(String leftTex, String rightTex, String chestName, EBEPack pack) { - pack.addModel(JModel.model().parent("block/template_chest_left").textures(withChestParticle(JModel.textures().var("chest", leftTex), chestName)), new Identifier("block/" + chestName + "_left")); - pack.addModel(JModel.model().parent("block/template_chest_left_lid").textures(withChestParticle(JModel.textures().var("chest", leftTex), chestName)), new Identifier("block/" + chestName + "_left_lid")); - pack.addModel(JModel.model().parent("block/template_chest_left_trunk").textures(withChestParticle(JModel.textures().var("chest", leftTex), chestName)), new Identifier("block/" + chestName + "_left_trunk")); - pack.addModel(JModel.model().parent("block/template_chest_right").textures(withChestParticle(JModel.textures().var("chest", rightTex), chestName)), new Identifier("block/" + chestName + "_right")); - pack.addModel(JModel.model().parent("block/template_chest_right_lid").textures(withChestParticle(JModel.textures().var("chest", rightTex), chestName)), new Identifier("block/" + chestName + "_right_lid")); - pack.addModel(JModel.model().parent("block/template_chest_right_trunk").textures(withChestParticle(JModel.textures().var("chest", rightTex), chestName)), new Identifier("block/" + chestName + "_right_trunk")); + addChestLikeModel("template_chest_left", leftTex, chestName, new Identifier("block/" + chestName + "_left"), pack); + addChestLikeModel("template_chest_left_lid", leftTex, chestName, new Identifier("block/" + chestName + "_left_lid"), pack); + addChestLikeModel("template_chest_left_trunk", leftTex, chestName, new Identifier("block/" + chestName + "_left_trunk"), pack); + addChestLikeModel("template_chest_right", rightTex, chestName, new Identifier("block/" + chestName + "_right"), pack); + addChestLikeModel("template_chest_right_lid", rightTex, chestName, new Identifier("block/" + chestName + "_right_lid"), pack); + addChestLikeModel("template_chest_right_trunk", rightTex, chestName, new Identifier("block/" + chestName + "_right_trunk"), pack); } - private static JTextures withChestParticle(JTextures textures, String chestName) { - if (EnhancedBlockEntities.CONFIG.experimentalChests) textures.var("particle", "block/"+chestName+"_particle"); - return textures; + private static String chestParticle(String chestName) { + if (EnhancedBlockEntities.CONFIG.experimentalChests) return kv("particle", "block/"+chestName+"_particle") + ","; + return ""; } - private static JTextures withBedParticle(JTextures textures, String bedColor) { - if (EnhancedBlockEntities.CONFIG.experimentalBeds) textures.var("particle", "block/"+bedColor+"_bed_particle"); - return textures; + private static String bedParticle(String bedColor) { + if (EnhancedBlockEntities.CONFIG.experimentalBeds) return kv("particle", "block/"+bedColor+"_bed_particle") + ","; + return ""; } - private static JTextures withSignParticle(JTextures textures, String signName) { - if (EnhancedBlockEntities.CONFIG.experimentalSigns) textures.var("particle", "block/"+signName+"_particle"); - return textures; + private static String signParticle(String signName) { + if (EnhancedBlockEntities.CONFIG.experimentalSigns) return kv("particle", "block/"+signName+"_particle") + ","; + return ""; } - public static void addChestBlockStates(String chestName, EBEPack pack) { - var variant = JState.variant(); - variantHFacing(variant, "type=single,facing=", "builtin:"+chestName+"_center"); - variantHFacing(variant, "type=left,facing=", "builtin:"+chestName+"_left"); - variantHFacing(variant, "type=right,facing=", "builtin:"+chestName+"_right"); + private static void addBlockState(Identifier id, TemplateProvider.TemplateApplyingFunction vars, EBEPack pack) { + pack.addTemplateResource(new Identifier(id.getNamespace(), "blockstates/" + id.getPath() + ".json"), + t -> t.load("blockstate/base.json", d -> d.def("vars", vars))); + } - pack.addBlockState(JState.state(variant), new Identifier(chestName)); + public static void addChestBlockStates(String chestName, EBEPack pack) { + addBlockState(new Identifier(chestName), + t0 -> list( + variantHFacing(t0, "type=single,facing=", "builtin:"+chestName+"_center"), + variantHFacing(t0, "type=left,facing=", "builtin:"+chestName+"_left"), + variantHFacing(t0, "type=right,facing=", "builtin:"+chestName+"_right") + ), pack); } public static void addSingleChestOnlyBlockStates(String chestName, EBEPack pack) { - pack.addBlockState( - JState.state( - variantHFacing(JState.variant(), "facing=", "builtin:"+chestName+"_center") - ), new Identifier(chestName) - ); + addBlockState(new Identifier(chestName), + t0 -> list( + variantHFacing(t0, "facing=", "builtin:"+chestName+"_center") + ), pack); + } + + public static void addParentModel(String parent, Identifier id, EBEPack pack) { + pack.addTemplateResource(new Identifier(id.getNamespace(), "models/" + id.getPath() + ".json"), t -> + "{" + kv("parent", parent) + "}"); + } + + public static void addParentTexModel(String parent, String textures, Identifier id, EBEPack pack) { + pack.addTemplateResource(new Identifier(id.getNamespace(), "models/" + id.getPath() + ".json"), t -> + t.load("model/parent_and_tex.json", d -> d.def("parent", parent).def("textures", textures))); } public static void addSignTypeModels(String signType, EBEPack pack) { var signName = signType+"_sign"; var signTex = "entity/signs/"+signType; addRotation16Models( - withSignParticle(new JTextures().var("sign", signTex), signName), + signParticle(signName) + kv("sign", signTex), "block/template_sign", "block/"+signName, ResourceUtil::signAOSuffix, pack); - var hangingTexDef = new JTextures() - .var("sign", "entity/signs/hanging/"+signType) - .var("particle", "block/particle_hanging_sign_"+signType); + var hangingTexDef = list( + kv("sign", "entity/signs/hanging/"+signType), + kv("particle", "block/particle_hanging_sign_"+signType) + ); addRotation16Models(hangingTexDef, "block/template_hanging_sign", "block/"+signType+"_hanging_sign", ResourceUtil::signAOSuffix, pack); addRotation16Models(hangingTexDef, "block/template_hanging_sign_attached", "block/"+signType+"_hanging_sign_attached", ResourceUtil::signAOSuffix, pack); - pack.addModel(JModel.model().parent(signAOSuffix("block/template_wall_sign")) - .textures(withSignParticle(JModel.textures().var("sign", signTex), signName)), new Identifier("block/"+signType+"_wall_sign")); - pack.addModel(JModel.model().parent(signAOSuffix("block/template_wall_hanging_sign")) - .textures(hangingTexDef), new Identifier("block/"+signType+"_wall_hanging_sign")); + addParentTexModel(signAOSuffix("block/template_wall_sign"), + signParticle(signName) + kv("sign", signTex), new Identifier("block/"+signType+"_wall_sign"), pack); + addParentTexModel(signAOSuffix("block/template_wall_hanging_sign"), + hangingTexDef, new Identifier("block/"+signType+"_wall_hanging_sign"), pack); } - public static void addRotation16Models(JTextures textures, String templatePrefix, String modelPrefix, Function suffix, EBEPack pack) { - pack.addModel(JModel.model().parent(suffix.apply(templatePrefix+"_0")).textures(textures), new Identifier(modelPrefix + "_0")); - pack.addModel(JModel.model().parent(suffix.apply(templatePrefix+"_22_5")).textures(textures), new Identifier(modelPrefix + "_22_5")); - pack.addModel(JModel.model().parent(suffix.apply(templatePrefix+"_45")).textures(textures), new Identifier(modelPrefix + "_45")); - pack.addModel(JModel.model().parent(suffix.apply(templatePrefix+"_67_5")).textures(textures), new Identifier(modelPrefix + "_67_5")); + public static void addRotation16Models(String textures, String templatePrefix, String modelPrefix, Function suffix, EBEPack pack) { + addParentTexModel(suffix.apply(templatePrefix+"_0"), textures, new Identifier(modelPrefix + "_0"), pack); + addParentTexModel(suffix.apply(templatePrefix+"_22_5"), textures, new Identifier(modelPrefix + "_22_5"), pack); + addParentTexModel(suffix.apply(templatePrefix+"_45"), textures, new Identifier(modelPrefix + "_45"), pack); + addParentTexModel(suffix.apply(templatePrefix+"_67_5"), textures, new Identifier(modelPrefix + "_67_5"), pack); } private static String signAOSuffix(String model) { @@ -141,71 +201,63 @@ private static String signAOSuffix(String model) { } public static void addSignBlockStates(String signName, String wallSignName, EBEPack pack) { - pack.addBlockState( - JState.state( - variantRotation16(JState.variant(), "rotation=", "block/"+signName) - ), new Identifier(signName) - ); - pack.addBlockState( - JState.state( - variantHFacing(JState.variant(), "facing=", "block/"+wallSignName) - ), new Identifier(wallSignName) - ); + addBlockState(new Identifier(signName), + t -> variantRotation16(t, "rotation=", "block/"+signName), pack); + addBlockState(new Identifier(wallSignName), + t -> variantHFacing(t, "facing=", "block/"+wallSignName), pack); } public static void addHangingSignBlockStates(String signName, String wallSignName, EBEPack pack) { - var variant = JState.variant(); - variantRotation16(variant, "attached=false,rotation=", "block/"+signName); - variantRotation16(variant, "attached=true,rotation=", "block/"+signName+"_attached"); - - pack.addBlockState(JState.state(variant), new Identifier(signName)); - pack.addBlockState( - JState.state( - variantHFacing(JState.variant(), "facing=", "block/"+wallSignName) - ), new Identifier(wallSignName) - ); + addBlockState(new Identifier(signName), + t -> list( + variantRotation16(t, "attached=false,rotation=", "block/"+signName), + variantRotation16(t, "attached=true,rotation=", "block/"+signName+"_attached") + ), pack); + + addBlockState(new Identifier(wallSignName), + t -> variantHFacing(t, "facing=", "block/"+wallSignName), pack); } public static void addBellBlockState(EBEPack pack) { - JVariant variant = JState.variant(); - for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { - int rot = (int)dir.asRotation() + 90; - variant - .put("attachment=double_wall,facing="+dir.getName(), JState.model("builtin:bell_between_walls").y(rot)) - .put("attachment=ceiling,facing="+dir.getName(), JState.model("builtin:bell_ceiling").y(rot + 90)) // adding 90 here and below to maintain Parity with vanilla's weird choice of rotations - .put("attachment=floor,facing="+dir.getName(), JState.model("builtin:bell_floor").y(rot + 90)) - .put("attachment=single_wall,facing="+dir.getName(), JState.model("builtin:bell_wall").y(rot)) - ; - } - pack.addBlockState(JState.state(variant), new Identifier("bell")); + addBlockState(new Identifier("bell"), + t -> { + var vars = new DelimitedAppender(","); + for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { + int rot = (int)dir.asRotation() + 90; + vars + .append(variantY(t, "attachment=double_wall,facing="+dir.getName(), "builtin:bell_between_walls", rot)) + .append(variantY(t, "attachment=ceiling,facing="+dir.getName(), "builtin:bell_ceiling", rot + 90)) // adding 90 here and below to maintain Parity with vanilla's weird choice of rotations + .append(variantY(t, "attachment=floor,facing="+dir.getName(), "builtin:bell_floor", rot + 90)) + .append(variantY(t, "attachment=single_wall,facing="+dir.getName(), "builtin:bell_wall", rot)); + } + return vars.get(); + }, pack); } public static void addBedModels(DyeColor bedColor, EBEPack pack) { String color = bedColor.getName(); - pack.addModel( - JModel.model() - .parent(bedAOSuffix("block/template_bed_head")) - .textures(withBedParticle(JModel.textures().var("bed", "entity/bed/" + color), color)), - new Identifier("block/" + color + "_bed_head") - ); - pack.addModel( - JModel.model() - .parent(bedAOSuffix("block/template_bed_foot")) - .textures(withBedParticle(JModel.textures().var("bed", "entity/bed/" + color), color)), - new Identifier("block/" + color + "_bed_foot") - ); + + addParentTexModel(bedAOSuffix("block/template_bed_head"), + bedParticle(color) + kv("bed", "entity/bed/" + color), + new Identifier("block/" + color + "_bed_head"), pack); + addParentTexModel(bedAOSuffix("block/template_bed_foot"), + bedParticle(color) + kv("bed", "entity/bed/" + color), + new Identifier("block/" + color + "_bed_foot"), pack); } public static void addBedBlockState(DyeColor bedColor, EBEPack pack) { String color = bedColor.getName(); - JVariant variant = JState.variant(); - for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { - int rot = (int)dir.asRotation() + 180; - variant - .put("part=head,facing="+dir.getName(), JState.model("block/" + bedColor + "_bed_head").y(rot)) - .put("part=foot,facing="+dir.getName(), JState.model("block/" + bedColor + "_bed_foot").y(rot)); - } - pack.addBlockState(JState.state(variant), new Identifier(color + "_bed")); + addBlockState(new Identifier(color + "_bed"), + t -> { + var vars = new DelimitedAppender(","); + for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { + int rot = (int)dir.asRotation() + 180; + vars + .append(variantY(t, "part=head,facing="+dir.getName(), "block/" + bedColor + "_bed_head", rot)) + .append(variantY(t, "part=foot,facing="+dir.getName(), "block/" + bedColor + "_bed_foot", rot)); + } + return vars.get(); + }, pack); } private static String bedAOSuffix(String model) { @@ -217,45 +269,53 @@ public static void addShulkerBoxModels(@Nullable DyeColor color, EBEPack pack) { var texture = color != null ? "entity/shulker/shulker_"+color.getName() : "entity/shulker/shulker"; var shulkerBoxStr = color != null ? color.getName()+"_shulker_box" : "shulker_box"; var particle = "block/"+shulkerBoxStr; - pack.addModel(JModel.model().parent("block/template_shulker_box").textures(JModel.textures().var("shulker", texture).var("particle", particle)), new Identifier("block/"+shulkerBoxStr)); - pack.addModel(JModel.model().parent("block/template_shulker_box_bottom").textures(JModel.textures().var("shulker", texture).var("particle", particle)), new Identifier("block/"+shulkerBoxStr+"_bottom")); - pack.addModel(JModel.model().parent("block/template_shulker_box_lid").textures(JModel.textures().var("shulker", texture).var("particle", particle)), new Identifier("block/"+shulkerBoxStr+"_lid")); + addParentTexModel("block/template_shulker_box", + list(kv("shulker", texture), kv("particle", particle)), + new Identifier("block/"+shulkerBoxStr), pack); + addParentTexModel("block/template_shulker_box_bottom", + list(kv("shulker", texture), kv("particle", particle)), + new Identifier("block/"+shulkerBoxStr+"_bottom"), pack); + addParentTexModel("block/template_shulker_box_lid", + list(kv("shulker", texture), kv("particle", particle)), + new Identifier("block/"+shulkerBoxStr+"_lid"), pack); } public static void addShulkerBoxBlockStates(@Nullable DyeColor color, EBEPack pack) { var shulkerBoxStr = color != null ? color.getName()+"_shulker_box" : "shulker_box"; - var variant = JState.variant() - .put("facing=up", JState.model("builtin:"+shulkerBoxStr)) - .put("facing=down", JState.model("builtin:"+shulkerBoxStr).x(180)); - for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { - int rot = (int)dir.asRotation() + 180; - variant.put("facing="+dir.getName(), JState.model("builtin:"+shulkerBoxStr).x(90).y(rot)); - } - pack.addBlockState(JState.state(variant), new Identifier(shulkerBoxStr)); + addBlockState(new Identifier(shulkerBoxStr), + t -> { + var vars = new DelimitedAppender(","); + vars + .append(variant(t, "facing=up", "builtin:"+shulkerBoxStr)) + .append(variantXY(t, "facing=down", "builtin:"+shulkerBoxStr, 180, 0)); + for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { + int rot = (int)dir.asRotation() + 180; + vars.append(variantXY(t, "facing="+dir.getName(), "builtin:"+shulkerBoxStr, 90, rot)); + } + return vars.get(); + }, pack); } public static void addDecoratedPotBlockState(EBEPack pack) { - pack.addBlockState(JState.state(variantHFacing(JState.variant(), "facing=", "builtin:decorated_pot")), new Identifier("decorated_pot")); + addBlockState(new Identifier("decorated_pot"), + t -> variantHFacing(t, "facing=", "builtin:decorated_pot"), pack); } public static void addDecoratedPotPatternModels(RegistryKey patternKey, EBEPack pack) { for (Direction dir : EBEUtil.HORIZONTAL_DIRECTIONS) { - pack.addModel(JModel.model().parent("block/template_pottery_pattern_" + dir.getName()) - .textures( - JModel.textures() - .var("pattern", DecoratedPotPatterns.getTextureId(patternKey).toString()) - ), - new Identifier("block/" + patternKey.getValue().getPath() + "_" + dir.getName()) - ); + addParentTexModel("block/template_pottery_pattern_" + dir.getName(), + kv("pattern", DecoratedPotPatterns.getTextureId(patternKey).toString()), + new Identifier("block/" + patternKey.getValue().getPath() + "_" + dir.getName()), + pack); } } public static void resetBasePack() { - BASE_PACK = new EBEPack(EBEUtil.id("base_resources")); + BASE_PACK = new EBEPack(EBEUtil.id("base_resources"), EnhancedBlockEntities.TEMPLATE_LOADER); } public static void resetTopLevelPack() { - TOP_LEVEL_PACK = new EBEPack(EBEUtil.id("top_level_resources")); + TOP_LEVEL_PACK = new EBEPack(EBEUtil.id("top_level_resources"), EnhancedBlockEntities.TEMPLATE_LOADER); } public static EBEPack getBasePack() { @@ -296,11 +356,31 @@ public static void dumpModAssets(Path dest) throws IOException { } public static void dumpAllPacks(Path dest) throws IOException { - getBasePack().dumpDirect(dest); - getTopLevelPack().dumpDirect(dest); + getBasePack().dump(dest); + getTopLevelPack().dump(dest); dumpModAssets(dest); } + private static class DelimitedAppender { + private final StringBuilder builder = new StringBuilder(); + private final CharSequence delimiter; + + private DelimitedAppender(CharSequence delimiter) { + this.delimiter = delimiter; + } + + public DelimitedAppender append(CharSequence seq) { + if (!this.builder.isEmpty()) this.builder.append(this.delimiter); + + this.builder.append(seq); + return this; + } + + public String get() { + return this.builder.toString(); + } + } + static { resetBasePack(); resetTopLevelPack(); diff --git a/src/main/java/foundationgames/enhancedblockentities/util/hacks/ResourceHacks.java b/src/main/java/foundationgames/enhancedblockentities/util/hacks/ResourceHacks.java index fa303463..e866f36b 100644 --- a/src/main/java/foundationgames/enhancedblockentities/util/hacks/ResourceHacks.java +++ b/src/main/java/foundationgames/enhancedblockentities/util/hacks/ResourceHacks.java @@ -2,7 +2,6 @@ import foundationgames.enhancedblockentities.client.resource.EBEPack; import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import java.io.IOException; @@ -19,7 +18,7 @@ private static void cropAndPutTexture(Identifier source, Identifier result, Reso } if (image == null) return; - TextureHacks.cropImage(image, u0, v0, u1, v1).ifPresent(imgBytes -> pack.addResource(ResourceType.CLIENT_RESOURCES, result, imgBytes)); + TextureHacks.cropImage(image, u0, v0, u1, v1).ifPresent(imgBytes -> pack.addResource(result, imgBytes)); image.close(); } diff --git a/src/main/resources/enhancedblockentities.accesswidener b/src/main/resources/enhancedblockentities.accesswidener index 8471e1df..015811d1 100644 --- a/src/main/resources/enhancedblockentities.accesswidener +++ b/src/main/resources/enhancedblockentities.accesswidener @@ -2,3 +2,5 @@ accessWidener v2 named accessible class net/minecraft/client/option/SimpleOption$Callbacks accessible class net/minecraft/client/render/model/BakedModelManager$BakingResult + +accessible field net/minecraft/block/DecoratedPotPatterns DECORATED_POT_SIDE_KEY Lnet/minecraft/registry/RegistryKey; diff --git a/src/main/resources/templates/blockstate/base.json b/src/main/resources/templates/blockstate/base.json new file mode 100644 index 00000000..db0e7b03 --- /dev/null +++ b/src/main/resources/templates/blockstate/base.json @@ -0,0 +1,5 @@ +{ + "variants": { + ![vars] + } +} \ No newline at end of file diff --git a/src/main/resources/templates/blockstate/var.json b/src/main/resources/templates/blockstate/var.json new file mode 100644 index 00000000..c58c587d --- /dev/null +++ b/src/main/resources/templates/blockstate/var.json @@ -0,0 +1 @@ +"![state]": {![extra]"model": "![model]"} \ No newline at end of file diff --git a/src/main/resources/templates/chest_item_model.json b/src/main/resources/templates/chest_item_model.json new file mode 100644 index 00000000..a4cc2f6c --- /dev/null +++ b/src/main/resources/templates/chest_item_model.json @@ -0,0 +1 @@ +{"parent":"block/![chest]","overrides":[{"predicate":{"ebe:is_christmas":1},"model": "item/christmas_chest"}]} \ No newline at end of file diff --git a/src/main/resources/templates/model/chest_like.json b/src/main/resources/templates/model/chest_like.json new file mode 100644 index 00000000..2826e974 --- /dev/null +++ b/src/main/resources/templates/model/chest_like.json @@ -0,0 +1,7 @@ +{ + "parent": "block/![parent]", + "textures": { + ![particle] + "chest": "entity/chest/![chest_tex]" + } +} \ No newline at end of file diff --git a/src/main/resources/templates/model/parent_and_tex.json b/src/main/resources/templates/model/parent_and_tex.json new file mode 100644 index 00000000..b24028b7 --- /dev/null +++ b/src/main/resources/templates/model/parent_and_tex.json @@ -0,0 +1,6 @@ +{ + "parent": "![parent]", + "textures": { + ![textures] + } +} \ No newline at end of file