mirror of
https://github.com/GTNewHorizons/AE2FluidCraft-Rework.git
synced 2026-11-12 00:07:29 +00:00
Compatibility with ae native fluid (#293)
Co-authored-by: lordIcocain <62835225+lordIcocain@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: Kogepan229 <kogepan25629@gmail.com>
This commit is contained in:
17 files changed
+228
-1334
No files matched your search
+74
-47
@@ -1,5 +1,7 @@
|
||||
package com.glodblock.github.client.gui.container.base;
|
||||
|
||||
import static appeng.util.Platform.writeStackNBT;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -25,13 +27,12 @@ import com.glodblock.github.common.item.ItemFluidEncodedPattern;
|
||||
import com.glodblock.github.common.item.ItemFluidPacket;
|
||||
import com.glodblock.github.inventory.IPatternConsumer;
|
||||
import com.glodblock.github.inventory.item.IItemPatternTerminal;
|
||||
import com.glodblock.github.loader.ItemAndBlockHolder;
|
||||
import com.glodblock.github.util.FluidPatternDetails;
|
||||
import com.glodblock.github.util.Util;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.implementations.ICraftingPatternItem;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
@@ -43,11 +44,11 @@ import appeng.container.slot.SlotPatternTerm;
|
||||
import appeng.container.slot.SlotRestrictedInput;
|
||||
import appeng.helpers.IContainerCraftingPacket;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.items.misc.ItemEncodedPattern;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.inventory.IAEAppEngInventory;
|
||||
import appeng.tile.inventory.InvOperation;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEFluidStack;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
@@ -172,7 +173,7 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
ItemStack is = clickSlot.getStack();
|
||||
if (is != null && !patternSlotOUT.getHasStack()
|
||||
&& is.stackSize == 1
|
||||
&& (is.getItem() instanceof ItemFluidEncodedPattern || is.getItem() instanceof ItemEncodedPattern)) {
|
||||
&& is.getItem() instanceof ICraftingPatternItem) {
|
||||
ItemStack output = is.copy();
|
||||
patternSlotOUT.putStack(output);
|
||||
p.inventory.setInventorySlotContents(clickSlot.getSlotIndex(), null);
|
||||
@@ -243,20 +244,6 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
return object > 0;
|
||||
}
|
||||
|
||||
protected boolean checkHasFluidPattern() {
|
||||
if (this.craftingMode) {
|
||||
return false;
|
||||
}
|
||||
boolean hasFluid = containsFluid(this.craftingSlots);
|
||||
boolean search = nonNullSlot(this.craftingSlots);
|
||||
if (!search) { // search=false -> inputs were empty
|
||||
return false;
|
||||
}
|
||||
hasFluid |= containsFluid(this.outputSlots);
|
||||
search = nonNullSlot(this.outputSlots);
|
||||
return hasFluid && search; // search=false -> outputs were empty
|
||||
}
|
||||
|
||||
protected ItemStack stampAuthor(ItemStack patternStack) {
|
||||
if (patternStack.stackTagCompound == null) {
|
||||
patternStack.stackTagCompound = new NBTTagCompound();
|
||||
@@ -266,13 +253,52 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
}
|
||||
|
||||
protected void encodeFluidPattern() {
|
||||
ItemStack patternStack = new ItemStack(ItemAndBlockHolder.PATTERN);
|
||||
FluidPatternDetails pattern = new FluidPatternDetails(patternStack);
|
||||
pattern.setInputs(collectInventory(this.craftingSlots));
|
||||
pattern.setOutputs(collectInventory(this.outputSlots));
|
||||
pattern.setCanBeSubstitute(this.beSubstitute ? 1 : 0);
|
||||
pattern.setCombine(this.combine ? 1 : 0);
|
||||
patternSlotOUT.putStack(stampAuthor(pattern.writeToStack()));
|
||||
ItemStack patternStack = AEApi.instance().definitions().items().encodedUltimatePattern().maybeStack(1).orNull();
|
||||
if (patternStack != null) {
|
||||
final NBTTagCompound encodedValue = new NBTTagCompound();
|
||||
|
||||
final ItemStack[] in = this.getInputs();
|
||||
final ItemStack[] out = this.getOutputs();
|
||||
|
||||
final NBTTagList tagIn = new NBTTagList();
|
||||
final NBTTagList tagOut = new NBTTagList();
|
||||
|
||||
for (final ItemStack i : in) {
|
||||
if (i != null) {
|
||||
if (i.getItem() instanceof ItemFluidPacket) {
|
||||
tagIn.appendTag(
|
||||
writeStackNBT(
|
||||
AEFluidStack.create(ItemFluidPacket.getFluidStack(i)),
|
||||
new NBTTagCompound(),
|
||||
true));
|
||||
} else {
|
||||
tagIn.appendTag(writeStackNBT(AEItemStack.create(i), new NBTTagCompound(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final ItemStack i : out) {
|
||||
if (i != null) {
|
||||
if (i.getItem() instanceof ItemFluidPacket) {
|
||||
tagOut.appendTag(
|
||||
writeStackNBT(
|
||||
AEFluidStack.create(ItemFluidPacket.getFluidStack(i)),
|
||||
new NBTTagCompound(),
|
||||
true));
|
||||
} else {
|
||||
tagOut.appendTag(writeStackNBT(AEItemStack.create(i), new NBTTagCompound(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encodedValue.setTag("in", tagIn);
|
||||
encodedValue.setTag("out", tagOut);
|
||||
encodedValue.setBoolean("substitute", substitute);
|
||||
encodedValue.setBoolean("beSubstitute", beSubstitute);
|
||||
encodedValue.setString("author", this.getPlayerInv().player.getCommandSenderName());
|
||||
patternStack.setTagCompound(encodedValue);
|
||||
patternSlotOUT.putStack(patternStack);
|
||||
}
|
||||
}
|
||||
|
||||
protected static IAEItemStack[] collectInventory(Slot[] slots) {
|
||||
@@ -369,25 +395,27 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
}
|
||||
|
||||
public void encode() {
|
||||
fillPattern();
|
||||
if (!checkHasFluidPattern()) {
|
||||
encodeItemPattern();
|
||||
return;
|
||||
}
|
||||
ItemStack stack = this.patternSlotOUT.getStack();
|
||||
if (stack == null) {
|
||||
stack = this.patternSlotIN.getStack();
|
||||
if (notPattern(stack)) {
|
||||
if (getInputs() != null && getOutputs() != null) {
|
||||
fillPattern();
|
||||
if (isCraftingMode()) {
|
||||
encodeItemPattern();
|
||||
return;
|
||||
}
|
||||
if (stack.stackSize == 1) {
|
||||
this.patternSlotIN.putStack(null);
|
||||
} else {
|
||||
stack.stackSize--;
|
||||
ItemStack stack = this.patternSlotOUT.getStack();
|
||||
if (stack == null) {
|
||||
stack = this.patternSlotIN.getStack();
|
||||
if (notPattern(stack)) {
|
||||
return;
|
||||
}
|
||||
if (stack.stackSize == 1) {
|
||||
this.patternSlotIN.putStack(null);
|
||||
} else {
|
||||
stack.stackSize--;
|
||||
}
|
||||
encodeFluidPattern();
|
||||
} else if (!notPattern(stack)) {
|
||||
encodeFluidPattern();
|
||||
}
|
||||
encodeFluidPattern();
|
||||
} else if (!notPattern(stack)) {
|
||||
encodeFluidPattern();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,10 +424,6 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
final ItemStack[] in = this.getInputs();
|
||||
final ItemStack[] out = this.getOutputs();
|
||||
|
||||
// if there is no input, this would be silly.
|
||||
if (in == null || out == null) {
|
||||
return;
|
||||
}
|
||||
// first check the output slots, should either be null, or a pattern
|
||||
if (output != null && this.notPattern(output)) {
|
||||
return;
|
||||
@@ -487,7 +511,10 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
boolean isPattern = definitions.items().encodedPattern().isSameAs(output);
|
||||
isPattern |= definitions.materials().blankPattern().isSameAs(output);
|
||||
|
||||
return !isPattern;
|
||||
boolean isUltimatePattern = definitions.items().encodedUltimatePattern().isSameAs(output);
|
||||
isUltimatePattern |= definitions.materials().blankPattern().isSameAs(output);
|
||||
|
||||
return !isPattern && !isUltimatePattern;
|
||||
}
|
||||
|
||||
protected NBTBase createItemTag(final ItemStack i) {
|
||||
@@ -569,7 +596,7 @@ public abstract class FCContainerEncodeTerminal extends ContainerItemMonitor
|
||||
for (Slot s : slots) {
|
||||
ItemStack st = s.getStack();
|
||||
if (st == null) continue;
|
||||
final int count;
|
||||
final long count;
|
||||
if (st.getItem() instanceof ItemFluidPacket) {
|
||||
count = ItemFluidPacket.getFluidAmount(st);
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.glodblock.github.common.item;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -23,6 +22,7 @@ import com.glodblock.github.util.NameConst;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.item.AEFluidStack;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@@ -40,11 +40,34 @@ public class ItemFluidPacket extends FCBaseItem {
|
||||
if (stack == null || !stack.hasTagCompound()) {
|
||||
return null;
|
||||
}
|
||||
FluidStack fluid = FluidStack
|
||||
.loadFluidStackFromNBT(Objects.requireNonNull(stack.getTagCompound()).getCompoundTag("FluidStack"));
|
||||
NBTTagCompound tag = stack.getTagCompound().getCompoundTag("FluidStack");
|
||||
FluidStack fluid = FluidStack.loadFluidStackFromNBT(tag);
|
||||
if (fluid != null && tag.getLong("Amount") > Integer.MAX_VALUE) fluid.amount = Integer.MAX_VALUE;
|
||||
return (fluid != null && fluid.amount > 0) ? fluid : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FluidStack getFluidStack(@Nullable IAEItemStack stack) {
|
||||
return stack != null ? getFluidStack(stack.getItemStack()) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IAEFluidStack getFluidAEStack(ItemStack stack) {
|
||||
if (stack != null && stack.hasTagCompound()) {
|
||||
NBTTagCompound tag = stack.getTagCompound().getCompoundTag("FluidStack");
|
||||
IAEFluidStack ifs = AEFluidStack.create(FluidStack.loadFluidStackFromNBT(tag));
|
||||
if (ifs != null && tag.hasKey("Amount")) ifs.setStackSize(tag.getLong("Amount"));
|
||||
return ifs;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IAEFluidStack getFluidAEStack(@Nullable IAEItemStack stack) {
|
||||
return stack != null ? getFluidAEStack(stack.getItemStack()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName(ItemStack stack) {
|
||||
FluidStack fluid = getFluidStack(stack);
|
||||
@@ -83,25 +106,20 @@ public class ItemFluidPacket extends FCBaseItem {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FluidStack getFluidStack(@Nullable IAEItemStack stack) {
|
||||
return stack != null ? getFluidStack(stack.getItemStack()) : null;
|
||||
}
|
||||
|
||||
public static void setFluidAmount(ItemStack stack, int amount) {
|
||||
public static void setFluidAmount(ItemStack stack, long amount) {
|
||||
if (stack == null || !stack.hasTagCompound()
|
||||
|| !stack.getTagCompound().hasKey("FluidStack", Constants.NBT.TAG_COMPOUND)) {
|
||||
return;
|
||||
}
|
||||
stack.getTagCompound().getCompoundTag("FluidStack").setInteger("Amount", amount);
|
||||
stack.getTagCompound().getCompoundTag("FluidStack").setLong("Amount", amount);
|
||||
}
|
||||
|
||||
public static int getFluidAmount(ItemStack stack) {
|
||||
public static long getFluidAmount(ItemStack stack) {
|
||||
if (stack == null || !stack.hasTagCompound()) {
|
||||
return 0;
|
||||
}
|
||||
// Default to 0 if no tag exists
|
||||
return stack.getTagCompound().getCompoundTag("FluidStack").getInteger("Amount");
|
||||
return stack.getTagCompound().getCompoundTag("FluidStack").getLong("Amount");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -120,10 +138,22 @@ public class ItemFluidPacket extends FCBaseItem {
|
||||
|
||||
@Nullable
|
||||
public static ItemStack newStack(@Nullable IAEFluidStack fluid) {
|
||||
if (fluid == null || fluid.getStackSize() == 0) {
|
||||
return null;
|
||||
if (fluid != null && fluid.getStackSize() > 0) {
|
||||
ItemStack stack = new ItemStack(ItemAndBlockHolder.PACKET);
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
NBTTagCompound fluidTag = new NBTTagCompound();
|
||||
fluid.getFluidStack().writeToNBT(fluidTag);
|
||||
fluidTag.setLong("Amount", fluid.getStackSize());
|
||||
tag.setTag("FluidStack", fluidTag);
|
||||
stack.setTagCompound(tag);
|
||||
return stack;
|
||||
}
|
||||
return newStack(fluid.getFluidStack());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IAEItemStack newAeStack(@Nullable FluidStack fluid) {
|
||||
return AEItemStack.create(newStack(fluid));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -143,11 +173,6 @@ public class ItemFluidPacket extends FCBaseItem {
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IAEItemStack newAeStack(@Nullable FluidStack fluid) {
|
||||
return AEItemStack.create(newStack(fluid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpriteNumber() {
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.glodblock.github.common.parts;
|
||||
|
||||
import static appeng.util.Platform.convertStack;
|
||||
import static appeng.util.Platform.stackConvert;
|
||||
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -11,11 +14,11 @@ import com.glodblock.github.client.textures.FCPartsTexture;
|
||||
import com.glodblock.github.common.item.ItemFluidDrop;
|
||||
import com.glodblock.github.common.item.ItemFluidPacket;
|
||||
import com.glodblock.github.common.parts.base.FCSharedFluidBus;
|
||||
import com.glodblock.github.inventory.FluidConvertingInventoryAdaptor;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.InsertionMode;
|
||||
import appeng.api.config.PowerMultiplier;
|
||||
import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.SchedulingMode;
|
||||
@@ -43,7 +46,6 @@ import appeng.me.GridAccessException;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEFluidStack;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
@@ -269,7 +271,7 @@ public class PartFluidExportBus extends FCSharedFluidBus implements ICraftingReq
|
||||
}
|
||||
|
||||
protected InventoryAdaptor getHandler(TileEntity target) {
|
||||
return target != null ? FluidConvertingInventoryAdaptor.wrap(target, this.getSide().getOpposite()) : null;
|
||||
return target != null ? InventoryAdaptor.getAdaptor(target, getSide().getOpposite()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,17 +284,15 @@ public class PartFluidExportBus extends FCSharedFluidBus implements ICraftingReq
|
||||
final double power = Math.ceil(items.getStackSize() / 1000D);
|
||||
|
||||
if (energy.extractAEPower(power, mode, PowerMultiplier.CONFIG) > power - 0.01) {
|
||||
ItemStack inputStack = items.getItemStack();
|
||||
|
||||
ItemStack remaining;
|
||||
IAEItemStack remaining;
|
||||
|
||||
if (mode == Actionable.SIMULATE) {
|
||||
remaining = d.simulateAdd(inputStack);
|
||||
remaining = stackConvert(d.simulateAddStack(convertStack(items), InsertionMode.DEFAULT));
|
||||
} else {
|
||||
remaining = d.addItems(inputStack);
|
||||
remaining = stackConvert(d.addStack(convertStack(items), InsertionMode.DEFAULT));
|
||||
}
|
||||
|
||||
return AEItemStack.create(remaining);
|
||||
return remaining;
|
||||
}
|
||||
}
|
||||
} catch (final GridAccessException e) {
|
||||
|
||||
@@ -53,6 +53,7 @@ import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IStorageMonitorable;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.helpers.DualityInterface;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
@@ -173,10 +174,13 @@ public class PartFluidP2PInterface extends PartP2PTunnelStatic<PartFluidP2PInter
|
||||
for (PartFluidP2PInterface p2p : getOutputs()) p2p.duality.addDrops(drops);
|
||||
} catch (GridAccessException ignored) {}
|
||||
} else {
|
||||
if (this.getWaitingToSend() != null) {
|
||||
for (final ItemStack is : this.getWaitingToSend()) {
|
||||
if (is != null) {
|
||||
drops.add(is);
|
||||
List<IAEStack<?>> waitingList = this.getWaitingToSend();
|
||||
if (waitingList != null) {
|
||||
for (final IAEStack<?> as : waitingList) {
|
||||
if (as instanceof IAEItemStack ais) {
|
||||
drops.add(ais.getItemStack());
|
||||
} else if (as instanceof IAEFluidStack afs) {
|
||||
drops.add(ItemFluidPacket.newStack(afs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -224,7 +224,6 @@ public class TileFluidInterface extends TileInterface implements IDualHost {
|
||||
@Override
|
||||
public void getDrops(World w, int x, int y, int z, List<ItemStack> drops) {
|
||||
this.fluidDuality.addDrops(drops);
|
||||
this.fluidDuality.convertDrops(drops, this.getInterfaceDuality().getWaitingToSend());
|
||||
super.getDrops(w, x, y, z, drops);
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,6 @@ import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import com.glodblock.github.coremod.transform.CraftingCpuTransformer;
|
||||
import com.glodblock.github.coremod.transform.CraftingGridCacheTransformer;
|
||||
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;
|
||||
import com.glodblock.github.coremod.transform.NEITransformer;
|
||||
@@ -25,10 +21,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.me.cache.CraftingGridCache" -> tform = CraftingGridCacheTransformer.INSTANCE;
|
||||
case "appeng.me.cluster.implementations.CraftingCPUCluster" -> tform = CraftingCpuTransformer.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;
|
||||
case "appeng.core.features.registries.ExternalStorageRegistry" -> tform = ExternalStorageRegistryTransformer.INSTANCE;
|
||||
|
||||
@@ -1,87 +1,18 @@
|
||||
package com.glodblock.github.coremod.hooker;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import com.glodblock.github.client.gui.GuiFluidCraftConfirm;
|
||||
import com.glodblock.github.common.item.ItemFluidDrop;
|
||||
import com.glodblock.github.common.item.ItemFluidPacket;
|
||||
import com.glodblock.github.inventory.CraftingGridCacheFluidInventoryProxyCell;
|
||||
import com.glodblock.github.inventory.FluidConvertingInventoryAdaptor;
|
||||
import com.glodblock.github.inventory.FluidConvertingInventoryCrafting;
|
||||
import com.glodblock.github.loader.ItemAndBlockHolder;
|
||||
import com.glodblock.github.util.Ae2Reflect;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.security.MachineSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.StorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.client.gui.IGuiTooltipHandler;
|
||||
import appeng.crafting.MECraftingInventory;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
|
||||
public class CoreModHooks {
|
||||
|
||||
public static InventoryCrafting wrapCraftingBuffer(InventoryCrafting inv) {
|
||||
return new FluidConvertingInventoryCrafting(
|
||||
inv.eventHandler,
|
||||
inv.inventoryWidth,
|
||||
inv.getSizeInventory() / inv.inventoryWidth);
|
||||
}
|
||||
|
||||
public static IAEItemStack wrapFluidPacketStack(IAEItemStack stack) {
|
||||
if (stack.getItem() == ItemAndBlockHolder.PACKET) {
|
||||
IAEItemStack dropStack = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stack.getItemStack()));
|
||||
if (dropStack != null) {
|
||||
return dropStack;
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static ItemStack removeFluidPackets(InventoryCrafting inv, int index) {
|
||||
ItemStack stack = inv.getStackInSlot(index);
|
||||
if (stack != null && stack.getItem() instanceof ItemFluidPacket) {
|
||||
FluidStack fluid = ItemFluidPacket.getFluidStack(stack);
|
||||
return ItemFluidDrop.newStack(fluid);
|
||||
} else {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InventoryAdaptor wrapInventory(@Nullable TileEntity tile, ForgeDirection face) {
|
||||
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());
|
||||
@@ -89,61 +20,6 @@ public class CoreModHooks {
|
||||
} else return aeStack.getItemStack();
|
||||
}
|
||||
|
||||
public static long getFluidSize(IAEItemStack aeStack) {
|
||||
if (aeStack.getItemStack() != null && aeStack.getItemStack().getItem() instanceof ItemFluidDrop) {
|
||||
return (long) Math.max(aeStack.getStackSize() / 1000D, 1);
|
||||
} else return aeStack.getStackSize();
|
||||
}
|
||||
|
||||
public static List<IMEInventoryHandler<?>> craftingGridCacheGetCellArray(final CraftingGridCache instance,
|
||||
final StorageChannel channel) {
|
||||
// Equivalent to original function, but using the proxy for fluid channel
|
||||
return channel == StorageChannel.ITEMS ? Arrays.asList(instance)
|
||||
: Arrays.asList(new CraftingGridCacheFluidInventoryProxyCell(instance));
|
||||
}
|
||||
|
||||
public static void storeFluidItem(CraftingCPUCluster instance) {
|
||||
final IGrid g = instance.getGrid();
|
||||
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final IStorageGrid sg = g.getCache(IStorageGrid.class);
|
||||
final IMEInventory<IAEItemStack> ii = sg.getItemInventory();
|
||||
final IMEInventory<IAEFluidStack> jj = sg.getFluidInventory();
|
||||
final MECraftingInventory inventory = (MECraftingInventory) instance.getInventory();
|
||||
|
||||
for (IAEItemStack is : inventory.getItemList()) {
|
||||
is = inventory.extractItems(is.copy(), Actionable.MODULATE, instance.getActionSource());
|
||||
|
||||
if (is != null) {
|
||||
Ae2Reflect.postCPUChange(instance, is, (MachineSource) instance.getActionSource());
|
||||
if (is.getItem() instanceof ItemFluidDrop) {
|
||||
IAEFluidStack fluidDrop = ItemFluidDrop.getAeFluidStack(is);
|
||||
fluidDrop = jj.injectItems(fluidDrop, Actionable.MODULATE, instance.getActionSource());
|
||||
if (fluidDrop == null) {
|
||||
is = null;
|
||||
} else {
|
||||
is.setStackSize(fluidDrop.getStackSize());
|
||||
}
|
||||
} else {
|
||||
is = ii.injectItems(is, Actionable.MODULATE, instance.getActionSource());
|
||||
}
|
||||
}
|
||||
|
||||
if (is != null) {
|
||||
inventory.injectItems(is, Actionable.MODULATE, instance.getActionSource());
|
||||
}
|
||||
}
|
||||
|
||||
if (inventory.getItemList().isEmpty()) {
|
||||
Ae2Reflect.setCPUInventory(instance, new MECraftingInventory());
|
||||
}
|
||||
|
||||
instance.markDirty();;
|
||||
}
|
||||
|
||||
public static ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) {
|
||||
if (gui instanceof IGuiTooltipHandler guiTooltipHandler) {
|
||||
return guiTooltipHandler.getHoveredStack();
|
||||
|
||||
@@ -1,142 +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 CraftingCpuTransformer extends FCClassTransformer.ClassMapper {
|
||||
|
||||
public static final CraftingCpuTransformer INSTANCE = new CraftingCpuTransformer();
|
||||
|
||||
private CraftingCpuTransformer() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
|
||||
return new TransformCraftingCPUCluster(Opcodes.ASM5, downstream);
|
||||
}
|
||||
|
||||
private static class TransformCraftingCPUCluster extends ClassVisitor {
|
||||
|
||||
TransformCraftingCPUCluster(int api, ClassVisitor cv) {
|
||||
super(api, cv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
if (name.equals("executeCrafting")) {
|
||||
return new TransformExecuteCrafting(api, super.visitMethod(access, name, desc, signature, exceptions));
|
||||
} else if (name.equals("cancel")) {
|
||||
return new TransformStoreItems(api, super.visitMethod(access, name, desc, signature, exceptions));
|
||||
}
|
||||
return super.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TransformExecuteCrafting extends MethodVisitor {
|
||||
|
||||
private boolean gotInventory = false;
|
||||
private int reach_stack = 0;
|
||||
|
||||
TransformExecuteCrafting(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/me/cluster/implementations/CraftingCPUCluster")
|
||||
&& name.equals("inventory")) {
|
||||
gotInventory = true;
|
||||
}
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLineNumber(int line, Label start) {
|
||||
gotInventory = false;
|
||||
super.visitLineNumber(line, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJumpInsn(int opcode, Label label) {
|
||||
if (opcode == Opcodes.IFNULL && reach_stack == 0) {
|
||||
reach_stack = 1;
|
||||
}
|
||||
super.visitJumpInsn(opcode, label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
||||
if (reach_stack == 1) {
|
||||
if (opcode == Opcodes.INVOKEINTERFACE && owner.equals("appeng/api/storage/data/IAEItemStack")
|
||||
&& name.equals("getStackSize")) {
|
||||
reach_stack = 2;
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"getFluidSize",
|
||||
"(Lappeng/api/storage/data/IAEItemStack;)J",
|
||||
false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("net/minecraft/inventory/InventoryCrafting")
|
||||
&& (name.equals("getStackInSlot") || name.equals("func_70301_a"))) {
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"removeFluidPackets",
|
||||
"(Lnet/minecraft/inventory/InventoryCrafting;I)Lnet/minecraft/item/ItemStack;",
|
||||
false);
|
||||
return;
|
||||
}
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
if (gotInventory) {
|
||||
if (opcode == Opcodes.INVOKESTATIC && owner.equals("appeng/util/item/AEItemStack")
|
||||
&& name.equals("create")) {
|
||||
gotInventory = false;
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"wrapFluidPacketStack",
|
||||
"(Lappeng/api/storage/data/IAEItemStack;)Lappeng/api/storage/data/IAEItemStack;",
|
||||
false);
|
||||
}
|
||||
} else if (opcode == Opcodes.INVOKESPECIAL && owner.equals("net/minecraft/inventory/InventoryCrafting")
|
||||
&& name.equals("<init>")) {
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"wrapCraftingBuffer",
|
||||
"(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/inventory/InventoryCrafting;",
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TransformStoreItems extends MethodVisitor {
|
||||
|
||||
TransformStoreItems(int api, MethodVisitor mv) {
|
||||
super(api, mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
||||
if (opcode == Opcodes.INVOKESPECIAL && owner.equals("appeng/me/cluster/implementations/CraftingCPUCluster")
|
||||
&& name.equals("storeItems")) {
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"storeFluidItem",
|
||||
"(Lappeng/me/cluster/implementations/CraftingCPUCluster;)V",
|
||||
false);
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package com.glodblock.github.coremod.transform;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import com.glodblock.github.coremod.FCClassTransformer;
|
||||
|
||||
public class CraftingGridCacheTransformer extends FCClassTransformer.ClassMapper {
|
||||
|
||||
public static final CraftingGridCacheTransformer INSTANCE = new CraftingGridCacheTransformer();
|
||||
|
||||
private CraftingGridCacheTransformer() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
|
||||
return new CraftingGridCacheTransformer.TransformCraftingGridCache(Opcodes.ASM5, downstream);
|
||||
}
|
||||
|
||||
private static class TransformCraftingGridCache extends ClassVisitor {
|
||||
|
||||
TransformCraftingGridCache(int api, ClassVisitor cv) {
|
||||
super(api, cv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
if (name.equals("getCellArray")) {
|
||||
return new CraftingGridCacheTransformer.ReplaceGetCellArray(
|
||||
api,
|
||||
super.visitMethod(access, name, desc, signature, exceptions));
|
||||
}
|
||||
return super.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReplaceGetCellArray extends MethodVisitor {
|
||||
|
||||
private final MethodVisitor target;
|
||||
|
||||
ReplaceGetCellArray(int api, MethodVisitor mv) {
|
||||
// Original method is replaced
|
||||
super(api, null);
|
||||
target = mv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCode() {
|
||||
target.visitCode();
|
||||
// Equivalent to
|
||||
// return CoreModHooks::craftingGridCacheGetCellArray(this, channel);
|
||||
target.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
target.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
target.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"craftingGridCacheGetCellArray",
|
||||
"(Lappeng/me/cache/CraftingGridCache;Lappeng/api/storage/StorageChannel;)Ljava/util/List;",
|
||||
false);
|
||||
target.visitInsn(Opcodes.ARETURN);
|
||||
target.visitMaxs(2, 3);
|
||||
target.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
-102
@@ -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,60 +0,0 @@
|
||||
package com.glodblock.github.coremod.transform;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import com.glodblock.github.coremod.FCClassTransformer;
|
||||
|
||||
public class DualityInterfaceTransformer extends FCClassTransformer.ClassMapper {
|
||||
|
||||
public static final DualityInterfaceTransformer INSTANCE = new DualityInterfaceTransformer();
|
||||
|
||||
private DualityInterfaceTransformer() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
|
||||
return new TransformDualityInterface(Opcodes.ASM5, downstream);
|
||||
}
|
||||
|
||||
private static class TransformDualityInterface extends ClassVisitor {
|
||||
|
||||
TransformDualityInterface(int api, ClassVisitor cv) {
|
||||
super(api, cv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
return switch (name) {
|
||||
case "pushItemsOut", "pushPattern", "isBusy" -> new TransformInvAdaptorCalls(
|
||||
api,
|
||||
super.visitMethod(access, name, desc, signature, exceptions));
|
||||
default -> super.visitMethod(access, name, desc, signature, exceptions);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class TransformInvAdaptorCalls extends MethodVisitor {
|
||||
|
||||
private TransformInvAdaptorCalls(int api, MethodVisitor mv) {
|
||||
super(api, mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
||||
if (opcode == Opcodes.INVOKESTATIC && owner.equals("appeng/util/InventoryAdaptor")
|
||||
&& name.equals("getAdaptor")) {
|
||||
super.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
"com/glodblock/github/coremod/hooker/CoreModHooks",
|
||||
"wrapInventory",
|
||||
"(Lnet/minecraft/tileentity/TileEntity;Lnet/minecraftforge/common/util/ForgeDirection;)Lappeng/util/InventoryAdaptor;",
|
||||
false);
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
package com.glodblock.github.inventory;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.glodblock.github.common.item.ItemFluidDrop;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.BaseActionSource;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.StorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
|
||||
public class CraftingGridCacheFluidInventoryProxyCell implements IMEInventoryHandler<IAEFluidStack> {
|
||||
|
||||
private final CraftingGridCache inner;
|
||||
|
||||
public CraftingGridCacheFluidInventoryProxyCell(final CraftingGridCache craftingGridCache) {
|
||||
inner = craftingGridCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack injectItems(IAEFluidStack input, Actionable type, BaseActionSource src) {
|
||||
return ItemFluidDrop
|
||||
.getAeFluidStack((IAEItemStack) inner.injectItems(ItemFluidDrop.newAeStack(input), type, src));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> getAvailableItems(IItemList<IAEFluidStack> out, int iteration) {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack getAvailableItem(@NotNull IAEFluidStack request, int iteration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageChannel getChannel() {
|
||||
return StorageChannel.FLUIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return inner.getAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized(IAEFluidStack input) {
|
||||
return inner.isPrioritized(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept(IAEFluidStack input) {
|
||||
return inner.canAccept(ItemFluidDrop.newAeStack(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return inner.getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return inner.getSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass(int i) {
|
||||
return inner.validForPass(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoCraftingInventory() {
|
||||
return inner.isAutoCraftingInventory();
|
||||
}
|
||||
}
|
||||
@@ -1,539 +0,0 @@
|
||||
package com.glodblock.github.inventory;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidTankInfo;
|
||||
import net.minecraftforge.fluids.IFluidHandler;
|
||||
|
||||
import com.glodblock.github.common.Config;
|
||||
import com.glodblock.github.common.item.ItemFluidDrop;
|
||||
import com.glodblock.github.common.item.ItemFluidPacket;
|
||||
import com.glodblock.github.common.parts.PartFluidExportBus;
|
||||
import com.glodblock.github.common.parts.PartFluidInterface;
|
||||
import com.glodblock.github.common.parts.PartFluidP2PInterface;
|
||||
import com.glodblock.github.common.tile.TileFluidInterface;
|
||||
import com.glodblock.github.util.BlockPos;
|
||||
import com.glodblock.github.util.ModAndClassUtil;
|
||||
import com.glodblock.github.util.Util;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.InsertionMode;
|
||||
import appeng.api.config.Upgrades;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.helpers.DualityInterface;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.AENetworkProxy;
|
||||
import appeng.parts.p2p.PartP2PLiquids;
|
||||
import appeng.tile.misc.TileInterface;
|
||||
import appeng.tile.networking.TileCableBus;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.inv.IInventoryDestination;
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import cofh.api.transport.IItemDuct;
|
||||
import crazypants.enderio.conduit.ConnectionMode;
|
||||
import crazypants.enderio.conduit.item.IItemConduit;
|
||||
import crazypants.enderio.conduit.liquid.ILiquidConduit;
|
||||
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
|
||||
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
|
||||
import gregtech.api.metatileentity.MetaPipeEntity;
|
||||
|
||||
public class FluidConvertingInventoryAdaptor extends InventoryAdaptor {
|
||||
|
||||
// facing is the target TE direction
|
||||
// |T|-facing->|I|
|
||||
public FluidConvertingInventoryAdaptor(TileEntity te, @Nullable InventoryAdaptor invItems,
|
||||
@Nullable IFluidHandler invFluids, ForgeDirection facing, BlockPos pos, boolean isOnmi) {
|
||||
this.invItems = invItems;
|
||||
this.invFluids = invFluids;
|
||||
this.side = facing;
|
||||
this.posInterface = pos;
|
||||
this.onmi = isOnmi;
|
||||
this.selfInterface = getInterfaceTE(pos.getTileEntity(), facing.getOpposite());
|
||||
this.targetInterface = getInterfaceTE(te, facing);
|
||||
}
|
||||
|
||||
private final InventoryAdaptor invItems;
|
||||
private final IFluidHandler invFluids;
|
||||
private final ForgeDirection side;
|
||||
private final BlockPos posInterface;
|
||||
@Nullable
|
||||
private final IInterfaceHost targetInterface;
|
||||
@Nullable
|
||||
private final IInterfaceHost selfInterface;
|
||||
private final boolean onmi;
|
||||
private static Method eioTypeCheck;
|
||||
private static Class<?> conduitClazz;
|
||||
|
||||
static {
|
||||
if (ModAndClassUtil.EIO) {
|
||||
try {
|
||||
conduitClazz = Class.forName("crazypants.enderio.conduit.TileConduitBundle");
|
||||
eioTypeCheck = conduitClazz.getDeclaredMethod("getConduit", Class.class);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
eioTypeCheck = null;
|
||||
}
|
||||
} else {
|
||||
eioTypeCheck = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static InventoryAdaptor wrap(TileEntity capProvider, ForgeDirection face) {
|
||||
TileEntity inter = capProvider.getWorldObj().getTileEntity(
|
||||
capProvider.xCoord + face.offsetX,
|
||||
capProvider.yCoord + face.offsetY,
|
||||
capProvider.zCoord + face.offsetZ);
|
||||
if (!Config.noFluidPacket && !(inter instanceof TileFluidInterface
|
||||
|| Util.getPart(inter, face.getOpposite()) instanceof PartFluidInterface
|
||||
|| Util.getPart(inter, face.getOpposite()) instanceof PartFluidExportBus
|
||||
|| Util.getPart(inter, face.getOpposite()) instanceof PartFluidP2PInterface))
|
||||
return InventoryAdaptor.getAdaptor(capProvider, face);
|
||||
if (InventoryAdaptor.getAdaptor(capProvider, face) == null
|
||||
&& !(ModAndClassUtil.EIO && capProvider instanceof IItemDuct)) {
|
||||
if (capProvider instanceof IFluidHandler tank) {
|
||||
if (tank.getTankInfo(face) == null || !(tank.getTankInfo(face).length > 0)) return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
InventoryAdaptor item = InventoryAdaptor.getAdaptor(capProvider, face);
|
||||
IFluidHandler fluid = capProvider instanceof IFluidHandler ? (IFluidHandler) capProvider : null;
|
||||
boolean onmi = false;
|
||||
if (inter instanceof TileInterface in) {
|
||||
onmi = in.getTargets().size() > 1;
|
||||
}
|
||||
return new FluidConvertingInventoryAdaptor(capProvider, item, fluid, face, new BlockPos(inter), onmi);
|
||||
}
|
||||
|
||||
public ItemStack addItems(ItemStack toBeAdded, InsertionMode insertionMode) {
|
||||
FluidStack fluid = Util.getFluidFromVirtual(toBeAdded);
|
||||
if (!this.onmi) {
|
||||
if (!checkValidSide(
|
||||
this.posInterface.getOffSet(this.side.getOpposite()).getTileEntity(),
|
||||
this.side.getOpposite())) {
|
||||
return toBeAdded;
|
||||
}
|
||||
if (fluid != null) {
|
||||
int filled = fillSideFluid(fluid, this.invFluids, this.side, true);
|
||||
fluid.amount -= filled;
|
||||
return ItemFluidDrop.newStack(fluid);
|
||||
} else {
|
||||
ItemStack notFilled = fillSideItem(toBeAdded, this.invItems, insertionMode, true);
|
||||
if (notFilled != null) {
|
||||
// Fill EIO Conduit at last.
|
||||
return fillEIOConduit(
|
||||
notFilled,
|
||||
this.posInterface.getOffSet(this.side.getOpposite()).getTileEntity(),
|
||||
this.side);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (fluid != null) {
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
if (fluid.amount <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (!checkValidSide(this.posInterface.getOffSet(dir).getTileEntity(), dir)) {
|
||||
continue;
|
||||
}
|
||||
int filled = fillSideFluid(fluid, getSideFluid(dir), dir.getOpposite(), true);
|
||||
fluid.amount -= filled;
|
||||
}
|
||||
return ItemFluidPacket.newStack(fluid);
|
||||
} else {
|
||||
ItemStack item = toBeAdded.copy();
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
if (item == null || item.stackSize <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (!checkValidSide(this.posInterface.getOffSet(dir).getTileEntity(), dir)) {
|
||||
continue;
|
||||
}
|
||||
item = fillSideItem(item, getSideItem(dir), insertionMode, true);
|
||||
}
|
||||
// Fill EIO Conduit at last.
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
if (item == null || item.stackSize <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (!checkValidSide(this.posInterface.getOffSet(dir).getTileEntity(), dir)) {
|
||||
continue;
|
||||
}
|
||||
item = fillEIOConduit(item, this.posInterface.getOffSet(dir).getTileEntity(), dir.getOpposite());
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack addItems(ItemStack toBeAdded) {
|
||||
return addItems(toBeAdded, InsertionMode.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateAdd(ItemStack toBeSimulated) {
|
||||
return simulateAdd(toBeSimulated, InsertionMode.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateAdd(ItemStack toBeSimulated, InsertionMode insertionMode) {
|
||||
FluidStack fluid = Util.getFluidFromVirtual(toBeSimulated);
|
||||
if (!this.onmi) {
|
||||
if (!checkValidSide(
|
||||
this.posInterface.getOffSet(this.side.getOpposite()).getTileEntity(),
|
||||
this.side.getOpposite())) {
|
||||
return toBeSimulated;
|
||||
}
|
||||
if (fluid != null) {
|
||||
int filled = fillSideFluid(fluid, this.invFluids, this.side, false);
|
||||
fluid.amount -= filled;
|
||||
return ItemFluidPacket.newStack(fluid);
|
||||
} else {
|
||||
// Assert EIO conduit can hold all item, as it is the origin practice in AE2
|
||||
if (isConduit(this.posInterface.getOffSet(this.side.getOpposite()).getTileEntity())) {
|
||||
return null;
|
||||
} else {
|
||||
return fillSideItem(toBeSimulated, this.invItems, insertionMode, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In onmi mode, fluid/item only need to be partly inserted.
|
||||
boolean sus = false;
|
||||
if (fluid != null) {
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
if (!checkValidSide(this.posInterface.getOffSet(dir).getTileEntity(), dir)) {
|
||||
continue;
|
||||
}
|
||||
int filled = fillSideFluid(fluid, getSideFluid(dir), dir.getOpposite(), false);
|
||||
if (filled > 0) {
|
||||
sus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
if (!checkValidSide(this.posInterface.getOffSet(dir).getTileEntity(), dir)) {
|
||||
continue;
|
||||
}
|
||||
// Assert EIO conduit can hold all item, as it is the origin practice in AE2
|
||||
if (isConduit(this.posInterface.getOffSet(dir).getTileEntity())) {
|
||||
return null;
|
||||
}
|
||||
ItemStack notFilled = fillSideItem(toBeSimulated, getSideItem(dir), insertionMode, false);
|
||||
if (notFilled == null || notFilled.stackSize < toBeSimulated.stackSize) {
|
||||
sus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sus ? null : toBeSimulated;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItems(int amount, ItemStack filter, IInventoryDestination destination) {
|
||||
return invItems != null ? invItems.removeItems(amount, filter, destination) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateRemove(int amount, ItemStack filter, IInventoryDestination destination) {
|
||||
return invItems != null ? invItems.simulateRemove(amount, filter, destination) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeSimilarItems(int amount, ItemStack filter, FuzzyMode fuzzyMode,
|
||||
IInventoryDestination destination) {
|
||||
return invItems != null ? invItems.removeSimilarItems(amount, filter, fuzzyMode, destination) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack simulateSimilarRemove(int amount, ItemStack filter, FuzzyMode fuzzyMode,
|
||||
IInventoryDestination destination) {
|
||||
return invItems != null ? invItems.simulateSimilarRemove(amount, filter, fuzzyMode, destination) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsItems() {
|
||||
if (!this.onmi) {
|
||||
// If there is no fluid tank or item inventory, it shouldn't send stuff here.
|
||||
return checkItemFluids(this.invFluids, this.invItems, this.side) > 0;
|
||||
}
|
||||
boolean anyValid = false;
|
||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
||||
// Avoid sending stuff into itself me network
|
||||
TileEntity te = this.posInterface.getOffSet(dir).getTileEntity();
|
||||
if (te != null && checkValidSide(te, dir)) {
|
||||
if (!isConduit(te) || (!isItemConduit(te) && isFluidConduitConnected(te, dir))) {
|
||||
final int result = checkItemFluids(
|
||||
this.getSideFluid(dir),
|
||||
this.getSideItem(dir),
|
||||
dir.getOpposite());
|
||||
if (result == 1) {
|
||||
return true;
|
||||
}
|
||||
if (result != 2) {
|
||||
anyValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Same here. if there is no fluid tank or item inventory existed, it shouldn't send stuff here.
|
||||
return !anyValid;
|
||||
}
|
||||
|
||||
public boolean hasSlots() {
|
||||
return (invFluids != null && invFluids.getTankInfo(side).length > 0) || (invItems != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemSlot> iterator() {
|
||||
FluidTankInfo[] info = null;
|
||||
if (invFluids != null) {
|
||||
info = invFluids.getTankInfo(side);
|
||||
}
|
||||
// Null check is needed because some tank infos return null (EIO conduits...)
|
||||
if (info == null) {
|
||||
info = new FluidTankInfo[0];
|
||||
}
|
||||
return new SlotIterator(info, invItems != null ? invItems.iterator() : Collections.emptyIterator());
|
||||
}
|
||||
|
||||
private IFluidHandler getSideFluid(ForgeDirection direction) {
|
||||
TileEntity te = this.posInterface.getOffSet(direction).getTileEntity();
|
||||
if (te instanceof IFluidHandler) {
|
||||
return (IFluidHandler) te;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int fillSideFluid(FluidStack fluid, IFluidHandler tank, ForgeDirection direction, boolean doFill) {
|
||||
if (tank != null) {
|
||||
return tank.fill(direction, fluid, doFill);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EIO conduit isn't considered here
|
||||
private ItemStack fillSideItem(ItemStack item, InventoryAdaptor inv, InsertionMode mode, boolean doFill) {
|
||||
if (inv != null) {
|
||||
if (doFill) {
|
||||
return inv.addItems(item, mode);
|
||||
} else {
|
||||
return inv.simulateAdd(item, mode);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private int gtMachineCircuitCheck(InventoryAdaptor ad) {
|
||||
if (ad == null) {
|
||||
return 0;
|
||||
}
|
||||
for (ItemSlot i : ad) {
|
||||
ItemStack is = i.getItemStack();
|
||||
if (is == null || Objects.requireNonNull(is.getItem()).getUnlocalizedName().equals("gt.integrated_circuit"))
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private boolean isGTMachine(Object o) {
|
||||
if (!(ModAndClassUtil.GT5 || ModAndClassUtil.GT5NH)) return false;
|
||||
|
||||
if (o instanceof TileEntity te) {
|
||||
return te.getBlockType().getUnlocalizedName().equals("gt.blockmachines");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isFluidConduitConnected(TileEntity te, ForgeDirection dir) {
|
||||
try {
|
||||
ILiquidConduit liquidConduit = (ILiquidConduit) eioTypeCheck.invoke(te, ILiquidConduit.class);
|
||||
return liquidConduit != null
|
||||
&& liquidConduit.getConnectionMode(dir.getOpposite()) != ConnectionMode.DISABLED;
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isItemConduit(TileEntity te) {
|
||||
if (isConduit(te)) {
|
||||
try {
|
||||
return eioTypeCheck.invoke(te, IItemConduit.class) != null;
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isConduit(TileEntity te) {
|
||||
return ModAndClassUtil.EIO && conduitClazz.isInstance(te);
|
||||
}
|
||||
|
||||
private ItemStack fillEIOConduit(ItemStack item, TileEntity te, ForgeDirection direction) {
|
||||
if (isConduit(te)) {
|
||||
return ((IItemDuct) te).insertItem(direction, item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
private InventoryAdaptor getSideItem(ForgeDirection direction) {
|
||||
TileEntity te = this.posInterface.getOffSet(direction).getTileEntity();
|
||||
return InventoryAdaptor.getAdaptor(te, direction.getOpposite());
|
||||
}
|
||||
|
||||
// 0 - It is empty
|
||||
// 1 - It contains item/fluid
|
||||
// 2 - It doesn't exist
|
||||
private int checkItemFluids(IFluidHandler tank, InventoryAdaptor inv, ForgeDirection direction) {
|
||||
if (tank == null && inv == null) {
|
||||
return 2;
|
||||
}
|
||||
if (targetInterface != null && targetInterface.getInstalledUpgrades(Upgrades.ADVANCED_BLOCKING) > 0
|
||||
&& targetInterface instanceof IDualHost
|
||||
&& !((IDualHost) targetInterface).getDualityFluid().getFluidInventory().getStorageList().isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
if (tank != null && tank.getTankInfo(direction) != null) {
|
||||
List<FluidTankInfo[]> tankInfos = new LinkedList<>();
|
||||
if (Util.getPart(tank, direction) instanceof PartP2PLiquids invFluidsP2P) {
|
||||
// read other ends of p2p for blocking mode
|
||||
try {
|
||||
Iterator<PartP2PLiquids> it = invFluidsP2P.getOutputs().iterator();
|
||||
boolean checkedInput = false;
|
||||
while (it.hasNext() || !checkedInput) {
|
||||
PartP2PLiquids p2p;
|
||||
if (it.hasNext()) {
|
||||
p2p = it.next();
|
||||
} else {
|
||||
p2p = invFluidsP2P.getInput();
|
||||
checkedInput = true;
|
||||
}
|
||||
if (p2p == invFluidsP2P || p2p == null) continue;
|
||||
IFluidHandler target = p2p.getTarget();
|
||||
if (target == null) continue;
|
||||
FluidTankInfo[] info = target.getTankInfo(p2p.getSide().getOpposite());
|
||||
if (info != null) {
|
||||
tankInfos.add(info);
|
||||
}
|
||||
}
|
||||
} catch (GridAccessException ignore) {}
|
||||
} else {
|
||||
tankInfos.add(tank.getTankInfo(direction));
|
||||
}
|
||||
boolean hasTank = false;
|
||||
for (FluidTankInfo[] tankInfoArray : tankInfos) {
|
||||
for (FluidTankInfo tankInfo : tankInfoArray) {
|
||||
hasTank = true;
|
||||
FluidStack fluid = tankInfo.fluid;
|
||||
if (fluid != null && fluid.amount > 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasTank && inv == null) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
if (isGTMachine(tank)) {
|
||||
return gtMachineCircuitCheck(inv);
|
||||
}
|
||||
return inv != null && inv.containsItems() ? 1 : 0;
|
||||
}
|
||||
|
||||
private boolean checkValidSide(TileEntity te, ForgeDirection direction) {
|
||||
if (isGTMachine(te)) {
|
||||
return checkGTPipeConnection(te, direction.getOpposite());
|
||||
}
|
||||
return isDifferentGrid(getInterfaceTE(te, direction.getOpposite()));
|
||||
}
|
||||
|
||||
private boolean checkGTPipeConnection(TileEntity te, ForgeDirection direction) {
|
||||
if (te instanceof IGregTechTileEntity) {
|
||||
IMetaTileEntity mte = ((IGregTechTileEntity) te).getMetaTileEntity();
|
||||
if (mte instanceof MetaPipeEntity) {
|
||||
return ((MetaPipeEntity) mte).isConnectedAtSide(direction);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static IInterfaceHost getInterfaceTE(TileEntity te, ForgeDirection face) {
|
||||
if (te instanceof IInterfaceHost) {
|
||||
return (IInterfaceHost) te;
|
||||
} else if (te instanceof TileCableBus) {
|
||||
IPart part = ((TileCableBus) te).getPart(face);
|
||||
if (part instanceof IInterfaceHost) {
|
||||
return (IInterfaceHost) part;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDifferentGrid(IInterfaceHost target) {
|
||||
if (this.selfInterface != null && target != null) {
|
||||
DualityInterface other = target.getInterfaceDuality();
|
||||
DualityInterface self = this.selfInterface.getInterfaceDuality();
|
||||
try {
|
||||
AENetworkProxy proxy1 = other.getProxy();
|
||||
AENetworkProxy proxy2 = self.getProxy();
|
||||
if (proxy1.getGrid() == proxy2.getGrid()) {
|
||||
return false;
|
||||
}
|
||||
} catch (GridAccessException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class SlotIterator implements Iterator<ItemSlot> {
|
||||
|
||||
private final FluidTankInfo[] tanks;
|
||||
private final Iterator<ItemSlot> itemSlots;
|
||||
private int nextSlotIndex = 0;
|
||||
|
||||
SlotIterator(FluidTankInfo[] tanks, Iterator<ItemSlot> itemSlots) {
|
||||
this.tanks = tanks;
|
||||
this.itemSlots = itemSlots;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return itemSlots.hasNext() || nextSlotIndex < tanks.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemSlot next() {
|
||||
if (nextSlotIndex < tanks.length) {
|
||||
FluidStack fluid = tanks[nextSlotIndex].fluid;
|
||||
ItemSlot slot = new ItemSlot();
|
||||
slot.setSlot(nextSlotIndex++);
|
||||
slot.setItemStack(fluid != null ? ItemFluidPacket.newStack(fluid) : null);
|
||||
slot.setExtractable(false);
|
||||
return slot;
|
||||
} else {
|
||||
ItemSlot slot = itemSlots.next();
|
||||
slot.setSlot(nextSlotIndex++);
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.glodblock.github.inventory;
|
||||
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import com.glodblock.github.common.item.ItemFluidDrop;
|
||||
import com.glodblock.github.common.item.ItemFluidPacket;
|
||||
|
||||
public class FluidConvertingInventoryCrafting extends InventoryCrafting {
|
||||
|
||||
public FluidConvertingInventoryCrafting(Container container, int width, int height) {
|
||||
super(container, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int index, ItemStack stack) {
|
||||
if (stack != null && stack.getItem() instanceof ItemFluidDrop) {
|
||||
FluidStack fluid = ItemFluidDrop.getFluidStack(stack);
|
||||
if (fluid != null) {
|
||||
super.setInventorySlotContents(index, ItemFluidPacket.newStack(new FluidStack(fluid, stack.stackSize)));
|
||||
} else {
|
||||
super.setInventorySlotContents(
|
||||
index,
|
||||
ItemFluidPacket.newStack(new FluidStack(FluidRegistry.WATER, 1000)));
|
||||
}
|
||||
} else {
|
||||
super.setInventorySlotContents(index, stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,11 @@ import net.minecraftforge.fluids.IFluidHandler;
|
||||
|
||||
import appeng.api.implementations.IUpgradeableHost;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingJob;
|
||||
import appeng.api.networking.security.BaseActionSource;
|
||||
import appeng.api.networking.security.MachineSource;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerUpgradeable;
|
||||
import appeng.container.implementations.CraftingCPURecord;
|
||||
import appeng.crafting.MECraftingInventory;
|
||||
import appeng.helpers.DualityInterface;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.me.helpers.AENetworkProxy;
|
||||
@@ -32,19 +27,12 @@ public class Ae2Reflect {
|
||||
private static final Field fInventory_containerUpgrade;
|
||||
private static final Field fAEPass_internal;
|
||||
private static final Field fAEInv_partitionList;
|
||||
private static final Field fCPU_cpu;
|
||||
private static final Field fCPU_myName;
|
||||
private static final Field fCPU_processors;
|
||||
private static final Field fCPU_size;
|
||||
private static final Field fCPU_inventory;
|
||||
private static final Field fCPU_machineSrc;
|
||||
private static final Field fContainerUpgradeable_upgradeable;
|
||||
private static final Field fDualInterface_gridProxy;
|
||||
private static final Field fCraftConfirm_result;
|
||||
private static final Method mItemSlot_setExtractable;
|
||||
private static final Method mCPU_getGrid;
|
||||
private static final Method mCPU_postChange;
|
||||
private static final Method mCPU_markDirty;
|
||||
private static final Method mP2PLiquids_getTarget;
|
||||
private static final Method mCraftConfirm_getGrid;
|
||||
|
||||
@@ -53,22 +41,11 @@ public class Ae2Reflect {
|
||||
fInventory_containerUpgrade = reflectField(ContainerUpgradeable.class, "upgradeable");
|
||||
fAEPass_internal = reflectField(MEPassThrough.class, "internal");
|
||||
fAEInv_partitionList = reflectField(MEInventoryHandler.class, "myPartitionList");
|
||||
fCPU_cpu = Ae2Reflect.reflectField(CraftingCPURecord.class, "cpu");
|
||||
fCPU_myName = Ae2Reflect.reflectField(CraftingCPURecord.class, "myName");
|
||||
fCPU_processors = Ae2Reflect.reflectField(CraftingCPURecord.class, "processors");
|
||||
fCPU_size = Ae2Reflect.reflectField(CraftingCPURecord.class, "size");
|
||||
fCPU_inventory = Ae2Reflect.reflectField(CraftingCPUCluster.class, "inventory");
|
||||
fCPU_machineSrc = Ae2Reflect.reflectField(CraftingCPUCluster.class, "machineSrc");
|
||||
fContainerUpgradeable_upgradeable = Ae2Reflect.reflectField(ContainerUpgradeable.class, "upgradeable");
|
||||
mItemSlot_setExtractable = reflectMethod(ItemSlot.class, "setExtractable", boolean.class);
|
||||
fDualInterface_gridProxy = reflectField(DualityInterface.class, "gridProxy");
|
||||
mCPU_getGrid = reflectMethod(CraftingCPUCluster.class, "getGrid");
|
||||
mCPU_postChange = reflectMethod(
|
||||
CraftingCPUCluster.class,
|
||||
"postChange",
|
||||
IAEItemStack.class,
|
||||
BaseActionSource.class);
|
||||
mCPU_markDirty = reflectMethod(CraftingCPUCluster.class, "markDirty");
|
||||
mP2PLiquids_getTarget = reflectMethod(PartP2PLiquids.class, "getTarget");
|
||||
fCraftConfirm_result = reflectField(ContainerCraftConfirm.class, "result");
|
||||
mCraftConfirm_getGrid = reflectMethod(ContainerCraftConfirm.class, "getGrid");
|
||||
@@ -135,26 +112,11 @@ public class Ae2Reflect {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ICraftingCPU getCPU(CraftingCPURecord cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_cpu);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getName(CraftingCPURecord cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_myName);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int getProcessors(CraftingCPURecord cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_processors);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static long getSize(CraftingCPURecord cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_size);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static IUpgradeableHost getUpgradeList(ContainerUpgradeable container) {
|
||||
return Ae2Reflect.readField(container, fInventory_containerUpgrade);
|
||||
@@ -183,20 +145,6 @@ public class Ae2Reflect {
|
||||
return Ae2Reflect.readField(ccc, fCraftConfirm_result);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static MECraftingInventory getCPUInventory(CraftingCPUCluster cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_inventory);
|
||||
}
|
||||
|
||||
public static void setCPUInventory(CraftingCPUCluster cpu, MECraftingInventory value) {
|
||||
Ae2Reflect.writeField(cpu, fCPU_inventory, value);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static MachineSource getCPUSource(CraftingCPUCluster cpu) {
|
||||
return Ae2Reflect.readField(cpu, fCPU_machineSrc);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static IUpgradeableHost getUpgradeableHost(ContainerUpgradeable owner) {
|
||||
return Ae2Reflect.readField(owner, fContainerUpgradeable_upgradeable);
|
||||
@@ -207,23 +155,6 @@ public class Ae2Reflect {
|
||||
return Ae2Reflect.readField(owner, fDualInterface_gridProxy);
|
||||
}
|
||||
|
||||
public static void postCPUChange(CraftingCPUCluster cpu, IAEItemStack stack, MachineSource src) {
|
||||
try {
|
||||
mCPU_postChange.invoke(cpu, stack, src);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to invoke method: " + mCPU_postChange, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void markCPUDirty(CraftingCPUCluster cpu) {
|
||||
try {
|
||||
mCPU_markDirty.invoke(cpu);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to invoke method: " + mCPU_markDirty, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static IFluidHandler getP2PLiquidTarget(PartP2PLiquids p2p) {
|
||||
try {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user