mirror of
https://github.com/TeamMidnightDust/CullLeaves.git
synced 2025-12-15 14:15:08 +01:00
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)
This commit is contained in:
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> getMixins() { return null; }
|
||||
@Override public String getRefMapperConfig() { return null; }
|
||||
@Override public void acceptTargets(Set<String> myTargets, Set<String> 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) {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package eu.midnightdust.cullleaves.mixin;
|
||||
|
||||
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.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 = 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<OptionGroup> cullleaves$addCullLeavesOption(List<OptionGroup> 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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"forceLeafCulling": true
|
||||
}
|
||||
Reference in New Issue
Block a user