From 204b13a23da839215da48896fd65b3c3b9f53932 Mon Sep 17 00:00:00 2001 From: Cadiboo <37298044+Cadiboo@users.noreply.github.com> Date: Sat, 20 Jan 2024 15:18:10 +1100 Subject: [PATCH] Make extended fluids start to work with Sodium --- .../github/cadiboo/nocubes/hooks/Hooks.java | 3 + .../cadiboo/nocubes/hooks/MixinAsm.java | 64 ++++++++++++------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/main/java/io/github/cadiboo/nocubes/hooks/Hooks.java b/src/main/java/io/github/cadiboo/nocubes/hooks/Hooks.java index 65e2fc88..1d7d1ee0 100644 --- a/src/main/java/io/github/cadiboo/nocubes/hooks/Hooks.java +++ b/src/main/java/io/github/cadiboo/nocubes/hooks/Hooks.java @@ -54,6 +54,7 @@ public static boolean collisionsEnabledFor(BlockStateBase state) { /** * Called from: {@link RebuildTask#compile} right before the BlockPos.getAllInBoxMutable iteration * Calls: {@link RendererDispatcher#renderChunk} to render our fluids and smooth terrain + * Call injected by {@link MixinAsm#transformChunkRenderer} */ @OnlyIn(Dist.CLIENT) public static void preIteration( @@ -76,6 +77,7 @@ public static void preIteration( /** * Same as {@link Hooks#preIteration} but for Sodium. + * Call injected by {@link MixinAsm#transformSodiumChunkRenderer} */ @OnlyIn(Dist.CLIENT) public static void preIterationSodium( @@ -113,6 +115,7 @@ public static void preIterationSodium( /** * Called from: {@link RebuildTask#compile} and {@link LiquidBlockRenderer#tesselate} instead of {@link BlockState#getFluidState()} + * Call injected by {@link MixinAsm#transformChunkRenderer} or {@link MixinAsm#transformSodiumChunkRenderer} *

* Hooking this makes extended fluids render properly */ diff --git a/src/main/java/io/github/cadiboo/nocubes/hooks/MixinAsm.java b/src/main/java/io/github/cadiboo/nocubes/hooks/MixinAsm.java index 76ad99ba..f455bfc6 100644 --- a/src/main/java/io/github/cadiboo/nocubes/hooks/MixinAsm.java +++ b/src/main/java/io/github/cadiboo/nocubes/hooks/MixinAsm.java @@ -88,27 +88,11 @@ public static void transformChunkRenderer(ClassNode targetClass) { print("Done injecting the preIteration hook"); } - // Redirects 'state.getFluidState()' to our own code so we can have extended fluids render properly - { - var getFluidStateCall = findFirstMethodCall( - methodNode, - ASMAPI.MethodType.VIRTUAL, - "net/minecraft/world/level/block/state/BlockState", - ASMAPI.mapMethod("m_60819_"), // getFluidState - "()Lnet/minecraft/world/level/material/FluidState;", - 0 // startIndex - ); - var previousLabel = findFirstLabelBefore(instructions, getFluidStateCall); - removeBetweenIndicesInclusive(instructions, instructions.indexOf(previousLabel) + 1, instructions.indexOf(getFluidStateCall)); - instructions.insert(previousLabel, ASMAPI.listOf( - new VarInsnNode(Opcodes.ALOAD, isOptiFinePresent ? (ofg8 ? 19 : 17) : 16), // pos - new VarInsnNode(Opcodes.ALOAD, isOptiFinePresent ? (ofg8 ? 20 : 18) : 18), // state - callNoCubesHook("getRenderFluidState", "(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/level/material/FluidState;") - )); - // We didn't remove the ASTORE instruction with our 'removeBetweenIndicesInclusive' so the result of our hook call automatically gets stored - print("Done injecting the fluid state getter redirect"); - } - + redirectBlockStateGetFluidStateSoExtendedFluidsWork( + methodNode, + // blockPos local variable index + isOptiFinePresent ? (ofg8 ? 19 : 17) : 16 + ); } static boolean detectOptiFine(InsnList instructions) { @@ -127,6 +111,39 @@ static boolean detectOptiFine(InsnList instructions) { return false; } + /** + * Redirects 'state.getFluidState()' to our own code, so we can have extended fluids render properly + * Specifically: changes 'state.getFluidState()' to 'Hooks.getRenderFluidState(pos, state)' + */ + static void redirectBlockStateGetFluidStateSoExtendedFluidsWork(MethodNode methodNode, int blockPosLocalVarIndex) { + var getFluidStateCall = findFirstMethodCall( + methodNode, + ASMAPI.MethodType.VIRTUAL, + "net/minecraft/world/level/block/state/BlockState", + ASMAPI.mapMethod("m_60819_"), // getFluidState + "()Lnet/minecraft/world/level/material/FluidState;", + 0 // startIndex + ); + + var instructions = methodNode.instructions; + var previousLabel = findFirstLabelBefore(instructions, getFluidStateCall); + + // Change + // LABEL + // + // INVOKE BlockState.getFluidState + // to + // LABEL + // LOAD blockPos + // + // INVOKE Hooks.getFluidState + instructions.insert(previousLabel, new VarInsnNode(Opcodes.ALOAD, blockPosLocalVarIndex)); + instructions.insert(getFluidStateCall, callNoCubesHook("getRenderFluidState", "(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/level/material/FluidState;")); + instructions.remove(getFluidStateCall); + + print("Done injecting the fluid state getter redirect"); + } + // endregion // region Fluid rendering @@ -217,6 +234,7 @@ public static void transformSodiumChunkRenderer(ClassNode targetClass) { var storeRenderContext = renderContextConstructor.getNext(); assertInstructionFound(storeRenderContext, "ASTORE blockRenderContext", instructions); + var blockPosLocalVarIndex = 14; instructions.insert(storeRenderContext, ASMAPI.listOf( // Fields new VarInsnNode(Opcodes.ALOAD, 0), // this @@ -235,11 +253,13 @@ public static void transformSodiumChunkRenderer(ClassNode targetClass) { new VarInsnNode(Opcodes.ILOAD, 11), // maxX new VarInsnNode(Opcodes.ILOAD, 12), // maxY new VarInsnNode(Opcodes.ILOAD, 13), // maxZ - new VarInsnNode(Opcodes.ALOAD, 14), // blockPos + new VarInsnNode(Opcodes.ALOAD, blockPosLocalVarIndex), // blockPos new VarInsnNode(Opcodes.ALOAD, 15), // modelOffset new VarInsnNode(Opcodes.ALOAD, 16), // context callNoCubesHook("preIterationSodium", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Lnet/minecraft/client/renderer/chunk/VisGraph;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;IIIIIILnet/minecraft/core/BlockPos$MutableBlockPos;Lnet/minecraft/core/BlockPos$MutableBlockPos;Ljava/lang/Object;)V") )); + + redirectBlockStateGetFluidStateSoExtendedFluidsWork(methodNode, blockPosLocalVarIndex); } /**