Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OptiFine crash [1.20.1] #191

Open
wants to merge 1 commit into
base: 1.20.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.stal111.valhelsia_structures.core.mixin;

import com.mojang.logging.LogUtils;
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 MixinConfigPlugin implements IMixinConfigPlugin {
private static boolean hasOptiFine = false;

static {
try {
Class.forName("optifine.Installer");
hasOptiFine = true;
LogUtils.getLogger().warn("!!! OptiFine is found !!!");
LogUtils.getLogger().warn("!!! Things may not work correctly !!!");
} catch (ClassNotFoundException ignored) {}
}

@Override
public void onLoad(String mixinPackage) {
}

@Override
public String getRefMapperConfig() {
return null;
}

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (hasOptiFine) {
return !mixinClassName.equals("com.stal111.valhelsia_structures.core.mixin.BlockModelRendererMixin");
} else {
return !mixinClassName.equals("com.stal111.valhelsia_structures.core.mixin.compat.optifine.BlockModelRendererOFMixin");
}
}

@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}

@Override
public List<String> getMixins() {
return null;
}

@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}

@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.stal111.valhelsia_structures.core.mixin.compat.optifine;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.stal111.valhelsia_structures.common.block.properties.ModBlockStateProperties;
import com.stal111.valhelsia_structures.core.ValhelsiaStructures;
import com.stal111.valhelsia_structures.core.init.ModBlocks;
import com.stal111.valhelsia_structures.core.mixin.ModelBakerImplAccessor;
import com.stal111.valhelsia_structures.utils.BrightnessCombinerUtils;
import com.stal111.valhelsia_structures.utils.ModTags;
import com.stal111.valhelsia_structures.utils.PosBasedBrightnessCombiner;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.BlockModelRotation;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.DoubleBlockCombiner;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.ModelData;
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.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
* Block Model Renderer Mixin <br>
* Valhelsia Structures - com.stal111.valhelsia_structures.core.mixin.BlockModelRendererMixin
*
* @author Valhelsia Team
* @since 2021-03-25
*/
@Mixin(ModelBlockRenderer.class)
public abstract class BlockModelRendererOFMixin {

@Shadow public abstract void tesselateWithAO(BlockAndTintGetter p_111079_, BakedModel p_111080_, BlockState p_111081_, BlockPos p_111082_, PoseStack p_111083_, VertexConsumer p_111084_, boolean p_111085_, RandomSource p_111086_, long p_111087_, int p_111088_);

@Shadow public abstract void tesselateWithoutAO(BlockAndTintGetter p_111091_, BakedModel p_111092_, BlockState p_111093_, BlockPos p_111094_, PoseStack p_111095_, VertexConsumer p_111096_, boolean p_111097_, RandomSource p_111098_, long p_111099_, int p_111100_);

@Inject(at = @At(value = "RETURN"), method = "tesselateBlock(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/minecraftforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V", remap = false, cancellable = true)
private void valhelsia_tesselateBlock(BlockAndTintGetter level, BakedModel model, BlockState state, BlockPos pos, PoseStack poseStack, VertexConsumer vertexConsumer, boolean checkSides, RandomSource random, long seed, int packedOverlay, ModelData modelData, RenderType renderType, CallbackInfo ci) {
if (state.is(ModBlocks.BONE_PILE.get())) {
for (int i = 1; i < state.getValue(ModBlockStateProperties.LAYERS_1_5); i++) {
model = ModelBakerImplAccessor.createModelBakerImpl(Minecraft.getInstance().getModelManager().getModelBakery(), (resourceLocation, material) -> {
return Minecraft.getInstance().getTextureAtlas(material.atlasLocation()).apply(resourceLocation);
}, new ResourceLocation(ValhelsiaStructures.MOD_ID, "block/bone_pile")).bake(new ResourceLocation(ValhelsiaStructures.MOD_ID, "block/bone_pile"), BlockModelRotation.by(90, 90 * i));

if (model == null) {
return;
}

boolean flag = Minecraft.useAmbientOcclusion() && state.getLightEmission(level, pos) == 0 && model.useAmbientOcclusion();

poseStack.translate(0.0D, 0.0625D, 0.0D);
modelData = model.getModelData(level, pos, state, modelData);

try {
if (flag) {
this.tesselateWithAO(level, model, state, pos, poseStack, vertexConsumer, checkSides, random, seed, packedOverlay);
} else {
this.tesselateWithoutAO(level, model, state, pos, poseStack, vertexConsumer, checkSides, random, seed, packedOverlay);
}
ci.cancel();
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Tesselating block model");
CrashReportCategory crashreportcategory = crashreport.addCategory("Block model being tesselated");
CrashReportCategory.populateBlockDetails(crashreportcategory, level, pos, state);
crashreportcategory.setDetail("Using AO", flag);
throw new ReportedException(crashreport);
}
}
}
}

/*
OptiFine practically changes this whole entire file.
Due to this, this mixin was causing a crash since it could not find some methods that OptiFine removed.
*/
@ModifyVariable(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/ModelBlockRenderer;renderQuadSmooth(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lcom/mojang/blaze3d/vertex/PoseStack$Pose;Lnet/minecraft/client/renderer/block/model/BakedQuad;FFFFIIIIILnet/optifine/render/RenderEnv;)V"), method = "renderQuadsFlat", ordinal = 0, argsOnly = true)
private int valhelsia_renderQuadsFlatOF(int value, BlockAndTintGetter level, BlockState state, BlockPos pos) {
if (state.is(ModTags.Blocks.SLEEPING_BAGS)) {
DoubleBlockCombiner.NeighborCombineResult<BlockPos> neighborCombineResult = BrightnessCombinerUtils.combineWithNeigbour(BedBlock::getBlockType, BedBlock::getConnectedDirection, ChestBlock.FACING, state, level, pos, (p_112202_, p_112203_) -> false);

return neighborCombineResult.apply(new PosBasedBrightnessCombiner()).get(value);
}

return value;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/valhelsia_structures.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"required": true,
"minVersion": "0.8",
"compatibilityLevel": "JAVA_17",
"plugin": "com.stal111.valhelsia_structures.core.mixin.MixinConfigPlugin",
"package": "com.stal111.valhelsia_structures.core.mixin",
"refmap": "valhelsia_structures.refmap.json",
"mixins": [
Expand All @@ -17,6 +18,7 @@
],
"client": [
"BlockModelRendererMixin",
"compat.optifine.BlockModelRendererOFMixin",
"ModelBakerImplAccessor"
],
"injectors": {
Expand Down