use fluid in patterns

This commit is contained in:
lordIcocain committed 2025-05-19 03:22:44 +03:00
1 parent bc1f6adf9d
commit 60a89bf2f9
5 files changed
+92 -141

No files matched your search

@@ -1,5 +1,6 @@
package com.glodblock.github.common.tile;
import static appeng.util.Platform.writeStackNBT;
import static com.glodblock.github.loader.RecipeLoader.BUCKET;
import javax.annotation.Nonnull;
@@ -17,7 +18,8 @@ import net.minecraftforge.fluids.FluidStack;
import org.apache.commons.lang3.tuple.MutablePair;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.util.NameConst;
import com.glodblock.github.util.Util;
import appeng.api.AEApi;
@@ -53,6 +55,8 @@ import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkInvTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.item.AEItemStack;
import cpw.mods.fml.common.registry.GameRegistry;
public class TileFluidAutoFiller extends AENetworkInvTile
implements ICraftingProvider, IMEMonitorHandlerReceiver<IAEFluidStack>, IGridTickable {
@@ -60,7 +64,7 @@ public class TileFluidAutoFiller extends AENetworkInvTile
private final AppEngInternalInventory inventory = new AppEngInternalInventory(this, 1);
private final BaseActionSource source = new MachineSource(this);
private IItemList<IAEFluidStack> fluids = AEApi.instance().storage().createFluidList();
private final Item encodedPattern = AEApi.instance().definitions().items().encodedPattern().maybeItem().orNull();
private final Item encodedPattern = GameRegistry.findItem(FluidCraft.MODID, NameConst.ITEM_FLUID_ENCODED_PATTERN);
private IAEItemStack returnStack;
private boolean isPowered;
@@ -156,19 +160,21 @@ public class TileFluidAutoFiller extends AENetworkInvTile
MutablePair<Integer, ItemStack> filled = Util.FluidUtil
.fillStack(this.getContainerItem().copy(), new FluidStack(fluid, maxCapacity));
if (filled.right == null) continue;
ItemStack pattern = getPattern(this.getContainerItem(), filled.right);
ItemStack pattern = getPattern(
this.getContainerItem(),
filled.right,
fluidStack.copy().setStackSize(maxCapacity));
ICraftingPatternItem patter = (ICraftingPatternItem) pattern.getItem();
craftingTracker.addCraftingOption(this, patter.getPatternForItem(pattern, getWorldObj()));
}
}
private ItemStack getPattern(ItemStack emptyContainer, ItemStack filledContainer) {
private ItemStack getPattern(ItemStack emptyContainer, ItemStack filledContainer, IAEFluidStack ifs) {
NBTTagList in = new NBTTagList();
NBTTagList out = new NBTTagList();
in.appendTag(emptyContainer.writeToNBT(new NBTTagCompound()));
ItemStack fluidDrop = ItemFluidDrop.newStack(Util.FluidUtil.getFluidFromContainer(filledContainer));
in.appendTag(createItemTag(fluidDrop));
out.appendTag(filledContainer.writeToNBT(new NBTTagCompound()));
in.appendTag(writeStackNBT(AEItemStack.create(emptyContainer), new NBTTagCompound()));
in.appendTag(writeStackNBT(ifs, new NBTTagCompound()));
out.appendTag(writeStackNBT(AEItemStack.create(filledContainer), new NBTTagCompound()));
NBTTagCompound itemTag = new NBTTagCompound();
itemTag.setTag("in", in);
itemTag.setTag("out", out);
@@ -188,8 +194,7 @@ public class TileFluidAutoFiller extends AENetworkInvTile
@Override
public boolean pushPattern(ICraftingPatternDetails patternDetails, InventoryCrafting table) {
this.returnStack = AEApi.instance().storage()
.createItemStack(patternDetails.getCondensedOutputs()[0].getItemStack());
this.returnStack = (IAEItemStack) patternDetails.getCondensedOutputs()[0];
try {
this.getProxy().getTick().alertDevice(this.getProxy().getNode());
} catch (GridAccessException ignored) {
@@ -8,7 +8,6 @@ import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import com.glodblock.github.coremod.transform.CraftingTreeNodeTransformer;
import com.glodblock.github.coremod.transform.DualityInterfaceTransformer;
import com.glodblock.github.coremod.transform.ExternalStorageRegistryTransformer;
import com.glodblock.github.coremod.transform.GuiCraftingTransformer;
@@ -23,8 +22,6 @@ public class FCClassTransformer implements IClassTransformer {
public byte[] transform(String name, String transformedName, byte[] basicClass) {
ClassMapper tform;
switch (transformedName) {
case "appeng.crafting.CraftingTreeNode" -> tform = CraftingTreeNodeTransformer.INSTANCE;
case "appeng.helpers.DualityInterface" -> tform = DualityInterfaceTransformer.INSTANCE;
case "appeng.client.gui.implementations.GuiCraftingCPU", "appeng.client.gui.implementations.GuiCraftConfirm", "net.p455w0rd.wirelesscraftingterminal.client.gui.GuiCraftConfirm", "appeng.client.gui.widgets.GuiCraftingTree" -> tform = GuiCraftingTransformer.INSTANCE;
case "appeng.integration.modules.NEI" -> tform = NEITransformer.INSTANCE;
@@ -24,18 +24,6 @@ public class CoreModHooks {
return tile != null ? FluidConvertingInventoryAdaptor.wrap(tile, face) : null;
}
public static long getCraftingByteCost(IAEItemStack stack) {
return stack.getItem() instanceof ItemFluidDrop ? (long) Math.ceil(stack.getStackSize() / 1000D)
: stack.getStackSize();
}
public static long getFluidDropsByteCost(long totalBytes, long originByte, IAEItemStack stack) {
if (stack != null && stack.getItem() instanceof ItemFluidDrop) {
return (long) Math.ceil(originByte / 1000D) + totalBytes;
}
return originByte + totalBytes;
}
public static ItemStack displayFluid(IAEItemStack aeStack) {
if (aeStack.getItemStack() != null && aeStack.getItemStack().getItem() instanceof ItemFluidDrop) {
FluidStack fluid = ItemFluidDrop.getFluidStack(aeStack.getItemStack());
@@ -1,102 +0,0 @@
package com.glodblock.github.coremod.transform;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import com.glodblock.github.coremod.FCClassTransformer;
public class CraftingTreeNodeTransformer extends FCClassTransformer.ClassMapper {
public static final CraftingTreeNodeTransformer INSTANCE = new CraftingTreeNodeTransformer();
private CraftingTreeNodeTransformer() {
// NO-OP
}
@Override
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
return new TransformCraftingTreeNode(Opcodes.ASM5, downstream);
}
private static class TransformCraftingTreeNode extends ClassVisitor {
TransformCraftingTreeNode(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("request")) {
return new TransformRequest(api, super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
private static class TransformRequest extends MethodVisitor {
private boolean writingBytes = false;
private int cnt = 0;
TransformRequest(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (opcode == Opcodes.GETFIELD && owner.equals("appeng/crafting/CraftingTreeNode")
&& name.equals("bytes")) {
writingBytes = true;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
public void visitLineNumber(int line, Label start) {
writingBytes = false; // no write here
super.visitLineNumber(line, start);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (writingBytes && opcode == Opcodes.INVOKEINTERFACE
&& owner.equals("appeng/api/storage/data/IAEItemStack")
&& name.equals("getStackSize")) {
writingBytes = false;
cnt++;
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"getCraftingByteCost",
"(Lappeng/api/storage/data/IAEItemStack;)J",
false);
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
@Override
public void visitInsn(int opcode) {
if (writingBytes && cnt == 5 && opcode == Opcodes.LADD) {
super.visitVarInsn(Opcodes.ALOAD, 0);
super.visitFieldInsn(
Opcodes.GETFIELD,
"appeng/crafting/CraftingTreeNode",
"what",
"Lappeng/api/storage/data/IAEItemStack;");
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"getFluidDropsByteCost",
"(JJLappeng/api/storage/data/IAEItemStack;)J",
false);
writingBytes = false;
cnt++;
return;
}
super.visitInsn(opcode);
}
}
}
@@ -1,5 +1,8 @@
package com.glodblock.github.util;
import static appeng.util.Platform.readStackNBT;
import static appeng.util.Platform.stackConvert;
import java.util.Arrays;
import java.util.Objects;
@@ -14,7 +17,9 @@ import net.minecraftforge.common.util.Constants;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.helpers.PatternHelper;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<FluidPatternDetails> {
@@ -22,6 +27,7 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
private final ItemStack patternStack;
private IAEItemStack patternStackAe;
private IAEItemStack[] inputs = null, inputsCond = null, outputs = null, outputsCond = null;
private IAEStack<?>[] aeInputs = null, aeInputsCond = null, aeOutputs = null, aeOutputsCond = null;
private int priority = 0;
private int combine = 0;
private int beSubstitute = 0;
@@ -83,18 +89,42 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
return checkInitialized(inputs);
}
@Override
public IAEStack<?>[] getAEInputs() {
return checkInitialized(aeInputs);
}
@Override
public IAEItemStack[] getCondensedInputs() {
return checkInitialized(inputsCond);
}
public boolean setInputs(IAEItemStack[] inputs) {
IAEItemStack[] condensed = condenseStacks(inputs);
@Override
public IAEStack<?>[] getCondensedAEInputs() {
return checkInitialized(aeInputsCond);
}
public boolean setInputs(IAEStack<?>[] inputs) {
IAEStack<?>[] condensed = condenseAEStacks(inputs);
if (condensed.length == 0) {
return false;
}
this.inputs = inputs;
this.inputsCond = condensed;
this.aeInputs = inputs;
this.aeInputsCond = condensed;
IAEItemStack[] legacy = new IAEItemStack[inputs.length];
for (int i = 0; i < inputs.length; i++) {
if (inputs[i] != null) {
if (inputs[i].isItem()) {
legacy[i] = (IAEItemStack) inputs[i];
} else {
legacy[i] = stackConvert(inputs[i]);
}
}
}
this.inputs = legacy;
this.inputsCond = condenseStacks(legacy);
return true;
}
@@ -103,18 +133,42 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
return checkInitialized(outputs);
}
@Override
public IAEStack<?>[] getAEOutputs() {
return checkInitialized(aeOutputs);
}
@Override
public IAEItemStack[] getCondensedOutputs() {
return checkInitialized(outputsCond);
}
public boolean setOutputs(IAEItemStack[] outputs) {
IAEItemStack[] condensed = condenseStacks(outputs);
@Override
public IAEStack<?>[] getCondensedAEOutputs() {
return checkInitialized(aeOutputsCond);
}
public boolean setOutputs(IAEStack<?>[] outputs) {
IAEStack<?>[] condensed = condenseAEStacks(outputs);
if (condensed.length == 0) {
return false;
}
this.outputs = Arrays.stream(outputs).filter(Objects::nonNull).toArray(IAEItemStack[]::new);
this.outputsCond = condensed;
this.aeOutputs = Arrays.stream(outputs).filter(Objects::nonNull).toArray(IAEStack<?>[]::new);
this.aeOutputsCond = condensed;
IAEItemStack[] legacy = new IAEItemStack[outputs.length];
for (int i = 0; i < outputs.length; i++) {
if (outputs[i] != null) {
if (outputs[i].isItem()) {
legacy[i] = (IAEItemStack) outputs[i];
} else {
legacy[i] = stackConvert(outputs[i]);
}
}
}
this.outputs = legacy;
this.outputsCond = condenseStacks(legacy);
return true;
}
@@ -122,11 +176,20 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
return PatternHelper.convertToCondensedList(stacks);
}
private static IAEStack<?>[] condenseAEStacks(IAEStack<?>[] stacks) {
return PatternHelper.convertToCondensedAEList(stacks);
}
@Override
public ItemStack getOutput(InventoryCrafting craftingInv, World world) {
throw new IllegalStateException("Not a crafting recipe!");
}
@Override
public boolean isValidItemForSlot(int slotIndex, IAEStack<?> stack, World world) {
throw new IllegalStateException("Not a crafting recipe!");
}
@Override
public boolean isValidItemForSlot(int slotIndex, ItemStack itemStack, World world) {
throw new IllegalStateException("Not a crafting recipe!");
@@ -171,12 +234,12 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
return patternStack;
}
public static NBTTagList writeStackArray(IAEItemStack[] stacks) {
public static NBTTagList writeStackArray(IAEStack<?>[] stacks) {
NBTTagList listTag = new NBTTagList();
for (IAEItemStack stack : stacks) {
for (IAEStack<?> stack : stacks) {
// see note at top of class
NBTTagCompound stackTag = new NBTTagCompound();
if (stack != null) stack.writeToNBT(stackTag);
Platform.writeStackNBT(stack, stackTag);
listTag.appendTag(stackTag);
}
return listTag;
@@ -196,11 +259,11 @@ public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<
&& setOutputs(readStackArray(tag.getTagList("out", Constants.NBT.TAG_COMPOUND)));
}
public static IAEItemStack[] readStackArray(NBTTagList listTag) {
public static IAEStack<?>[] readStackArray(NBTTagList listTag) {
// see note at top of class
IAEItemStack[] stacks = new IAEItemStack[listTag.tagCount()];
IAEStack<?>[] stacks = new IAEStack<?>[listTag.tagCount()];
for (int i = 0; i < stacks.length; i++) {
stacks[i] = AEItemStack.loadItemStackFromNBT(listTag.getCompoundTagAt(i));
stacks[i] = readStackNBT(listTag.getCompoundTagAt(i), true);
}
return stacks;
}