From b8d2e6b4ab6beb99ce21c7da6105235d8b264c87 Mon Sep 17 00:00:00 2001 From: Martin Prokoph Date: Tue, 24 Dec 2024 14:01:05 +0100 Subject: [PATCH] Many QoL improvements & Resourcepack features - Support Sodium 0.6+ - Allow resourcepacks to force culling and hide fully-encircled leaf blocks - Force leaf culling when the smart leaves pack is enabled - Reload world when the config changes - Only apply Sodium mixins when Sodium is actually installed (Removes log spam) --- common/build.gradle | 2 - .../cullleaves/CullLeavesClient.java | 78 +++++++++++++++++++ .../cullleaves/CullLeavesMixinPlugin.java | 32 ++++++++ .../cullleaves/config/CullLeavesConfig.java | 7 ++ .../mixin/MixinBlockModelRenderer.java | 25 ++++++ .../cullleaves/mixin/MixinLeavesBlock.java | 8 +- .../mixin/MixinMangroveRootsBlock.java | 8 +- .../src/main/resources/cullleaves.mixins.json | 5 +- .../assets/cullleaves/options/options.json | 3 + fabric/build.gradle | 7 +- .../fabric/CullLeavesClientFabric.java | 18 ++++- .../mixin/sodium/MixinBlockRenderer.java | 22 ++++++ .../sodium/MixinSodiumGameOptionPages.java | 55 +++++++++++++ .../resources/cullleaves-fabric.mixins.json | 14 ++++ fabric/src/main/resources/fabric.mod.json | 7 +- gradle.properties | 16 ++-- neoforge/build.gradle | 11 ++- .../neoforge/CullLeavesClientEvents.java | 10 ++- .../mixin/sodium/MixinBlockRenderer.java | 26 +++++++ .../sodium}/MixinSodiumGameOptionPages.java | 16 ++-- .../resources/META-INF/neoforge.mods.toml | 5 +- .../resources/cullleaves-neoforge.mixins.json | 14 ++++ 22 files changed, 343 insertions(+), 46 deletions(-) create mode 100644 common/src/main/java/eu/midnightdust/cullleaves/CullLeavesClient.java create mode 100644 common/src/main/java/eu/midnightdust/cullleaves/CullLeavesMixinPlugin.java create mode 100644 common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinBlockModelRenderer.java create mode 100644 common/src/main/resources/resourcepacks/smartleaves/assets/cullleaves/options/options.json create mode 100644 fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinBlockRenderer.java create mode 100644 fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinSodiumGameOptionPages.java create mode 100644 fabric/src/main/resources/cullleaves-fabric.mixins.json create mode 100644 neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinBlockRenderer.java rename {common/src/main/java/eu/midnightdust/cullleaves/mixin => neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium}/MixinSodiumGameOptionPages.java (81%) create mode 100644 neoforge/src/main/resources/cullleaves-neoforge.mixins.json diff --git a/common/build.gradle b/common/build.gradle index 62246a9..5c0bee3 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -12,8 +12,6 @@ dependencies { // Do NOT use other classes from fabric loader modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modCompileOnlyApi "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric" - modCompileOnlyApi "maven.modrinth:sodium:${rootProject.sodium_version}" - // Remove the next line if you don't want to depend on the API //modApi "dev.architectury:architectury:${rootProject.architectury_version}" } diff --git a/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesClient.java b/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesClient.java new file mode 100644 index 0000000..bb5078d --- /dev/null +++ b/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesClient.java @@ -0,0 +1,78 @@ +package eu.midnightdust.cullleaves; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import eu.midnightdust.cullleaves.config.CullLeavesConfig; +import net.minecraft.block.BlockState; +import net.minecraft.block.LeavesBlock; +import net.minecraft.block.MangroveRootsBlock; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.SynchronousResourceReloader; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class CullLeavesClient { + public static final String MOD_ID = "cullleaves"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + public static boolean forceLeafCulling = false; + public static boolean forceHideInnerLeaves = false; + + public static boolean shouldHideBlock(BlockView world, BlockPos pos) { + if (CullLeavesClient.forceHideInnerLeaves) { + boolean shouldForceCull = true; + for (Direction dir : Direction.values()) { + BlockState otherState = world.getBlockState(pos.offset(dir)); + if (!(otherState.getBlock() instanceof LeavesBlock) && + !otherState.isSideSolidFullSquare(world, pos, dir.getOpposite())) { + shouldForceCull = false; + break; + } + } + return shouldForceCull; + } + return false; + } + public static boolean isLeafSideInvisible(BlockState neighborState) { + if (CullLeavesConfig.enabled || CullLeavesClient.forceLeafCulling) { + return neighborState.getBlock() instanceof LeavesBlock; + } + else return false; + } + public static boolean isRootSideInvisible(BlockState neighborState) { + if (CullLeavesConfig.cullRoots) { + return neighborState.getBlock() instanceof MangroveRootsBlock; + } + else return false; + } + + public static class ReloadListener implements SynchronousResourceReloader { + public static final ReloadListener INSTANCE = new ReloadListener(); + + private ReloadListener() {} + + @Override + public void reload(ResourceManager manager) { + CullLeavesClient.forceLeafCulling = false; + CullLeavesClient.forceHideInnerLeaves = false; + manager.findResources("options", path -> path.toString().startsWith("cullleaves") && path.toString().endsWith("options.json")).forEach((id, resource) -> { + try { + JsonObject json = JsonParser.parseReader(resource.getReader()).getAsJsonObject(); + if (json.has("forceLeafCulling")) { + CullLeavesClient.forceLeafCulling = json.get("forceLeafCulling").getAsBoolean(); + LOGGER.info("Forcing leaf culling as requested by resourcepack"); + } + if (json.has("forceHideInnerLeaves")) { + CullLeavesClient.forceHideInnerLeaves = json.get("forceHideInnerLeaves").getAsBoolean(); + LOGGER.info("Not rendering inner leaves as requested by resourcepack"); + } + } catch (IOException e) { throw new RuntimeException(e); } + }); + } + } +} diff --git a/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesMixinPlugin.java b/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesMixinPlugin.java new file mode 100644 index 0000000..2e0aa71 --- /dev/null +++ b/common/src/main/java/eu/midnightdust/cullleaves/CullLeavesMixinPlugin.java @@ -0,0 +1,32 @@ +package eu.midnightdust.cullleaves; + +import eu.midnightdust.lib.util.PlatformFunctions; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Set; + +public class CullLeavesMixinPlugin implements IMixinConfigPlugin { + private String mixinPackage; + + @Override + public void onLoad(String mixinPackage) { + this.mixinPackage = mixinPackage + "."; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + final String mixinName = mixinClassName.substring(this.mixinPackage.length()); + + if (mixinName.indexOf('.') < 0) return true; + return PlatformFunctions.isModLoaded(mixinName.substring(0, mixinName.indexOf('.'))); + } + + @Override public List getMixins() { return null; } + @Override public String getRefMapperConfig() { return null; } + @Override public void acceptTargets(Set myTargets, Set otherTargets) {} + @Override public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} + @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} +} \ No newline at end of file diff --git a/common/src/main/java/eu/midnightdust/cullleaves/config/CullLeavesConfig.java b/common/src/main/java/eu/midnightdust/cullleaves/config/CullLeavesConfig.java index 605069f..f494fa0 100755 --- a/common/src/main/java/eu/midnightdust/cullleaves/config/CullLeavesConfig.java +++ b/common/src/main/java/eu/midnightdust/cullleaves/config/CullLeavesConfig.java @@ -1,10 +1,17 @@ package eu.midnightdust.cullleaves.config; import eu.midnightdust.lib.config.MidnightConfig; +import net.minecraft.client.MinecraftClient; public class CullLeavesConfig extends MidnightConfig { @Entry // Enable/Disable the mod. Requires Chunk Reload (F3 + A). public static boolean enabled = true; @Entry // Enable/Disable culling on Mangrove Roots. public static boolean cullRoots = true; + + @Override + public void writeChanges(String modid) { + MinecraftClient.getInstance().worldRenderer.reload(); + super.writeChanges(modid); + } } diff --git a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinBlockModelRenderer.java b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinBlockModelRenderer.java new file mode 100644 index 0000000..6956ec2 --- /dev/null +++ b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinBlockModelRenderer.java @@ -0,0 +1,25 @@ +package eu.midnightdust.cullleaves.mixin; + +import eu.midnightdust.cullleaves.CullLeavesClient; +import net.minecraft.block.BlockState; +import net.minecraft.block.LeavesBlock; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.block.BlockModelRenderer; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.BlockRenderView; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BlockModelRenderer.class) +public class MixinBlockModelRenderer { + @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZLnet/minecraft/util/math/random/Random;JI)V", cancellable = true) + private void cullleaves$cancelRendering(BlockRenderView world, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrices, VertexConsumer vertexConsumer, boolean cull, Random random, long seed, int overlay, CallbackInfo ci) { + if (state.getBlock() instanceof LeavesBlock && + CullLeavesClient.shouldHideBlock(world, pos)) ci.cancel(); + } +} diff --git a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinLeavesBlock.java b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinLeavesBlock.java index 72e4029..0883a60 100755 --- a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinLeavesBlock.java +++ b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinLeavesBlock.java @@ -1,6 +1,6 @@ package eu.midnightdust.cullleaves.mixin; -import eu.midnightdust.cullleaves.config.CullLeavesConfig; +import eu.midnightdust.cullleaves.CullLeavesClient; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.block.Block; @@ -18,11 +18,7 @@ public abstract class MixinLeavesBlock extends Block { } @Override - @SuppressWarnings("deprecation") public boolean isSideInvisible(BlockState state, BlockState neighborState, Direction offset) { - if (CullLeavesConfig.enabled) { - return neighborState.getBlock() instanceof LeavesBlock; - } - else return false; + return CullLeavesClient.isLeafSideInvisible(neighborState); } } \ No newline at end of file diff --git a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinMangroveRootsBlock.java b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinMangroveRootsBlock.java index adecbc9..b2153f5 100755 --- a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinMangroveRootsBlock.java +++ b/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinMangroveRootsBlock.java @@ -1,6 +1,6 @@ package eu.midnightdust.cullleaves.mixin; -import eu.midnightdust.cullleaves.config.CullLeavesConfig; +import eu.midnightdust.cullleaves.CullLeavesClient; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.block.*; @@ -16,11 +16,7 @@ public abstract class MixinMangroveRootsBlock extends Block { } @Override - @SuppressWarnings("deprecation") public boolean isSideInvisible(BlockState state, BlockState neighborState, Direction offset) { - if (CullLeavesConfig.cullRoots) { - return neighborState.getBlock() instanceof MangroveRootsBlock; - } - else return false; + return CullLeavesClient.isRootSideInvisible(neighborState); } } \ No newline at end of file diff --git a/common/src/main/resources/cullleaves.mixins.json b/common/src/main/resources/cullleaves.mixins.json index 0d01c5a..043214a 100644 --- a/common/src/main/resources/cullleaves.mixins.json +++ b/common/src/main/resources/cullleaves.mixins.json @@ -1,12 +1,13 @@ { "required": true, "package": "eu.midnightdust.cullleaves.mixin", + "plugin": "eu.midnightdust.cullleaves.CullLeavesMixinPlugin", "compatibilityLevel": "JAVA_17", "minVersion": "0.8", "client": [ + "MixinBlockModelRenderer", "MixinLeavesBlock", - "MixinMangroveRootsBlock", - "MixinSodiumGameOptionPages" + "MixinMangroveRootsBlock" ], "injectors": { "defaultRequire": 1 diff --git a/common/src/main/resources/resourcepacks/smartleaves/assets/cullleaves/options/options.json b/common/src/main/resources/resourcepacks/smartleaves/assets/cullleaves/options/options.json new file mode 100644 index 0000000..47bbe5e --- /dev/null +++ b/common/src/main/resources/resourcepacks/smartleaves/assets/cullleaves/options/options.json @@ -0,0 +1,3 @@ +{ + "forceLeafCulling": true +} \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle index 7b82654..372eb46 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -9,8 +9,6 @@ architectury { fabric() } -loom { -} repositories { maven { url "https://api.modrinth.com/maven" } } @@ -29,9 +27,8 @@ dependencies { modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" // Remove the next line if you don't want to depend on the API //modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" - modImplementation "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric" - include "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric" - modRuntimeOnly "maven.modrinth:sodium:${rootProject.sodium_version}" + modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric") + modImplementation "maven.modrinth:sodium:${rootProject.sodium_version}-fabric" common(project(path: ":common", configuration: "namedElements")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } diff --git a/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/CullLeavesClientFabric.java b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/CullLeavesClientFabric.java index a2101ad..a13fd2b 100644 --- a/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/CullLeavesClientFabric.java +++ b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/CullLeavesClientFabric.java @@ -1,19 +1,33 @@ package eu.midnightdust.cullleaves.fabric; +import eu.midnightdust.cullleaves.CullLeavesClient; import eu.midnightdust.cullleaves.config.CullLeavesConfig; import eu.midnightdust.lib.config.MidnightConfig; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourcePackActivationType; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; public class CullLeavesClientFabric implements ClientModInitializer { @Override public void onInitializeClient() { - MidnightConfig.init("cullleaves", CullLeavesConfig.class); + MidnightConfig.init(CullLeavesClient.MOD_ID, CullLeavesConfig.class); FabricLoader.getInstance().getModContainer("cullleaves").ifPresent(modContainer -> { - ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of("cullleaves:smartleaves"), modContainer, ResourcePackActivationType.NORMAL); + ResourceManagerHelper.registerBuiltinResourcePack(Identifier.of(CullLeavesClient.MOD_ID,"smartleaves"), modContainer, ResourcePackActivationType.NORMAL); + }); + ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + @Override + public Identifier getFabricId() { + return Identifier.of(CullLeavesClient.MOD_ID, "resourcepack_options"); + } + @Override + public void reload(ResourceManager manager) { + CullLeavesClient.ReloadListener.INSTANCE.reload(manager); + } }); } } diff --git a/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinBlockRenderer.java b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinBlockRenderer.java new file mode 100644 index 0000000..38e52ba --- /dev/null +++ b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinBlockRenderer.java @@ -0,0 +1,22 @@ +package eu.midnightdust.cullleaves.fabric.mixin.sodium; + +import eu.midnightdust.cullleaves.CullLeavesClient; +import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderer; +import net.caffeinemc.mods.sodium.client.render.frapi.render.AbstractBlockRenderContext; +import net.minecraft.block.BlockState; +import net.minecraft.block.LeavesBlock; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BlockRenderer.class) +public abstract class MixinBlockRenderer extends AbstractBlockRenderContext { + @Inject(at = @At("HEAD"), method = "renderModel", cancellable = true) + public void cullleaves$cancelRendering(BakedModel model, BlockState state, BlockPos pos, BlockPos origin, CallbackInfo ci) { + if (state.getBlock() instanceof LeavesBlock && CullLeavesClient.shouldHideBlock(this.level, pos)) + ci.cancel(); + } +} diff --git a/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinSodiumGameOptionPages.java b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinSodiumGameOptionPages.java new file mode 100644 index 0000000..5797df6 --- /dev/null +++ b/fabric/src/main/java/eu/midnightdust/cullleaves/fabric/mixin/sodium/MixinSodiumGameOptionPages.java @@ -0,0 +1,55 @@ +package eu.midnightdust.cullleaves.fabric.mixin.sodium; + +import eu.midnightdust.cullleaves.config.CullLeavesConfig; +import net.caffeinemc.mods.sodium.client.gui.options.OptionFlag; +import net.caffeinemc.mods.sodium.client.gui.options.OptionGroup; +import net.caffeinemc.mods.sodium.client.gui.options.OptionImpact; +import net.caffeinemc.mods.sodium.client.gui.options.OptionImpl; +import net.caffeinemc.mods.sodium.client.gui.options.control.TickBoxControl; +import net.caffeinemc.mods.sodium.client.gui.options.storage.SodiumOptionsStorage; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import java.util.List; + +@Mixin(value = net.caffeinemc.mods.sodium.client.gui.SodiumGameOptionPages.class, remap = false) +public class MixinSodiumGameOptionPages { + + @Shadow @Final private static SodiumOptionsStorage sodiumOpts; + + @ModifyVariable(method = "performance", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;")) + private static List cullleaves$addCullLeavesOption(List groups) { + groups.add(OptionGroup.createBuilder() + .add(OptionImpl.createBuilder(boolean.class, sodiumOpts) + .setName(Text.translatable("cullleaves.midnightconfig.enabled")) + .setTooltip(Text.translatable("cullleaves.midnightconfig.enabled.tooltip.sodium")) + .setControl(TickBoxControl::new) + .setBinding((opts, value) -> { + CullLeavesConfig.enabled = value; + CullLeavesConfig.write("cullleaves"); + }, opts -> CullLeavesConfig.enabled) + .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) + .setImpact(OptionImpact.MEDIUM) + .build() + ).add(OptionImpl.createBuilder(boolean.class, sodiumOpts) + .setName(Text.translatable("cullleaves.midnightconfig.cullRoots")) + .setTooltip(Text.translatable("cullleaves.midnightconfig.cullRoots.tooltip.sodium")) + .setControl(TickBoxControl::new) + .setBinding((opts, value) -> { + CullLeavesConfig.cullRoots = value; + CullLeavesConfig.write("cullleaves"); + }, opts -> CullLeavesConfig.cullRoots) + .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) + .setImpact(OptionImpact.MEDIUM) + .build() + ) + .build() + ); + + return groups; + } +} diff --git a/fabric/src/main/resources/cullleaves-fabric.mixins.json b/fabric/src/main/resources/cullleaves-fabric.mixins.json new file mode 100644 index 0000000..c58f968 --- /dev/null +++ b/fabric/src/main/resources/cullleaves-fabric.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "eu.midnightdust.cullleaves.fabric.mixin", + "plugin": "eu.midnightdust.cullleaves.CullLeavesMixinPlugin", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "client": [ + "sodium.MixinBlockRenderer", + "sodium.MixinSodiumGameOptionPages" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 11b0563..5907e32 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -27,13 +27,14 @@ "depends": { "midnightlib": "*", - "minecraft": ">=1.19.3" + "minecraft": ">=1.21" }, "breaks": { - "sodium": "<0.4.9" + "sodium": "<0.6.0" }, "mixins": [ - "cullleaves.mixins.json" + "cullleaves.mixins.json", + "cullleaves-fabric.mixins.json" ] } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 045a861..3453016 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,23 +1,23 @@ org.gradle.jvmargs=-Xmx4096M -minecraft_version=1.21 -yarn_mappings=1.21+build.2 +minecraft_version=1.21.1 +yarn_mappings=1.21.1+build.3 enabled_platforms=fabric,neoforge archives_base_name=cullleaves -mod_version=3.4.0 +mod_version=4.0.0 maven_group=eu.midnightdust release_type=release curseforge_id=423254 modrinth_id=GNxdLCoP -midnightlib_version=1.5.7 -sodium_version=mc1.21-0.5.9 +midnightlib_version=1.6.3 +sodium_version=mc1.21.1-0.6.5 -fabric_loader_version=0.15.11 -fabric_api_version=0.100.1+1.21 +fabric_loader_version=0.16.9 +fabric_api_version=0.110.0+1.21.1 -neoforge_version=21.0.14-beta +neoforge_version=21.1.82 yarn_mappings_patch_neoforge_version = 1.21+build.4 quilt_loader_version=0.18.9 diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 0ae8c50..ca964c2 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -12,7 +12,15 @@ architectury { loom {} repositories { maven { url "https://api.modrinth.com/maven" } - maven {url "https://maven.neoforged.net/releases"} + maven { url "https://maven.neoforged.net/releases" } + maven { url "https://maven.pkg.github.com/ims212/ForgifiedFabricAPI" + credentials { + username = "IMS212" + // Read only token + password = "ghp_" + "DEuGv0Z56vnSOYKLCXdsS9svK4nb9K39C1Hn" + } + } + maven{ url "https://maven.su5ed.dev/releases" } } configurations { @@ -29,6 +37,7 @@ dependencies { // Remove the next line if you don't want to depend on the API //modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" modImplementation "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-neoforge" + modImplementation "maven.modrinth:sodium:${rootProject.sodium_version}-neoforge" //include "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-forge" common(project(path: ":common", configuration: "namedElements")) { transitive false } diff --git a/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/CullLeavesClientEvents.java b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/CullLeavesClientEvents.java index 65a8312..378c02a 100644 --- a/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/CullLeavesClientEvents.java +++ b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/CullLeavesClientEvents.java @@ -1,5 +1,6 @@ package eu.midnightdust.cullleaves.neoforge; +import eu.midnightdust.cullleaves.CullLeavesClient; import net.minecraft.resource.*; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -7,17 +8,18 @@ import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModList; import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforgespi.locating.IModFile; import java.util.Optional; -@EventBusSubscriber(modid = "cullleaves", bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +@EventBusSubscriber(modid = CullLeavesClient.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public class CullLeavesClientEvents { @SubscribeEvent public static void addPackFinders(AddPackFindersEvent event) { if (event.getPackType() == ResourceType.CLIENT_RESOURCES) { - registerResourcePack(event, Identifier.of("cullleaves", "smartleaves"), false); + registerResourcePack(event, Identifier.of(CullLeavesClient.MOD_ID, "smartleaves"), false); } } private static void registerResourcePack(AddPackFindersEvent event, Identifier id, boolean alwaysEnabled) { @@ -33,4 +35,8 @@ public class CullLeavesClientEvents { } catch (NullPointerException e) {e.fillInStackTrace();} })); } + @SubscribeEvent + public static void onResourceReload(RegisterClientReloadListenersEvent event) { + event.registerReloadListener(CullLeavesClient.ReloadListener.INSTANCE); + } } diff --git a/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinBlockRenderer.java b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinBlockRenderer.java new file mode 100644 index 0000000..6874bf4 --- /dev/null +++ b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinBlockRenderer.java @@ -0,0 +1,26 @@ +package eu.midnightdust.cullleaves.neoforge.mixin.sodium; + +import eu.midnightdust.cullleaves.CullLeavesClient; +import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderer; +import net.minecraft.block.BlockState; +import net.minecraft.block.LeavesBlock; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BlockRenderer.class) +public abstract class MixinBlockRenderer { + // Unfortunately, we cannot use the level view from AbstractBlockRenderContext on NeoForge because of method conflicts + @Unique private static final MinecraftClient cullleaves$client = MinecraftClient.getInstance(); + + @Inject(at = @At("HEAD"), method = "renderModel", cancellable = true) + public void cullleaves$cancelRendering(BakedModel model, BlockState state, BlockPos pos, BlockPos origin, CallbackInfo ci) { + if (CullLeavesClient.forceHideInnerLeaves && state.getBlock() instanceof LeavesBlock && CullLeavesClient.shouldHideBlock(cullleaves$client.world, pos)) + ci.cancel(); + } +} diff --git a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinSodiumGameOptionPages.java b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinSodiumGameOptionPages.java similarity index 81% rename from common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinSodiumGameOptionPages.java rename to neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinSodiumGameOptionPages.java index 3b184fa..b842658 100644 --- a/common/src/main/java/eu/midnightdust/cullleaves/mixin/MixinSodiumGameOptionPages.java +++ b/neoforge/src/main/java/eu/midnightdust/cullleaves/neoforge/mixin/sodium/MixinSodiumGameOptionPages.java @@ -1,13 +1,13 @@ -package eu.midnightdust.cullleaves.mixin; +package eu.midnightdust.cullleaves.neoforge.mixin.sodium; import eu.midnightdust.cullleaves.config.CullLeavesConfig; -import me.jellysquid.mods.sodium.client.gui.SodiumGameOptionPages; -import me.jellysquid.mods.sodium.client.gui.options.OptionFlag; -import me.jellysquid.mods.sodium.client.gui.options.OptionGroup; -import me.jellysquid.mods.sodium.client.gui.options.OptionImpact; -import me.jellysquid.mods.sodium.client.gui.options.OptionImpl; -import me.jellysquid.mods.sodium.client.gui.options.control.TickBoxControl; -import me.jellysquid.mods.sodium.client.gui.options.storage.SodiumOptionsStorage; +import net.caffeinemc.mods.sodium.client.gui.SodiumGameOptionPages; +import net.caffeinemc.mods.sodium.client.gui.options.OptionFlag; +import net.caffeinemc.mods.sodium.client.gui.options.OptionGroup; +import net.caffeinemc.mods.sodium.client.gui.options.OptionImpact; +import net.caffeinemc.mods.sodium.client.gui.options.OptionImpl; +import net.caffeinemc.mods.sodium.client.gui.options.control.TickBoxControl; +import net.caffeinemc.mods.sodium.client.gui.options.storage.SodiumOptionsStorage; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 55c5e70..d76837c 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -16,6 +16,9 @@ logoFile = "icon.png" [[mixins]] config = "cullleaves.mixins.json" +[[mixins]] +config = "cullleaves-neoforge.mixins.json" + [[dependencies.cullleaves]] modId = "neoforge" required = true @@ -26,7 +29,7 @@ side = "CLIENT" [[dependencies.cullleaves]] modId = "minecraft" required = true -versionRange = "[1.20,)" +versionRange = "[1.21,)" ordering = "NONE" side = "CLIENT" diff --git a/neoforge/src/main/resources/cullleaves-neoforge.mixins.json b/neoforge/src/main/resources/cullleaves-neoforge.mixins.json new file mode 100644 index 0000000..7396f95 --- /dev/null +++ b/neoforge/src/main/resources/cullleaves-neoforge.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "eu.midnightdust.cullleaves.neoforge.mixin", + "plugin": "eu.midnightdust.cullleaves.CullLeavesMixinPlugin", + "compatibilityLevel": "JAVA_17", + "minVersion": "0.8", + "client": [ + "sodium.MixinBlockRenderer", + "sodium.MixinSodiumGameOptionPages" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file