Added transformer to fix coolant cells
Closes #83. Added class transformer which adds check for GT's brand new HeatComponent interface
This commit is contained in:
parent
12fa856051
commit
9e9f9b283e
5 changed files with 131 additions and 17 deletions
17
src/main/java/gregtechmod/api/interfaces/IHeatComponent.java
Normal file
17
src/main/java/gregtechmod/api/interfaces/IHeatComponent.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package gregtechmod.api.interfaces;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Implementing this interface will mark item as IC2 reactor component which <u>stores</u> heat
|
||||
* Used to fix IC2 through ASM to not allow put back warm cells
|
||||
* @author TheDarkDnKTv
|
||||
*
|
||||
*/
|
||||
public interface IHeatComponent {
|
||||
|
||||
/**
|
||||
* @return amount of heat stored in stack
|
||||
*/
|
||||
int getHeatStored(ItemStack stack);
|
||||
}
|
|
@ -41,21 +41,19 @@ public class GT_CoolantCellIC_Item extends GT_CoolantCell_Item implements IReact
|
|||
public int alterHeat(IReactor aReactor, ItemStack aStack, int x, int y, int aHeat) {
|
||||
int tHeat = getHeatOfStack(aStack);
|
||||
|
||||
if (!aReactor.isFluidCooled() || aHeat > 0) {
|
||||
tHeat += aHeat;
|
||||
tHeat += aHeat;
|
||||
|
||||
if (tHeat > heatStorage) {
|
||||
aReactor.setItemAt(x, y, (ItemStack)null);
|
||||
aHeat = heatStorage - tHeat + 1;
|
||||
} else {
|
||||
if (tHeat < 0) {
|
||||
aHeat = tHeat;
|
||||
tHeat = 0;
|
||||
} else {
|
||||
aHeat = 0;
|
||||
}
|
||||
setHeatForStack(aStack, tHeat);
|
||||
}
|
||||
if (tHeat > heatStorage) {
|
||||
aReactor.setItemAt(x, y, (ItemStack)null);
|
||||
aHeat = heatStorage - tHeat + 1;
|
||||
} else {
|
||||
if (tHeat < 0) {
|
||||
aHeat = tHeat;
|
||||
tHeat = 0;
|
||||
} else {
|
||||
aHeat = 0;
|
||||
}
|
||||
setHeatForStack(aStack, tHeat);
|
||||
}
|
||||
|
||||
return aHeat;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package gregtechmod.api.items;
|
||||
|
||||
import gregtechmod.api.GregTech_API;
|
||||
import gregtechmod.api.interfaces.IHeatComponent;
|
||||
import gregtechmod.api.util.GT_Utility;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -8,7 +10,7 @@ import net.minecraft.client.resources.I18n;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class GT_CoolantCell_Item extends GT_Generic_Item {
|
||||
public class GT_CoolantCell_Item extends GT_Generic_Item implements IHeatComponent {
|
||||
protected int heatStorage;
|
||||
|
||||
public GT_CoolantCell_Item(String aUnlocalized, int aMaxStore) {
|
||||
|
@ -60,4 +62,13 @@ public class GT_CoolantCell_Item extends GT_Generic_Item {
|
|||
}
|
||||
return tNBT.getInteger("heat");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeatStored(ItemStack stack) {
|
||||
if (GT_Utility.isStackValid(stack)) {
|
||||
return getHeatOfStack(stack);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ public class GT_CoreMod implements IFMLLoadingPlugin {
|
|||
@Override
|
||||
public String[] getASMTransformerClass() {
|
||||
return new String[] {
|
||||
"gregtechmod.common.asm.EnergyNetTransformer"
|
||||
"gregtechmod.common.asm.EnergyNetTransformer",
|
||||
"gregtechmod.common.asm.IC2ReactorSlotTransformer"
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package gregtechmod.common.asm;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.LineNumberNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.TypeInsnNode;
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
|
||||
/**
|
||||
* @author TheDarkDnKTv
|
||||
*
|
||||
*/
|
||||
public class IC2ReactorSlotTransformer implements IClassTransformer {
|
||||
|
||||
private final static String TE_REACTOR = GT_CoreMod.getIC2CoreClass("block.reactor.tileentity.TileEntityNuclearReactorElectric");
|
||||
private final static String STACK_TYPE = FMLDeobfuscatingRemapper.INSTANCE.map("net/minecraft/item/ItemStack");
|
||||
|
||||
@Override
|
||||
public byte[] transform(String name, String transformedName, byte[] basicClass) {
|
||||
if (TE_REACTOR.equals(name)) {
|
||||
ClassReader reader = new ClassReader(basicClass);
|
||||
ClassNode clz = new ClassNode();
|
||||
reader.accept(clz, 0);
|
||||
|
||||
for (MethodNode method : clz.methods) {
|
||||
if (method.name.equals("isUsefulItem") && method.access == ACC_PUBLIC && method.desc.equals(String.format("(L%s;Z)Z", STACK_TYPE))) { // (Ladd;Z)Z
|
||||
GT_CoreMod.log.info("Transforming " + TE_REACTOR);
|
||||
try {
|
||||
for (int i = 0; i < method.instructions.size(); i++) {
|
||||
AbstractInsnNode ins = method.instructions.get(i);
|
||||
if (ins.getOpcode() == ALOAD && ins.getNext().getOpcode() == INVOKEVIRTUAL && ((MethodInsnNode)ins.getNext()).name.equals("getClass")) {
|
||||
ins = ins.getNext().getNext().getNext(); // IF_ACMPNE L5
|
||||
LabelNode next = ((JumpInsnNode) ins).label;
|
||||
LabelNode lb = new LabelNode(new Label());
|
||||
((JumpInsnNode) ins).label = lb;
|
||||
|
||||
InsnList list = new InsnList();
|
||||
{
|
||||
final String GT = "gregtechmod/api/interfaces/IHeatComponent";
|
||||
list.add(lb);
|
||||
list.add(new LineNumberNode(301, lb));
|
||||
list.add(new VarInsnNode(ALOAD, 3));
|
||||
list.add(new TypeInsnNode(INSTANCEOF, GT));
|
||||
list.add(new JumpInsnNode(IFEQ, next));
|
||||
list.add(new VarInsnNode(ALOAD, 3));
|
||||
list.add(new TypeInsnNode(CHECKCAST, GT));
|
||||
list.add(new VarInsnNode(ALOAD, 1));
|
||||
list.add(new MethodInsnNode(INVOKEINTERFACE, GT, "getHeatStored", String.format("(L%s;)I", STACK_TYPE), true));
|
||||
list.add(new JumpInsnNode(IFLE, next));
|
||||
list.add(new InsnNode(ICONST_0));
|
||||
list.add(new InsnNode(IRETURN));
|
||||
}
|
||||
|
||||
method.instructions.insertBefore(next, list);
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
clz.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoSuchMethodException("Not found entry signature in isUsefulItem");
|
||||
} catch (Throwable e) {
|
||||
GT_CoreMod.log.error("Error on transformation");
|
||||
GT_CoreMod.log.catching(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return basicClass;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue