Skip to content

Commit

Permalink
Fix vanilla potion effects rendering above the NEI tooltips in the in…
Browse files Browse the repository at this point in the history
…ventory (#91)

* Fix vanilla potion effects rendering above the NEI tooltips in the inventory, and doesn't render the potions effects shadowed when NEI is hiden

* applied spotless
  • Loading branch information
Alexdoru authored Sep 1, 2022
1 parent bf4151d commit 98bff90
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public enum AsmTransformers {
() -> Hodgepodge.config.speedupProgressBar,
Collections.singletonList("com.mitchej123.hodgepodge.asm.SpeedupProgressBarTransformer")),
FIX_POTION_EFFECT_RENDERING(
"Move vanilla potion effect status rendering before everything else",
"Fix vanilla potion effects rendering above the NEI tooltips in the inventory",
() -> Hodgepodge.config.fixPotionEffectRender,
Collections.singletonList("com.mitchej123.hodgepodge.asm.InventoryEffectRendererTransformer")),
THERMOS_SLEDGEHAMMER_FURNACE_FIX(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import com.mitchej123.hodgepodge.asm.util.AbstractMethodTransformer;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.*;

public class InventoryEffectRendererTransformer extends AbstractClassTransformer {
public InventoryEffectRendererTransformer() {
Expand All @@ -15,25 +14,144 @@ public InventoryEffectRendererTransformer() {
new AbstractMethodTransformer() {
@Override
public void transform() {
// Cut out super.drawScreen() sequence
AbstractInsnNode start =

final String NEIClientConfigClasspath = "codechicken/nei/NEIClientConfig";
try {
if (this.getClass().getClassLoader().getResource(NEIClientConfigClasspath + ".class")
== null) {
log.info("Skip reordering InventoryEffectRenderer.drawScreen since NEI is not loaded");
return;
}
} catch (Exception ignored) {
}

/*
============ORIGINAL CODE=========
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
if (this.field_147045_u) {
this.func_147044_g();
}
============TARGET CODE==========
boolean bookmarkPanelHidden = NEIClientConfig.isHidden();
if (bookmarkPanelHidden) {
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
}
if (this.field_147045_u) {
this.func_147044_g();
}
if (bookmarkPanelHidden) {
return;
}
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
==========TARGET BYTECODE========
L0
INVOKESTATIC codechicken/nei/NEIClientConfig.isHidden ()Z
DUP
ISTORE 4
IFEQ L5
LINENUMBER 44 L0
ALOAD 0
ILOAD 1
ILOAD 2
FLOAD 3
INVOKESPECIAL net/minecraft/client/gui/inventory/GuiContainer.drawScreen (IIF)V
L5
L1
LINENUMBER 46 L1
ALOAD 0
GETFIELD net/minecraft/client/renderer/InventoryEffectRenderer.field_147045_u : Z
IFEQ L2
L3
LINENUMBER 48 L3
ALOAD 0
INVOKESPECIAL net/minecraft/client/renderer/InventoryEffectRenderer.func_147044_g ()V
L2
ILOAD 4
IFEQ L6
RETURN
L6
ALOAD 0
ILOAD 1
ILOAD 2
FLOAD 3
INVOKESPECIAL net/minecraft/client/gui/inventory/GuiContainer.drawScreen (IIF)V
LINENUMBER 50 L2
FRAME SAME
RETURN
L4
*/

AbstractInsnNode startNodeSuperCall =
findNext(currentMethod.instructions.getFirst(), matchOpcode(Opcodes.ALOAD));
// this cannot be InsnList, because it would prematurely take ownership of the removed
// instructions
AbstractInsnNode[] instToMove = new AbstractInsnNode[5];
InsnList superCallInsnList = new InsnList();
for (int i = 0; i < 5; ++i) {
instToMove[i] = start;
start = start.getNext();
superCallInsnList.add(startNodeSuperCall.clone(null));
startNodeSuperCall = startNodeSuperCall.getNext();
}

int ordinal = 0;
AbstractInsnNode drawScreenMethodeInsnNode = null;
AbstractInsnNode drawPotionEffectsNode = null;
for (AbstractInsnNode insnNode : currentMethod.instructions.toArray()) {
if (insnNode instanceof MethodInsnNode && insnNode.getOpcode() == Opcodes.INVOKESPECIAL) {
if (ordinal == 0) {
drawScreenMethodeInsnNode = insnNode;
ordinal++;
continue;
}
if (ordinal == 1) {
drawPotionEffectsNode = insnNode;
}
}
}

if (drawScreenMethodeInsnNode == null || drawPotionEffectsNode == null) {
log.info("Failed reordering InventoryEffectRenderer.drawScreen");
return;
}
for (int i = 0; i < 5; ++i) currentMethod.instructions.remove(instToMove[i]);

// And paste it 2 instructions below status effect rendering (after the label)
InsnList listMove = new InsnList();
for (AbstractInsnNode n : instToMove) listMove.add(n);
AbstractInsnNode inv =
findNext(currentMethod.instructions.getFirst(), matchOpcode(Opcodes.INVOKESPECIAL));
/*
* Injects before super call :
* boolean bookmarkPanelHidden = NEIClientConfig.isHidden();
* if (bookmarkPanelHidden) {
*/
LabelNode skipFirstIfLabel = new LabelNode();
InsnList headInjectionList = new InsnList();
headInjectionList.add(new MethodInsnNode(
Opcodes.INVOKESTATIC, NEIClientConfigClasspath, "isHidden", "()Z", false));
headInjectionList.add(new InsnNode(Opcodes.DUP));
headInjectionList.add(new VarInsnNode(Opcodes.ISTORE, 4));
headInjectionList.add(new JumpInsnNode(Opcodes.IFEQ, skipFirstIfLabel));
currentMethod.instructions.insert(currentMethod.instructions.getFirst(), headInjectionList);

/*
* Injects end of first if after the drawScreen super call
*/
currentMethod.instructions.insert(drawScreenMethodeInsnNode, skipFirstIfLabel);

/*
* Injects at the end of the method :
* if(bookmarkPanelHidden){
* return;
* }
* super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
*/
InsnList secondDrawScreenInsnList = new InsnList();
LabelNode skipSecondIfLabel = new LabelNode();
secondDrawScreenInsnList.add(new VarInsnNode(Opcodes.ILOAD, 4));
secondDrawScreenInsnList.add(new JumpInsnNode(Opcodes.IFEQ, skipSecondIfLabel));
secondDrawScreenInsnList.add(new InsnNode(Opcodes.RETURN));
secondDrawScreenInsnList.add(skipSecondIfLabel);
secondDrawScreenInsnList.add(superCallInsnList);
currentMethod.instructions.insert(drawPotionEffectsNode.getNext(), secondDrawScreenInsnList);

currentMethod.maxLocals = 5;
log.info("Reordering InventoryEffectRenderer.drawScreen");
currentMethod.instructions.insert(inv.getNext(), listMove);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ public LoadingConfig(File file) {
"tweaks",
"fixPotionEffectRender",
true,
"Move vanilla potion effect status rendering before everything else")
"Fix vanilla potion effects rendering above the NEI tooltips in the inventory")
.getBoolean();
installAnchorAlarm = config.get(
"tweaks", "installAnchorAlarm", true, "Wake up passive & personal anchors on player login")
Expand Down

0 comments on commit 98bff90

Please sign in to comment.