diff --git a/src/main/java/gregtech/api/capability/DualHandler.java b/src/main/java/gregtech/api/capability/DualHandler.java new file mode 100644 index 00000000000..015017c769e --- /dev/null +++ b/src/main/java/gregtech/api/capability/DualHandler.java @@ -0,0 +1,238 @@ +package gregtech.api.capability; + +import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.util.ItemStackHashStrategy; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidTankProperties; +import net.minecraftforge.items.IItemHandlerModifiable; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class DualHandler implements IItemHandlerModifiable, IMultipleTankHandler, INotifiableHandler { + + @NotNull + private static final ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingAll(); + + @NotNull + protected IItemHandlerModifiable itemDelegate; + @NotNull + protected IMultipleTankHandler fluidDelegate; + + private final List unwrapped; + + List notifiableEntities = new ArrayList<>(); + private final boolean isExport; + + public DualHandler(@NotNull IItemHandlerModifiable itemDelegate, + @NotNull IMultipleTankHandler fluidDelegate, + boolean isExport) { + this.itemDelegate = itemDelegate; + this.fluidDelegate = fluidDelegate; + this.isExport = isExport; + + List list = new ArrayList<>(); + for (ITankEntry tank : this.fluidDelegate) { + list.add(wrap(tank)); + } + this.unwrapped = list; + } + + public DualHandler(@NotNull IItemHandlerModifiable itemDelegate, + @NotNull IFluidTank fluidTank, + boolean isExport) { + this(itemDelegate, new FluidTankList(false, fluidTank), isExport); + } + + private DualEntry wrap(ITankEntry entry) { + return entry instanceof DualEntry ? (DualEntry) entry : new DualEntry(this, entry); + } + + public boolean isExport() { + return this.isExport; + } + + @Override + public int getSlots() { + return itemDelegate.getSlots(); + } + + @Override + public @NotNull ItemStack getStackInSlot(int slot) { + return itemDelegate.getStackInSlot(slot); + } + + @Override + public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + var remainder = itemDelegate.insertItem(slot, stack, simulate); + if (!simulate && !strategy.equals(remainder, stack)) + onContentsChanged(); + return remainder; + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + var extracted = itemDelegate.extractItem(slot, amount, simulate); + if (!simulate && !extracted.isEmpty()) + onContentsChanged(); + return extracted; + } + + @Override + public int getSlotLimit(int slot) { + return itemDelegate.getSlotLimit(slot); + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + var oldStack = itemDelegate.getStackInSlot(slot); + itemDelegate.setStackInSlot(slot, stack); + if (!strategy.equals(oldStack, stack)) + onContentsChanged(); + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return this.fluidDelegate.getTankProperties(); + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + int filled = fluidDelegate.fill(resource, doFill); + if (doFill && filled > 0) onContentsChanged(); + return filled; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + var drained = fluidDelegate.drain(resource, doDrain); + if (doDrain && drained != null) onContentsChanged(); + return drained; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + var drained = fluidDelegate.drain(maxDrain, doDrain); + if (doDrain && drained != null) onContentsChanged(); + return drained; + } + + @Override + public @NotNull List getFluidTanks() { + return this.unwrapped; + } + + @Override + public int getTanks() { + return this.fluidDelegate.getTanks(); + } + + @Override + public @NotNull ITankEntry getTankAt(int index) { + return this.unwrapped.get(index); + } + + @Override + public boolean allowSameFluidFill() { + return this.fluidDelegate.allowSameFluidFill(); + } + + public void onContentsChanged(Object handler) { + for (MetaTileEntity metaTileEntity : notifiableEntities) { + addToNotifiedList(metaTileEntity, handler, isExport); + } + } + + public void onContentsChanged() { + onContentsChanged(this); + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + if (metaTileEntity == null || this.notifiableEntities.contains(metaTileEntity)) + return; + this.notifiableEntities.add(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.notifiableEntities.remove(metaTileEntity); + } + + public @NotNull IItemHandlerModifiable getItemDelegate() { + return itemDelegate; + } + + public @NotNull IMultipleTankHandler getFluidDelegate() { + return fluidDelegate; + } + + public static class DualEntry implements ITankEntry, INotifiableHandler { + + @NotNull + private final DualHandler tank; + + @NotNull + private final ITankEntry delegate; + + public DualEntry(@NotNull DualHandler tank, @NotNull ITankEntry delegate) { + this.delegate = delegate; + this.tank = tank; + } + + @Override + public @NotNull IMultipleTankHandler getParent() { + return this.tank; + } + + @Override + public @NotNull ITankEntry getDelegate() { + return this.delegate; + } + + @Override + public IFluidTankProperties[] getTankProperties() { + return this.getDelegate().getTankProperties(); + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + int filled = getDelegate().fill(resource, doFill); + if (doFill && filled > 0) + tank.onContentsChanged(this); + return filled; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + var drained = getDelegate().drain(resource, doDrain); + if (doDrain && drained != null) + tank.onContentsChanged(this); + return drained; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + var drained = getDelegate().drain(maxDrain, doDrain); + if (doDrain && drained != null) + tank.onContentsChanged(this); + return drained; + } + + @Override + public void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.tank.addNotifiableMetaTileEntity(metaTileEntity); + } + + @Override + public void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity) { + this.tank.removeNotifiableMetaTileEntity(metaTileEntity); + } + } +} diff --git a/src/main/java/gregtech/api/capability/IDualHandler.java b/src/main/java/gregtech/api/capability/IDualHandler.java deleted file mode 100644 index 595efc6a9f2..00000000000 --- a/src/main/java/gregtech/api/capability/IDualHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package gregtech.api.capability; - -import net.minecraftforge.items.IItemHandler; - -public interface IDualHandler { - - boolean hasFluidTanks(); - - boolean hasItemHandlers(); - - IMultipleTankHandler getFluidTanks(); - - IItemHandler getItemHandlers(); -} diff --git a/src/main/java/gregtech/api/capability/IMultipleTankHandler.java b/src/main/java/gregtech/api/capability/IMultipleTankHandler.java index b9e89c71d30..4a36b4dcafe 100644 --- a/src/main/java/gregtech/api/capability/IMultipleTankHandler.java +++ b/src/main/java/gregtech/api/capability/IMultipleTankHandler.java @@ -1,5 +1,6 @@ package gregtech.api.capability; +import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.fluids.FluidStack; @@ -7,7 +8,6 @@ import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidTankProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,12 +22,12 @@ * * @see gregtech.api.capability.impl.FluidTankList FluidTankList */ -public interface IMultipleTankHandler extends IFluidHandler, Iterable { +public interface IMultipleTankHandler extends IFluidHandler, Iterable { /** * Comparator for entries that can be used in insertion logic */ - Comparator ENTRY_COMPARATOR = (o1, o2) -> { + Comparator ENTRY_COMPARATOR = (o1, o2) -> { // #1: non-empty tank first boolean empty1 = o1.getFluidAmount() <= 0; boolean empty2 = o2.getFluidAmount() <= 0; @@ -46,7 +46,7 @@ public interface IMultipleTankHandler extends IFluidHandler, Iterable getFluidTanks(); + List getFluidTanks(); /** * @return Number of tanks in this tank handler @@ -54,7 +54,7 @@ public interface IMultipleTankHandler extends IFluidHandler, Iterable fluidTanks = getFluidTanks(); + List fluidTanks = getFluidTanks(); for (int i = 0; i < fluidTanks.size(); i++) { FluidStack tankStack = fluidTanks.get(i).getFluid(); if (fluidStack == tankStack || tankStack != null && tankStack.isFluidEqual(fluidStack)) { @@ -81,7 +81,7 @@ default int getIndexOfFluid(@Nullable FluidStack fluidStack) { } @Override - default Iterator iterator() { + default Iterator iterator() { return getFluidTanks().iterator(); } @@ -89,160 +89,65 @@ default Iterator iterator() { * Entry of multi fluid tanks. Retains reference to original {@link IMultipleTankHandler} for accessing * information such as {@link IMultipleTankHandler#allowSameFluidFill()}. */ - final class MultiFluidTankEntry implements IFluidTank, IFluidHandler, IFilteredFluidContainer { - - private final IMultipleTankHandler tank; - private final IFluidTank delegate; - - public MultiFluidTankEntry(@NotNull IMultipleTankHandler tank, @NotNull IFluidTank delegate) { - this.tank = tank; - this.delegate = delegate; - } + interface ITankEntry extends IFluidTank, IFluidHandler, IFilteredFluidContainer, INBTSerializable { @NotNull - public IMultipleTankHandler getTank() { - return tank; - } + IMultipleTankHandler getParent(); @NotNull - public IFluidTank getDelegate() { - return delegate; - } + IFluidTank getDelegate(); - public boolean allowSameFluidFill() { - return tank.allowSameFluidFill(); + default boolean allowSameFluidFill() { + return getParent().allowSameFluidFill(); } - @Nullable - @Override - public IFilter getFilter() { - return this.delegate instanceof IFilteredFluidContainer filtered ? filtered.getFilter() : null; + default IFilter getFilter() { + return getDelegate() instanceof IFilteredFluidContainer filtered ? filtered.getFilter() : null; } - @NotNull - public IFluidTankProperties[] getTankProperties() { - return delegate instanceof IFluidHandler fluidHandler ? - fluidHandler.getTankProperties() : - new IFluidTankProperties[] { new FallbackTankProperty() }; - } - - public NBTTagCompound trySerialize() { - if (delegate instanceof FluidTank fluidTank) { + @Override + default NBTTagCompound serializeNBT() { + if (getDelegate() instanceof FluidTank fluidTank) { return fluidTank.writeToNBT(new NBTTagCompound()); - } else if (delegate instanceof INBTSerializable serializable) { - try { - return (NBTTagCompound) serializable.serializeNBT(); - } catch (ClassCastException ignored) {} + } else if (getDelegate() instanceof INBTSerializableserializable) { + if (serializable.serializeNBT() instanceof NBTTagCompound compound) { + return compound; + } } return new NBTTagCompound(); } - @SuppressWarnings({ "unchecked" }) - public void tryDeserialize(NBTTagCompound tag) { - if (delegate instanceof FluidTank fluidTank) { - fluidTank.readFromNBT(tag); - } else if (delegate instanceof INBTSerializable serializable) { + @Override + @SuppressWarnings("unchecked") + default void deserializeNBT(NBTTagCompound nbt) { + if (getDelegate() instanceof FluidTank fluidTank) { + fluidTank.readFromNBT(nbt); + } else if (getDelegate() instanceof INBTSerializableserializable) { try { - serializable.deserializeNBT(tag); + ((INBTSerializable) serializable).deserializeNBT(nbt); } catch (ClassCastException ignored) {} } } @Nullable @Override - public FluidStack getFluid() { - return delegate.getFluid(); - } - - @Override - public int getFluidAmount() { - return delegate.getFluidAmount(); - } - - @Override - public int getCapacity() { - return delegate.getCapacity(); - } - - @Override - public FluidTankInfo getInfo() { - return delegate.getInfo(); - } - - @Override - public int fill(FluidStack resource, boolean doFill) { - return delegate.fill(resource, doFill); - } - - @Nullable - @Override - public FluidStack drain(FluidStack resource, boolean doDrain) { - if (resource == null || resource.amount <= 0) { - return null; - } - if (delegate instanceof IFluidHandler fluidHandler) { - return fluidHandler.drain(resource, doDrain); - } - // just imitate the logic - FluidStack fluid = delegate.getFluid(); - return fluid != null && fluid.isFluidEqual(resource) ? drain(resource.amount, doDrain) : null; - } - - @Nullable - @Override - public FluidStack drain(int maxDrain, boolean doDrain) { - return delegate.drain(maxDrain, doDrain); + default FluidStack getFluid() { + return getDelegate().getFluid(); } @Override - public int hashCode() { - return delegate.hashCode(); + default int getFluidAmount() { + return getDelegate().getFluidAmount(); } @Override - @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") - public boolean equals(Object obj) { - return this == obj || delegate.equals(obj); + default int getCapacity() { + return getDelegate().getCapacity(); } @Override - public String toString() { - return delegate.toString(); - } - - private final class FallbackTankProperty implements IFluidTankProperties { - - @Nullable - @Override - public FluidStack getContents() { - return delegate.getFluid(); - } - - @Override - public int getCapacity() { - return delegate.getCapacity(); - } - - @Override - public boolean canFill() { - return true; - } - - @Override - public boolean canDrain() { - return true; - } - - @Override - public boolean canFillFluidType(FluidStack fluidStack) { - IFilter filter = getFilter(); - return filter == null || filter.test(fluidStack); - } - - @Override - public boolean canDrainFluidType(FluidStack fluidStack) { - return true; - } + default FluidTankInfo getInfo() { + return getDelegate().getInfo(); } } } diff --git a/src/main/java/gregtech/api/capability/INotifiableHandler.java b/src/main/java/gregtech/api/capability/INotifiableHandler.java index 8dddb60482d..9a8c915e9eb 100644 --- a/src/main/java/gregtech/api/capability/INotifiableHandler.java +++ b/src/main/java/gregtech/api/capability/INotifiableHandler.java @@ -2,6 +2,8 @@ import gregtech.api.metatileentity.MetaTileEntity; +import net.minecraftforge.items.IItemHandler; + /** * For Item and Fluid handlers capable of notifying entities when * their contents change @@ -30,4 +32,12 @@ default void addToNotifiedList(MetaTileEntity metaTileEntity, T handler, boo void addNotifiableMetaTileEntity(MetaTileEntity metaTileEntity); void removeNotifiableMetaTileEntity(MetaTileEntity metaTileEntity); + + default int size() { + if (this instanceof IItemHandler handler) + return handler.getSlots(); + else if (this instanceof IMultipleTankHandler tankHandler) + return tankHandler.getTanks(); + return 1; + } } diff --git a/src/main/java/gregtech/api/capability/IQuantumController.java b/src/main/java/gregtech/api/capability/IQuantumController.java index e4ebc31ba22..45acca307c9 100644 --- a/src/main/java/gregtech/api/capability/IQuantumController.java +++ b/src/main/java/gregtech/api/capability/IQuantumController.java @@ -20,7 +20,7 @@ public interface IQuantumController extends ICapabilityProvider { BlockPos getPos(); - IDualHandler getHandler(); + DualHandler getHandler(); boolean isPowered(); diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java index e674db66763..e4dff86749b 100644 --- a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -2,6 +2,7 @@ import gregtech.api.capability.IDistillationTower; import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.pattern.BlockPattern; @@ -75,7 +76,7 @@ public void determineOrderedFluidOutputs() { // noinspection SimplifyStreamApiCallChains List fluidExportParts = tower.getMultiblockParts().stream() .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && - abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && + abilityPart.getAbilities().contains(MultiblockAbility.EXPORT_FLUIDS) && abilityPart instanceof MetaTileEntityMultiblockPart) .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) .collect(Collectors.toList()); @@ -92,11 +93,12 @@ public void determineOrderedFluidOutputs() { } MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); if (part.getPos().getY() == y) { - List hatchTanks = new ObjectArrayList<>(); + AbilityInstances hatchTanks = new AbilityInstances(MultiblockAbility.EXPORT_FLUIDS); // noinspection unchecked - ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); - orderedHandlerList.add(new FluidTankList(false, hatchTanks)); - tankList.addAll(hatchTanks); + ((IMultiblockAbilityPart) part) + .registerAbilities(hatchTanks); + orderedHandlerList.add(new FluidTankList(false, hatchTanks.cast())); + tankList.addAll(hatchTanks.cast()); exportIndex++; } else if (part.getPos().getY() > y) { orderedHandlerList.add(FakeTank.INSTANCE); diff --git a/src/main/java/gregtech/api/capability/impl/FluidTankList.java b/src/main/java/gregtech/api/capability/impl/FluidTankList.java index 29594258fb4..2895b0c0cee 100644 --- a/src/main/java/gregtech/api/capability/impl/FluidTankList.java +++ b/src/main/java/gregtech/api/capability/impl/FluidTankList.java @@ -1,5 +1,6 @@ package gregtech.api.capability.impl; +import gregtech.api.capability.IFilter; import gregtech.api.capability.IMultipleTankHandler; import net.minecraft.nbt.NBTTagCompound; @@ -8,6 +9,7 @@ import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import org.jetbrains.annotations.NotNull; @@ -20,7 +22,7 @@ public class FluidTankList implements IMultipleTankHandler, INBTSerializable { - private final MultiFluidTankEntry[] fluidTanks; + private final ITankEntry[] fluidTanks; private final boolean allowSameFluidFill; public FluidTankList(boolean allowSameFluidFill, IFluidTank... fluidTanks) { @@ -39,9 +41,9 @@ public FluidTankList(boolean allowSameFluidFill, @NotNull List list = new ArrayList<>(parent.getFluidTanks()); + ArrayList list = new ArrayList<>(parent.getFluidTanks()); for (IFluidTank tank : additionalTanks) list.add(wrapIntoEntry(tank)); - this.fluidTanks = list.toArray(new MultiFluidTankEntry[0]); + this.fluidTanks = list.toArray(new ITankEntry[0]); this.allowSameFluidFill = allowSameFluidFill; } @@ -51,7 +53,7 @@ private MultiFluidTankEntry wrapIntoEntry(IFluidTank tank) { @NotNull @Override - public List getFluidTanks() { + public List getFluidTanks() { return Collections.unmodifiableList(Arrays.asList(fluidTanks)); } @@ -62,7 +64,7 @@ public int getTanks() { @NotNull @Override - public MultiFluidTankEntry getTankAt(int index) { + public ITankEntry getTankAt(int index) { return fluidTanks[index]; } @@ -70,7 +72,7 @@ public MultiFluidTankEntry getTankAt(int index) { @Override public IFluidTankProperties[] getTankProperties() { ArrayList propertiesList = new ArrayList<>(); - for (MultiFluidTankEntry fluidTank : fluidTanks) { + for (ITankEntry fluidTank : fluidTanks) { Collections.addAll(propertiesList, fluidTank.getTankProperties()); } return propertiesList.toArray(new IFluidTankProperties[0]); @@ -91,11 +93,11 @@ public int fill(FluidStack resource, boolean doFill) { // flag value indicating whether the fluid was stored in 'distinct' slot at least once boolean distinctSlotVisited = false; - MultiFluidTankEntry[] fluidTanks = this.fluidTanks.clone(); + ITankEntry[] fluidTanks = this.fluidTanks.clone(); Arrays.sort(fluidTanks, IMultipleTankHandler.ENTRY_COMPARATOR); // search for tanks with same fluid type first - for (MultiFluidTankEntry tank : fluidTanks) { + for (ITankEntry tank : fluidTanks) { // if the fluid to insert matches the tank, insert the fluid if (resource.isFluidEqual(tank.getFluid())) { int inserted = tank.fill(resource, doFill); @@ -118,7 +120,7 @@ public int fill(FluidStack resource, boolean doFill) { } } // if we still have fluid to insert, loop through empty tanks until we find one that can accept the fluid - for (MultiFluidTankEntry tank : fluidTanks) { + for (ITankEntry tank : fluidTanks) { // if the tank uses distinct fluid fill (allowSameFluidFill disabled) and another distinct tank had // received the fluid, skip this tank boolean usesDistinctFluidFill = tank.allowSameFluidFill(); @@ -207,7 +209,7 @@ public NBTTagCompound serializeNBT() { NBTTagCompound fluidInventory = new NBTTagCompound(); NBTTagList tanks = new NBTTagList(); for (int i = 0; i < this.getTanks(); i++) { - tanks.appendTag(this.fluidTanks[i].trySerialize()); + tanks.appendTag(this.fluidTanks[i].serializeNBT()); } fluidInventory.setTag("Tanks", tanks); return fluidInventory; @@ -217,7 +219,7 @@ public NBTTagCompound serializeNBT() { public void deserializeNBT(NBTTagCompound nbt) { NBTTagList tanks = nbt.getTagList("Tanks", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < Math.min(fluidTanks.length, tanks.tagCount()); i++) { - this.fluidTanks[i].tryDeserialize(tanks.getCompoundTagAt(i)); + this.fluidTanks[i].deserializeNBT(tanks.getCompoundTagAt(i)); } } @@ -243,4 +245,117 @@ public String toString(boolean lineBreak) { if (lineBreak) stb.append('\n'); return stb.append(']').toString(); } + + /** + * Entry of multi fluid tanks. Retains reference to original {@link IMultipleTankHandler} for accessing + * information such as {@link IMultipleTankHandler#allowSameFluidFill()}. + */ + private static final class MultiFluidTankEntry implements ITankEntry { + + private final IMultipleTankHandler tank; + private final IFluidTank delegate; + private final IFluidTankProperties[] fallback; + + public MultiFluidTankEntry(@NotNull IMultipleTankHandler tank, @NotNull IFluidTank delegate) { + this.tank = tank; + this.delegate = delegate; + this.fallback = new IFluidTankProperties[] { + new FallbackTankProperty() + }; + } + + @NotNull + @Override + public IMultipleTankHandler getParent() { + return tank; + } + + @NotNull + @Override + public IFluidTank getDelegate() { + return delegate; + } + + @NotNull + public IFluidTankProperties[] getTankProperties() { + return delegate instanceof IFluidHandler fluidHandler ? + fluidHandler.getTankProperties() : fallback; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return delegate.fill(resource, doFill); + } + + @Nullable + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + if (resource == null || resource.amount <= 0) { + return null; + } + if (delegate instanceof IFluidHandler fluidHandler) { + return fluidHandler.drain(resource, doDrain); + } + // just imitate the logic + FluidStack fluid = delegate.getFluid(); + return fluid != null && fluid.isFluidEqual(resource) ? drain(resource.amount, doDrain) : null; + } + + @Nullable + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + return delegate.drain(maxDrain, doDrain); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + + @Override + @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") + public boolean equals(Object obj) { + return this == obj || delegate.equals(obj); + } + + @Override + public String toString() { + return delegate.toString(); + } + + private final class FallbackTankProperty implements IFluidTankProperties { + + @Nullable + @Override + public FluidStack getContents() { + return delegate.getFluid(); + } + + @Override + public int getCapacity() { + return delegate.getCapacity(); + } + + @Override + public boolean canFill() { + return true; + } + + @Override + public boolean canDrain() { + return true; + } + + @Override + public boolean canFillFluidType(FluidStack fluidStack) { + IFilter filter = getFilter(); + return filter == null || filter.test(fluidStack); + } + + @Override + public boolean canDrainFluidType(FluidStack fluidStack) { + return true; + } + } + } } diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index ffb12d0dcd6..4f45f7b6d45 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -90,7 +90,7 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { @NotNull public Collection getBackingHandlers() { - return Collections.unmodifiableCollection(handlerBySlotIndex.values()); + return Collections.unmodifiableCollection(baseIndexOffset.keySet()); } private boolean invalidSlot(int slot) { diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index 728ed138cc9..ba6cae067e0 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -1,6 +1,7 @@ package gregtech.api.capability.impl; import gregtech.api.GTValues; +import gregtech.api.capability.DualHandler; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.IMultiblockController; import gregtech.api.capability.IMultipleRecipeMaps; @@ -99,6 +100,21 @@ protected IMultipleTankHandler getInputTank() { return controller.getInputFluidInventory(); } + /** + * Overload of {@link #getInputTank()} to gather extra fluid tanks + * that could exist in a distinct item handler (such as a {@link DualHandler}) + * + * @param items Handler to gather fluid tanks from + * @return a new FluidTankList with extra fluid tanks on top of the existing fluid tanks + */ + protected IMultipleTankHandler getInputTank(IItemHandler items) { + var tanks = new ArrayList<>(getInputTank().getFluidTanks()); + if (items instanceof IMultipleTankHandler tankHandler) { + tanks.addAll(tankHandler.getFluidTanks()); + } + return new FluidTankList(getInputTank().allowSameFluidFill(), tanks); + } + @Override protected IMultipleTankHandler getOutputTank() { RecipeMapMultiblockController controller = (RecipeMapMultiblockController) metaTileEntity; @@ -200,7 +216,6 @@ protected void trySearchNewRecipeDistinct() { long maxVoltage = getMaxVoltage(); Recipe currentRecipe; List importInventory = getInputBuses(); - IMultipleTankHandler importFluids = getInputTank(); // Our caching implementation // This guarantees that if we get a recipe cache hit, our efficiency is no different from other machines @@ -223,7 +238,7 @@ protected void trySearchNewRecipeDistinct() { continue; } // Look for a new recipe after a cache miss - currentRecipe = findRecipe(maxVoltage, bus, importFluids); + currentRecipe = findRecipe(maxVoltage, bus, getInputTank(bus)); // Cache the current recipe, if one is found if (currentRecipe != null && checkRecipe(currentRecipe)) { this.previousRecipe = currentRecipe; @@ -253,7 +268,7 @@ public void invalidateInputs() { } protected boolean checkPreviousRecipeDistinct(IItemHandlerModifiable previousBus) { - return previousRecipe != null && previousRecipe.matches(false, previousBus, getInputTank()); + return previousRecipe != null && previousRecipe.matches(false, previousBus, getInputTank(previousBus)); } protected boolean prepareRecipeDistinct(Recipe recipe) { @@ -263,14 +278,15 @@ protected boolean prepareRecipeDistinct(Recipe recipe) { recipe = findParallelRecipe( recipe, currentDistinctInputBus, - getInputTank(), + getInputTank(currentDistinctInputBus), getOutputInventory(), getOutputTank(), getMaxParallelVoltage(), getParallelLimit()); if (recipe != null) { - recipe = setupAndConsumeRecipeInputs(recipe, currentDistinctInputBus); + recipe = setupAndConsumeRecipeInputs(recipe, currentDistinctInputBus, + getInputTank(currentDistinctInputBus)); if (recipe != null) { setupRecipe(recipe); return true; diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 9eafc841c65..21f373638fb 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -12,7 +12,6 @@ import gregtech.api.capability.impl.FluidHandlerProxy; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.ItemHandlerProxy; -import gregtech.api.capability.impl.NotifiableFluidTank; import gregtech.api.cover.Cover; import gregtech.api.cover.CoverHolder; import gregtech.api.cover.CoverRayTracer; @@ -393,26 +392,28 @@ public final String getMetaFullName() { return getMetaName() + ".name"; } - public void addNotifiedInput(T input) { + public void addNotifiedInput(Object input) { if (input instanceof IItemHandlerModifiable) { if (!notifiedItemInputList.contains(input)) { this.notifiedItemInputList.add((IItemHandlerModifiable) input); } - } else if (input instanceof IFluidHandler) { + } + if (input instanceof IFluidHandler) { if (!notifiedFluidInputList.contains(input)) { this.notifiedFluidInputList.add((IFluidHandler) input); } } } - public void addNotifiedOutput(T output) { + public void addNotifiedOutput(Object output) { if (output instanceof IItemHandlerModifiable) { if (!notifiedItemOutputList.contains(output)) { this.notifiedItemOutputList.add((IItemHandlerModifiable) output); } - } else if (output instanceof NotifiableFluidTank) { + } + if (output instanceof IFluidHandler) { if (!notifiedFluidOutputList.contains(output)) { - this.notifiedFluidOutputList.add((NotifiableFluidTank) output); + this.notifiedFluidOutputList.add((IFluidHandler) output); } } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/AbilityInstances.java b/src/main/java/gregtech/api/metatileentity/multiblock/AbilityInstances.java new file mode 100644 index 00000000000..deea075bebf --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/multiblock/AbilityInstances.java @@ -0,0 +1,127 @@ +package gregtech.api.metatileentity.multiblock; + +import gregtech.api.util.GTLog; + +import it.unimi.dsi.fastutil.objects.AbstractObjectList; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Stores a list of {@link MultiblockAbility} instances. + *
+ *
+ * Make sure to use {@link AbilityInstances#isKey(MultiblockAbility)} to check what kind of + * instances to add to this list. + */ +public class AbilityInstances extends AbstractObjectList { + + public static final AbilityInstances EMPTY = new AbilityInstances(null) { + + @Override + public boolean isKey(MultiblockAbility key) { + return false; + } + + @Override + protected boolean canAdd(Object o) { + return false; + } + + @Override + public @NotNull List cast() { + return Collections.emptyList(); + } + }; + + private final MultiblockAbility key; + private final List instances = new ArrayList<>(); + + public AbilityInstances(MultiblockAbility key) { + this.key = key; + } + + @Override + public Object get(int index) { + return instances.get(index); + } + + public boolean isKey(MultiblockAbility key) { + return this.key.equals(key); + } + + public @NotNull List cast() { + return this.key.castList(this); + } + + /** + * Adds an instance of a MultiblockAbility to this list. If the object + * passed in is a list of instances that match the key, they will all be added. + * if the object is not what the key expects, an exception will be thrown. + * + * @param o element whose class matches the type from the key + * @return true if the list was modified + */ + @Override + public boolean add(Object o) { + int s = size(); + // if what's added isn't what the key expects, + // and it's an iterable, try to add all of its elements instead + if (!canAdd(o) && o instanceof Iterableiterable) { + for (var e : iterable) + add(size(), e); + } else { + // otherwise add as normal + add(s, o); + } + return s != size(); + } + + protected boolean canAdd(Object o) { + return this.key.checkType(o); + } + + @Override + public void add(int index, Object element) { + if (canAdd(element) && !instances.contains(element)) + instances.add(index, element); + } + + /** + * Replaces the element at the index. Will throw an exception if the element is not what the key expects. + * + * @param index index of the element to replace + * @param element element to be stored at the specified position + * @return the element previously stored at the index + */ + @Override + public Object set(int index, Object element) { + if (!canAdd(element)) return null; + + int existing = instances.indexOf(element); + if (existing != -1) { + GTLog.logger.warn("attempted to set \"{}\" at index {} when we already have it at {}", + element.getClass().getSimpleName(), index, existing); + return null; + } + + return instances.set(index, element); + } + + @Override + public Object remove(int index) { + return instances.remove(index); + } + + @Override + public int size() { + return instances.size(); + } + + @Override + public String toString() { + return String.format("key{%s, %s}", this.key, super.toString()); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockAbilityPart.java b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockAbilityPart.java index d71121f196d..d66334adf4c 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockAbilityPart.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/IMultiblockAbilityPart.java @@ -1,10 +1,39 @@ package gregtech.api.metatileentity.multiblock; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; import java.util.List; public interface IMultiblockAbilityPart extends IMultiblockPart { - MultiblockAbility getAbility(); + /** + * Returns only one ability for this multiblock part. + * If you need more than one, override {@link #getAbilities()} instead. + * + * @return The MultiblockAbility this part has + */ + default @Nullable MultiblockAbility getAbility() { + return null; + } + + /** + * Returns a list of abilities that this multiblock part may have. + * + * @return a list of MultiblockAbilities + */ + default @NotNull List> getAbilities() { + return getAbility() == null ? Collections.emptyList() : Collections.singletonList(getAbility()); + } - void registerAbilities(List abilityList); + /** + * Register abilities to the multiblock here + *
+ * Check {@link AbilityInstances#isKey(MultiblockAbility) AbiliteInstances.isKey()} if you override + * {@link IMultiblockAbilityPart#getAbilities()} + * + * @param abilityInstances list to register abilities to + */ + void registerAbilities(@NotNull AbilityInstances abilityInstances); } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockAbility.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockAbility.java index 4c23893823c..340a9bf9e14 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockAbility.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockAbility.java @@ -8,73 +8,83 @@ import net.minecraftforge.items.IItemHandlerModifiable; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -@SuppressWarnings("InstantiationOfUtilityClass") public class MultiblockAbility { - public static final Map> NAME_REGISTRY = new HashMap<>(); public static final Map, List> REGISTRY = new Object2ObjectOpenHashMap<>(); - public static final MultiblockAbility EXPORT_ITEMS = new MultiblockAbility<>( - "export_items"); - public static final MultiblockAbility IMPORT_ITEMS = new MultiblockAbility<>( - "import_items"); - - public static final MultiblockAbility EXPORT_FLUIDS = new MultiblockAbility<>("export_fluids"); - public static final MultiblockAbility IMPORT_FLUIDS = new MultiblockAbility<>("import_fluids"); - - public static final MultiblockAbility INPUT_ENERGY = new MultiblockAbility<>("input_energy"); - public static final MultiblockAbility OUTPUT_ENERGY = new MultiblockAbility<>("output_energy"); - - public static final MultiblockAbility SUBSTATION_INPUT_ENERGY = new MultiblockAbility<>( - "substation_input_energy"); - public static final MultiblockAbility SUBSTATION_OUTPUT_ENERGY = new MultiblockAbility<>( - "substation_output_energy"); - - public static final MultiblockAbility ROTOR_HOLDER = new MultiblockAbility<>("rotor_holder"); - - public static final MultiblockAbility PUMP_FLUID_HATCH = new MultiblockAbility<>("pump_fluid_hatch"); - - public static final MultiblockAbility STEAM = new MultiblockAbility<>("steam"); - public static final MultiblockAbility STEAM_IMPORT_ITEMS = new MultiblockAbility<>( - "steam_import_items"); - public static final MultiblockAbility STEAM_EXPORT_ITEMS = new MultiblockAbility<>( - "steam_export_items"); - - public static final MultiblockAbility MAINTENANCE_HATCH = new MultiblockAbility<>( - "maintenance_hatch"); - public static final MultiblockAbility MUFFLER_HATCH = new MultiblockAbility<>("muffler_hatch"); - - public static final MultiblockAbility MACHINE_HATCH = new MultiblockAbility<>( - "machine_hatch"); - - public static final MultiblockAbility TANK_VALVE = new MultiblockAbility<>("tank_valve"); - - public static final MultiblockAbility PASSTHROUGH_HATCH = new MultiblockAbility<>( - "passthrough_hatch"); - - public static final MultiblockAbility DATA_ACCESS_HATCH = new MultiblockAbility<>( - "data_access_hatch"); - public static final MultiblockAbility OPTICAL_DATA_RECEPTION = new MultiblockAbility<>( - "optical_data_reception"); - public static final MultiblockAbility OPTICAL_DATA_TRANSMISSION = new MultiblockAbility<>( - "optical_data_transmission"); - public static final MultiblockAbility INPUT_LASER = new MultiblockAbility<>("input_laser"); - public static final MultiblockAbility OUTPUT_LASER = new MultiblockAbility<>("output_laser"); - - public static final MultiblockAbility COMPUTATION_DATA_RECEPTION = new MultiblockAbility<>( - "computation_data_reception"); - public static final MultiblockAbility COMPUTATION_DATA_TRANSMISSION = new MultiblockAbility<>( - "computation_data_transmission"); - - public static final MultiblockAbility HPCA_COMPONENT = new MultiblockAbility<>( - "hpca_component"); - public static final MultiblockAbility OBJECT_HOLDER = new MultiblockAbility<>("object_holder"); + public static final MultiblockAbility EXPORT_ITEMS = ability( + "export_items", IItemHandlerModifiable.class); + public static final MultiblockAbility IMPORT_ITEMS = ability( + "import_items", IItemHandlerModifiable.class); + + public static final MultiblockAbility EXPORT_FLUIDS = ability( + "export_fluids", IFluidTank.class); + public static final MultiblockAbility IMPORT_FLUIDS = ability( + "import_fluids", IFluidTank.class); + + public static final MultiblockAbility INPUT_ENERGY = ability( + "input_energy", IEnergyContainer.class); + public static final MultiblockAbility OUTPUT_ENERGY = ability( + "output_energy", IEnergyContainer.class); + + public static final MultiblockAbility SUBSTATION_INPUT_ENERGY = ability( + "substation_input_energy", IEnergyContainer.class); + public static final MultiblockAbility SUBSTATION_OUTPUT_ENERGY = ability( + "substation_output_energy", IEnergyContainer.class); + + public static final MultiblockAbility ROTOR_HOLDER = ability( + "rotor_holder", IRotorHolder.class); + + public static final MultiblockAbility PUMP_FLUID_HATCH = ability( + "pump_fluid_hatch", IFluidTank.class); + + public static final MultiblockAbility STEAM = new MultiblockAbility<>( + "steam", IFluidTank.class); + public static final MultiblockAbility STEAM_IMPORT_ITEMS = ability( + "steam_import_items", IItemHandlerModifiable.class); + public static final MultiblockAbility STEAM_EXPORT_ITEMS = ability( + "steam_export_items", IItemHandlerModifiable.class); + + public static final MultiblockAbility MAINTENANCE_HATCH = ability( + "maintenance_hatch", IMaintenanceHatch.class); + public static final MultiblockAbility MUFFLER_HATCH = ability( + "muffler_hatch", IMufflerHatch.class); + + public static final MultiblockAbility MACHINE_HATCH = ability( + "machine_hatch", IItemHandlerModifiable.class); + + public static final MultiblockAbility TANK_VALVE = ability( + "tank_valve", IFluidHandler.class); + + public static final MultiblockAbility PASSTHROUGH_HATCH = ability( + "passthrough_hatch", IPassthroughHatch.class); + + public static final MultiblockAbility DATA_ACCESS_HATCH = ability( + "data_access_hatch", IDataAccessHatch.class); + public static final MultiblockAbility OPTICAL_DATA_RECEPTION = ability( + "optical_data_reception", IOpticalDataAccessHatch.class); + public static final MultiblockAbility OPTICAL_DATA_TRANSMISSION = ability( + "optical_data_transmission", IOpticalDataAccessHatch.class); + public static final MultiblockAbility INPUT_LASER = ability( + "input_laser", ILaserContainer.class); + public static final MultiblockAbility OUTPUT_LASER = ability( + "output_laser", ILaserContainer.class); + + public static final MultiblockAbility COMPUTATION_DATA_RECEPTION = ability( + "computation_data_reception", IOpticalComputationHatch.class); + public static final MultiblockAbility COMPUTATION_DATA_TRANSMISSION = ability( + "computation_data_transmission", IOpticalComputationHatch.class); + + public static final MultiblockAbility HPCA_COMPONENT = ability( + "hpca_component", IHPCAComponentHatch.class); + public static final MultiblockAbility OBJECT_HOLDER = ability( + "object_holder", IObjectHolder.class); public static void registerMultiblockAbility(MultiblockAbility ability, MetaTileEntity part) { if (!REGISTRY.containsKey(ability)) { @@ -83,7 +93,33 @@ public static void registerMultiblockAbility(MultiblockAbility ability, MetaT REGISTRY.get(ability).add(part); } - public MultiblockAbility(String name) { - NAME_REGISTRY.put(name.toLowerCase(), this); + public static MultiblockAbility ability(String name, Class clazz) { + return new MultiblockAbility<>(name, clazz); + } + + private final String name; + private final Class clazz; + + public MultiblockAbility(String name, Class clazz) { + this.name = name.toLowerCase(); + this.clazz = clazz; + } + + @Override + public String toString() { + return name; + } + + public boolean checkType(Object o) { + return clazz.isAssignableFrom(o.getClass()); + } + + @SuppressWarnings("unchecked") + public @NotNull List castList(AbilityInstances instances) { + if (instances.isKey(this)) { + return (List) instances; + } + throw new IllegalArgumentException("Cannot cast instances of " + instances + " because they are not of " + + this.clazz.getSimpleName() + "!"); } } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java index ff3848b1557..49b277a4ff2 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockControllerBase.java @@ -80,7 +80,7 @@ public abstract class MultiblockControllerBase extends MetaTileEntity implements @Nullable public BlockPattern structurePattern; - private final Map, List> multiblockAbilities = new HashMap<>(); + private final Map, AbilityInstances> multiblockAbilities = new HashMap<>(); private final List multiblockParts = new ArrayList<>(); private boolean structureFormed; @@ -231,11 +231,17 @@ private static Supplier getCandidates(IBlockState... allowedStates) } public static TraceabilityPredicate abilities(MultiblockAbility... allowedAbilities) { - return tilePredicate((state, tile) -> tile instanceof IMultiblockAbilityPart && - ArrayUtils.contains(allowedAbilities, ((IMultiblockAbilityPart) tile).getAbility()), - getCandidates(Arrays.stream(allowedAbilities) - .flatMap(ability -> MultiblockAbility.REGISTRY.get(ability).stream()) - .toArray(MetaTileEntity[]::new))); + return tilePredicate((state, tile) -> { + if (tile instanceof IMultiblockAbilityPartabilityPart) { + for (var ability : abilityPart.getAbilities()) { + if (ArrayUtils.contains(allowedAbilities, ability)) + return true; + } + } + return false; + }, getCandidates(Arrays.stream(allowedAbilities) + .flatMap(ability -> MultiblockAbility.REGISTRY.get(ability).stream()) + .toArray(MetaTileEntity[]::new))); } public static TraceabilityPredicate states(IBlockState... allowedStates) { @@ -333,6 +339,7 @@ protected Function multiblockPartSorter() { return BlockPos::hashCode; } + @SuppressWarnings({ "rawtypes", "unchecked" }) public void checkStructurePattern() { if (structurePattern == null) return; PatternMatchContext context = structurePattern.checkPatternFastAt(getWorld(), getPos(), @@ -349,14 +356,18 @@ public void checkStructurePattern() { } this.setFlipped(context.neededFlip()); parts.sort(Comparator.comparing(it -> multiblockPartSorter().apply(((MetaTileEntity) it).getPos()))); - Map, List> abilities = new HashMap<>(); - for (IMultiblockPart multiblockPart : parts) { - if (multiblockPart instanceof IMultiblockAbilityPart) { - @SuppressWarnings("unchecked") - IMultiblockAbilityPart abilityPart = (IMultiblockAbilityPart) multiblockPart; - List abilityInstancesList = abilities.computeIfAbsent(abilityPart.getAbility(), - k -> new ArrayList<>()); - abilityPart.registerAbilities(abilityInstancesList); + Map, AbilityInstances> abilities = new HashMap<>(); + for (IMultiblockPart part : parts) { + if (part instanceof IMultiblockAbilityPart abilityPart) { + List abilityList = abilityPart.getAbilities(); + for (MultiblockAbility ability : abilityList) { + if (!checkAbilityPart(ability, ((MetaTileEntity) abilityPart).getPos())) + continue; + + AbilityInstances instances = abilities.computeIfAbsent(ability, + AbilityInstances::new); + abilityPart.registerAbilities(instances); + } } } this.multiblockParts.addAll(parts); @@ -375,6 +386,15 @@ public void checkStructurePattern() { } } + /** + * Checks if a multiblock ability at a given block pos should be added to the ability instances + * + * @return true if the ability should be added to this multiblocks ability instances + */ + protected boolean checkAbilityPart(MultiblockAbility ability, BlockPos pos) { + return true; + } + protected void formStructure(PatternMatchContext context) {} public void invalidateStructure() { @@ -394,10 +414,8 @@ public void onRemoval() { } } - @SuppressWarnings("unchecked") public List getAbilities(MultiblockAbility ability) { - List rawList = (List) multiblockAbilities.getOrDefault(ability, Collections.emptyList()); - return Collections.unmodifiableList(rawList); + return Collections.unmodifiableList(multiblockAbilities.getOrDefault(ability, AbilityInstances.EMPTY).cast()); } public List getMultiblockParts() { diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java index 8dc938db623..12c75ff27e9 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/MultiblockWithDisplayBase.java @@ -535,7 +535,8 @@ protected void setVoidingMode(int mode) { for (IFluidTank tank : this.getAbilities(MultiblockAbility.IMPORT_FLUIDS)) { this.getNotifiedFluidInputList().add((IFluidHandler) tank); } - this.getNotifiedItemInputList().addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); + this.getNotifiedItemInputList() + .addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); markDirty(); } diff --git a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java index 06032732857..02ba5655857 100644 --- a/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java +++ b/src/main/java/gregtech/api/metatileentity/multiblock/RecipeMapMultiblockController.java @@ -26,6 +26,7 @@ import net.minecraft.util.text.Style; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.items.IItemHandlerModifiable; import codechicken.lib.render.CCRenderState; @@ -47,6 +48,7 @@ public abstract class RecipeMapMultiblockController extends MultiblockWithDispla protected IItemHandlerModifiable outputInventory; protected IMultipleTankHandler inputFluidInventory; protected IMultipleTankHandler outputFluidInventory; + protected IMultipleTankHandler extendedFluidInputs; protected IEnergyContainer energyContainer; private boolean isDistinct = false; @@ -74,7 +76,10 @@ public IItemHandlerModifiable getOutputInventory() { } public IMultipleTankHandler getInputFluidInventory() { - return inputFluidInventory; + // if distinct, return the normal input fluid inventory, + // as recipe logic handles gathering extra fluids + // if not distinct, return all the fluids instead + return isDistinct() ? inputFluidInventory : extendedFluidInputs; } public IMultipleTankHandler getOutputFluidInventory() { @@ -122,6 +127,7 @@ protected void initializeAbilities() { this.inputInventory = new ItemHandlerList(getAbilities(MultiblockAbility.IMPORT_ITEMS)); this.inputFluidInventory = new FluidTankList(allowSameFluidFillForOutputs(), getAbilities(MultiblockAbility.IMPORT_FLUIDS)); + this.extendedFluidInputs = extendedImportFluidList(this.inputFluidInventory); this.outputInventory = new ItemHandlerList(getAbilities(MultiblockAbility.EXPORT_ITEMS)); this.outputFluidInventory = new FluidTankList(allowSameFluidFillForOutputs(), getAbilities(MultiblockAbility.EXPORT_FLUIDS)); @@ -135,11 +141,30 @@ protected void initializeAbilities() { private void resetTileAbilities() { this.inputInventory = new GTItemStackHandler(this, 0); this.inputFluidInventory = new FluidTankList(true); + this.extendedFluidInputs = new FluidTankList(true); this.outputInventory = new GTItemStackHandler(this, 0); this.outputFluidInventory = new FluidTankList(true); this.energyContainer = new EnergyContainerList(Lists.newArrayList()); } + protected IMultipleTankHandler extendedImportFluidList(IMultipleTankHandler fluids) { + List tanks = new ArrayList<>(fluids.getFluidTanks()); + // iterate import items to look for and tanks that we might have missed + // honestly this might not be worth checking because + // it might already be handled in ARL/MRL + for (var handler : getAbilities(MultiblockAbility.IMPORT_ITEMS)) { + if (handler instanceof IFluidTank tank) { + if (!tanks.contains(tank)) tanks.add(tank); + } else if (handler instanceof IMultipleTankHandler multipleTankHandler) { + for (var tank : multipleTankHandler.getFluidTanks()) { + if (!tanks.contains(tank)) tanks.add(tank); + } + } + } + + return new FluidTankList(allowSameFluidFillForOutputs(), tanks); + } + protected boolean allowSameFluidFillForOutputs() { return true; } @@ -254,7 +279,8 @@ public void setDistinct(boolean isDistinct) { getMultiblockParts().forEach(part -> part.onDistinctChange(isDistinct)); // mark buses as changed on distinct toggle if (this.isDistinct) { - this.notifiedItemInputList.addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); + this.notifiedItemInputList + .addAll(this.getAbilities(MultiblockAbility.IMPORT_ITEMS)); } else { this.notifiedItemInputList.add(this.inputInventory); } diff --git a/src/main/java/gregtech/api/recipes/Recipe.java b/src/main/java/gregtech/api/recipes/Recipe.java index ff495651ac5..fc275cdf52f 100644 --- a/src/main/java/gregtech/api/recipes/Recipe.java +++ b/src/main/java/gregtech/api/recipes/Recipe.java @@ -245,46 +245,40 @@ public final boolean matches(boolean consumeIfSuccessful, IItemHandlerModifiable * @return true if the recipe matches the given inputs false otherwise. */ public boolean matches(boolean consumeIfSuccessful, List inputs, List fluidInputs) { - Pair fluids = null; - Pair items = null; + if (inputs.size() == 0 && fluidInputs.size() == 0) + return false; - if (fluidInputs.size() > 0) { - fluids = matchesFluid(fluidInputs); - if (!fluids.getKey()) { - return false; - } + Pair fluids = matchesFluid(fluidInputs); + if (!fluids.getKey()) { + return false; } - if (inputs.size() > 0) { - items = matchesItems(inputs); - if (!items.getKey()) { - return false; - } + Pair items = matchesItems(inputs); + if (!items.getKey()) { + return false; } if (consumeIfSuccessful) { - if (fluids != null) { - int[] fluidAmountInTank = fluids.getValue(); + int[] fluidAmountInTank = fluids.getValue(); - for (int i = 0; i < fluidAmountInTank.length; i++) { - FluidStack fluidStack = fluidInputs.get(i); - int fluidAmount = fluidAmountInTank[i]; - if (fluidStack == null || fluidStack.amount == fluidAmount) - continue; - fluidStack.amount = fluidAmount; - if (fluidStack.amount == 0) - fluidInputs.set(i, null); - } + for (int i = 0; i < fluidAmountInTank.length; i++) { + FluidStack fluidStack = fluidInputs.get(i); + int fluidAmount = fluidAmountInTank[i]; + if (fluidStack == null || fluidStack.amount == fluidAmount) + continue; + fluidStack.amount = fluidAmount; + if (fluidStack.amount == 0) + fluidInputs.set(i, null); } - if (items != null) { - int[] itemAmountInSlot = items.getValue(); - for (int i = 0; i < itemAmountInSlot.length; i++) { - ItemStack itemInSlot = inputs.get(i); - int itemAmount = itemAmountInSlot[i]; - if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) - continue; - itemInSlot.setCount(itemAmountInSlot[i]); - } + + int[] itemAmountInSlot = items.getValue(); + + for (int i = 0; i < itemAmountInSlot.length; i++) { + ItemStack itemInSlot = inputs.get(i); + int itemAmount = itemAmountInSlot[i]; + if (itemInSlot.isEmpty() || itemInSlot.getCount() == itemAmount) + continue; + itemInSlot.setCount(itemAmountInSlot[i]); } } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 02701d9b61b..42da3a04836 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -432,7 +432,7 @@ public int size() { * modifications in list will reflect on fluid handler and wise-versa */ public static List fluidHandlerToList(IMultipleTankHandler fluidInputs) { - List backedList = fluidInputs.getFluidTanks(); + List backedList = fluidInputs.getFluidTanks(); return new AbstractList() { @Override diff --git a/src/main/java/gregtech/api/util/OverlayedFluidHandler.java b/src/main/java/gregtech/api/util/OverlayedFluidHandler.java index ece86333d65..d2d0dafb239 100644 --- a/src/main/java/gregtech/api/util/OverlayedFluidHandler.java +++ b/src/main/java/gregtech/api/util/OverlayedFluidHandler.java @@ -1,7 +1,6 @@ package gregtech.api.util; import gregtech.api.capability.IMultipleTankHandler; -import gregtech.api.capability.IMultipleTankHandler.MultiFluidTankEntry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidTankProperties; @@ -22,9 +21,9 @@ public class OverlayedFluidHandler { public OverlayedFluidHandler(@NotNull IMultipleTankHandler tank) { this.overlayedTanks = new ArrayList<>(); - MultiFluidTankEntry[] entries = tank.getFluidTanks().toArray(new MultiFluidTankEntry[0]); + var entries = tank.getFluidTanks().toArray(new IMultipleTankHandler.ITankEntry[0]); Arrays.sort(entries, IMultipleTankHandler.ENTRY_COMPARATOR); - for (MultiFluidTankEntry fluidTank : entries) { + for (var fluidTank : entries) { for (IFluidTankProperties property : fluidTank.getTankProperties()) { this.overlayedTanks.add(new OverlayedTank(property, fluidTank.allowSameFluidFill())); } diff --git a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java index 1045603125a..0f8abef5cbe 100644 --- a/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/TricorderBehavior.java @@ -296,9 +296,9 @@ else if (metaTileEntity instanceof IDataInfoProvider) GTValues.VNF[tier])); var handler = quantumController.getHandler(); list.add(new TextComponentTranslation("behavior.tricorder.quantum_controller.connected_items", - TextFormatting.RED.toString() + handler.getItemHandlers().getSlots())); + TextFormatting.RED.toString() + handler.getItemDelegate().getSlots())); list.add(new TextComponentTranslation("behavior.tricorder.quantum_controller.connected_fluids", - TextFormatting.RED.toString() + handler.getFluidTanks().getTanks())); + TextFormatting.RED.toString() + handler.getFluidDelegate().getTanks())); } else if (metaTileEntity instanceof IQuantumStoragestorage) { var qcontrollor = storage.getQuantumController(); if (qcontrollor != null) { diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 1e13f91f1fe..9bfa01652e6 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -1304,7 +1304,8 @@ public static void registerMetaTileEntities( */ public static @NotNull T registerMetaTileEntity(int id, @NotNull T mte) { if (mte instanceof IMultiblockAbilityPartabilityPart) { - MultiblockAbility.registerMultiblockAbility(abilityPart.getAbility(), mte); + for (var ability : abilityPart.getAbilities()) + MultiblockAbility.registerMultiblockAbility(ability, mte); } if (Mods.JustEnoughItems.isModLoaded() && mte instanceof MultiblockControllerBase controller && diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java index 8512fbb181f..de11fab72e4 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; @@ -182,8 +183,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java index 328c9d08884..bc194d85474 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityHull.java @@ -5,6 +5,7 @@ import gregtech.api.capability.impl.EnergyContainerHandler; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; @@ -110,8 +111,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityRockBreaker.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityRockBreaker.java index 7ff2b055358..db5f83778f6 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityRockBreaker.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityRockBreaker.java @@ -75,7 +75,7 @@ private void checkAdjacentFluids() { } @Override - public void addNotifiedInput(T input) { + public void addNotifiedInput(Object input) { super.addNotifiedInput(input); onNeighborChanged(); } diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java index bbdfff7ae9d..a17b955729c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityPumpHatch.java @@ -5,6 +5,7 @@ import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.mui.GTGuiTextures; @@ -41,6 +42,7 @@ import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.RichTextWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -112,8 +114,8 @@ public ICubeRenderer getBaseTexture() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(exportFluids.getTankAt(0)); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(exportFluids.getTankAt(0)); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java index 13f9c9657f3..231a19fee37 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java +++ b/src/main/java/gregtech/common/metatileentities/multi/MetaTileEntityTankValve.java @@ -4,6 +4,7 @@ import gregtech.api.capability.impl.FluidTankList; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -122,8 +123,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this.getImportFluids()); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this.getImportFluids()); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java index c1ac8373b43..1159bbb558c 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityAutoMaintenanceHatch.java @@ -3,6 +3,7 @@ import gregtech.api.capability.IMaintenanceHatch; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; @@ -20,6 +21,7 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -104,8 +106,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java index 85c2bc25173..61c7e343392 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityComputationHatch.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IOpticalComputationProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.util.GTLog; @@ -151,8 +152,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java index a50acc06ba0..ee036b768a2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityDataAccessHatch.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -213,8 +214,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java index 5d0b13fc491..489afffac1f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityEnergyHatch.java @@ -8,6 +8,7 @@ import gregtech.api.capability.impl.EnergyContainerHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.util.GTUtility; @@ -116,8 +117,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(energyContainer); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(energyContainer); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 4cb1dd3003e..85519ccfda7 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -1,16 +1,25 @@ package gregtech.common.metatileentities.multi.multiblockpart; -import gregtech.api.capability.*; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IControllable; +import gregtech.api.capability.IFilter; +import gregtech.api.capability.IFilteredFluidContainer; +import gregtech.api.capability.IGhostSlotConfigurable; import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; import gregtech.api.capability.impl.NotifiableFluidTank; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; +import gregtech.api.mui.widget.GhostCircuitSlotWidget; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.metatileentities.MetaTileEntities; @@ -51,16 +60,20 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiablePart - implements IMultiblockAbilityPart, IControllable { + implements IMultiblockAbilityPart, IControllable, + IGhostSlotConfigurable { public static final int INITIAL_INVENTORY_SIZE = 8000; // only holding this for convenience protected final HatchFluidTank fluidTank; protected boolean workingEnabled; + private GhostCircuitItemStackHandler circuitInventory; // export hatch-only fields protected boolean locked; @@ -70,8 +83,33 @@ public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiable public MetaTileEntityFluidHatch(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) { super(metaTileEntityId, tier, isExportHatch); this.fluidTank = new HatchFluidTank(getInventorySize(), this, isExportHatch); + initializeInventory(); // the fact that this has to be called three times is so dumb this.workingEnabled = true; - initializeInventory(); + } + + @Override + protected void initializeInventory() { + super.initializeInventory(); + if (this.hasGhostCircuitInventory()) { + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + } + } + + @Override + public boolean hasGhostCircuitInventory() { + return !isExportHatch; + } + + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory == null || this.circuitInventory.getCircuitValue() == config) { + return; + } + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); + } } @Override @@ -88,6 +126,8 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { if (locked && lockedFluid != null) { data.setTag("LockedFluid", lockedFluid.writeToNBT(new NBTTagCompound())); } + } else { + this.circuitInventory.write(data); } return data; } @@ -106,6 +146,8 @@ public void readFromNBT(NBTTagCompound data) { this.locked = data.getBoolean("IsLocked"); this.lockedFluid = this.locked ? FluidStack.loadFluidStackFromNBT(data.getCompoundTag("LockedFluid")) : null; + } else { + this.circuitInventory.read(data); } } @@ -153,6 +195,8 @@ public void writeInitialSyncData(PacketBuffer buf) { buf.writeBoolean(workingEnabled); if (isExportHatch) { buf.writeBoolean(locked); + } else { + buf.writeVarInt(this.circuitInventory.getCircuitValue()); } } @@ -162,6 +206,8 @@ public void receiveInitialSyncData(PacketBuffer buf) { this.workingEnabled = buf.readBoolean(); if (isExportHatch) { this.locked = buf.readBoolean(); + } else { + setGhostCircuitConfig(buf.readVarInt()); } } @@ -213,13 +259,20 @@ protected IItemHandlerModifiable createExportItemHandler() { } @Override - public MultiblockAbility getAbility() { - return isExportHatch ? MultiblockAbility.EXPORT_FLUIDS : MultiblockAbility.IMPORT_FLUIDS; + public @NotNull List> getAbilities() { + return isExportHatch ? + Collections.singletonList(MultiblockAbility.EXPORT_FLUIDS) : + Arrays.asList(MultiblockAbility.IMPORT_FLUIDS, MultiblockAbility.IMPORT_ITEMS); } @Override - public void registerAbilities(List abilityList) { - abilityList.add(fluidTank); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + if (abilityInstances.isKey(MultiblockAbility.EXPORT_FLUIDS) || + abilityInstances.isKey(MultiblockAbility.IMPORT_FLUIDS)) { + abilityInstances.add(this.fluidTank); + } else if (abilityInstances.isKey(MultiblockAbility.IMPORT_ITEMS)) { + abilityInstances.add(this.circuitInventory); + } } @Override @@ -250,8 +303,6 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .childIf(isExportHatch, new ToggleButton() .pos(7, 63) .overlay(GTGuiTextures.BUTTON_LOCK) - // todo doing things this way causes flickering if it fails - // due to sync value cache .value(new BooleanSyncValue(this::isLocked, b -> fluidSyncHandler.lockFluid(b, false))) .addTooltip(true, IKey.lang("gregtech.gui.fluid_lock.tooltip.enabled")) .addTooltip(false, IKey.lang("gregtech.gui.fluid_lock.tooltip.disabled"))) @@ -265,6 +316,10 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) .slot(new ModularSlot(exportItems, 0) .accessibility(false, true))) + .childIf(!isExportHatch, new GhostCircuitSlotWidget() + .slot(circuitInventory, 0) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY) + .pos(124, 62)) // common ui .child(new RichTextWidget() @@ -304,6 +359,20 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .bindPlayerInventory(); } + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + if (hasGhostCircuitInventory()) + this.circuitInventory.addNotifiableMetaTileEntity(controllerBase); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + if (hasGhostCircuitInventory()) + this.circuitInventory.removeNotifiableMetaTileEntity(controllerBase); + } + @Override public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 37c145eab75..16a9a8bcf6d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -8,6 +8,7 @@ import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -255,11 +256,11 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { } @Override - public void registerAbilities(List abilityList) { + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { if (this.hasGhostCircuitInventory() && this.actualImportItems != null) { - abilityList.add(isExportHatch ? this.exportItems : this.actualImportItems); + abilityInstances.add(isExportHatch ? this.exportItems : this.actualImportItems); } else { - abilityList.add(isExportHatch ? this.exportItems : this.importItems); + abilityInstances.add(isExportHatch ? this.exportItems : this.importItems); } } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java index 3d594d4827d..38e1dbdcd31 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityLaserHatch.java @@ -6,6 +6,7 @@ import gregtech.api.metatileentity.IDataInfoProvider; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; @@ -71,8 +72,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this.buffer); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this.buffer); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java index 46f47cf3928..ba324cf1dff 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMachineHatch.java @@ -4,6 +4,7 @@ import gregtech.api.metatileentity.IMachineHatchMultiblock; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -58,8 +59,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(machineHandler); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(machineHandler); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java index 6c8e3cd2e97..8f6a37b55c2 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMaintenanceHatch.java @@ -14,10 +14,7 @@ import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMaintenance; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; -import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.metatileentity.multiblock.*; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.TooltipHelper; @@ -516,8 +513,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java index 2d53b425b5f..c8fea455e34 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMufflerHatch.java @@ -6,9 +6,7 @@ import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; -import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.metatileentity.multiblock.*; import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -145,8 +143,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java index ff1b2341f32..2501b75a8db 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java @@ -7,6 +7,7 @@ import gregtech.api.capability.impl.NotifiableFluidTank; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.mui.GTGuis; @@ -37,6 +38,7 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.layout.Grid; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -199,8 +201,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.addAll(fluidTankList.getFluidTanks()); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.addAll(fluidTankList.getFluidTanks()); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java index 1d3d2be909f..7efd88c5471 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiblockNotifiablePart.java @@ -3,7 +3,7 @@ import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.INotifiableHandler; import gregtech.api.capability.impl.FluidTankList; -import gregtech.api.capability.impl.NotifiableItemStackHandler; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import net.minecraft.util.ResourceLocation; @@ -21,16 +21,21 @@ public MetaTileEntityMultiblockNotifiablePart(ResourceLocation metaTileEntityId, this.isExportHatch = isExportHatch; } - private NotifiableItemStackHandler getItemHandler() { - NotifiableItemStackHandler handler = null; - if (isExportHatch && getExportItems() instanceof NotifiableItemStackHandler) { - handler = (NotifiableItemStackHandler) getExportItems(); - } else if (!isExportHatch && getImportItems() instanceof NotifiableItemStackHandler) { - handler = (NotifiableItemStackHandler) getImportItems(); - } else if (getItemInventory() instanceof NotifiableItemStackHandler) { - handler = (NotifiableItemStackHandler) getItemInventory(); + private List getItemHandlers() { + List notifiables = new ArrayList<>(); + var mteHandler = isExportHatch ? getExportItems() : getImportItems(); + if (mteHandler instanceof INotifiableHandler notifiable) { + notifiables.add(notifiable); + } else if (mteHandler instanceof ItemHandlerList list) { + for (var handler : list.getBackingHandlers()) { + if (handler instanceof INotifiableHandler notifiable) + notifiables.add(notifiable); + } } - return handler; + if (getItemInventory() instanceof INotifiableHandler notifiable) { + notifiables.add(notifiable); + } + return notifiables; } private FluidTankList getFluidHandlers() { @@ -46,16 +51,17 @@ private FluidTankList getFluidHandlers() { private List getPartHandlers() { List handlerList = new ArrayList<>(); - NotifiableItemStackHandler itemHandler = getItemHandler(); - if (itemHandler != null && itemHandler.getSlots() > 0) { - handlerList.add(itemHandler); + for (var notif : getItemHandlers()) { + if (notif.size() > 0) { + handlerList.add(notif); + } } if (this.fluidInventory.getTankProperties().length > 0) { FluidTankList fluidTankList = getFluidHandlers(); if (fluidTankList != null) { for (IFluidTank fluidTank : fluidTankList) { - if (fluidTank instanceof IMultipleTankHandler.MultiFluidTankEntry entry) { + if (fluidTank instanceof IMultipleTankHandler.ITankEntry entry) { fluidTank = entry.getDelegate(); } if (fluidTank instanceof INotifiableHandler) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java index d358d7eccc7..568e897c850 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityObjectHolder.java @@ -9,6 +9,7 @@ import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -115,8 +116,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java index b86782957d2..204dfd6c9c6 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityOpticalDataHatch.java @@ -6,6 +6,7 @@ import gregtech.api.capability.IOpticalDataAccessHatch; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -128,8 +129,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchFluid.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchFluid.java index 5305afee5e5..14c86351976 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchFluid.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchFluid.java @@ -9,6 +9,7 @@ import gregtech.api.capability.impl.NotifiableItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; @@ -208,8 +209,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java index 7f9e5dc3b1c..a5be8680efa 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityPassthroughHatchItem.java @@ -8,6 +8,7 @@ import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IPassthroughHatch; import gregtech.api.metatileentity.multiblock.MultiblockAbility; @@ -220,8 +221,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @NotNull diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java index e91f6e4f05d..83488327c26 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityReservoirHatch.java @@ -1,22 +1,28 @@ package gregtech.common.metatileentities.multi.multiblockpart; import gregtech.api.GTValues; +import gregtech.api.capability.IGhostSlotConfigurable; import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.GhostCircuitItemStackHandler; import gregtech.api.capability.impl.NotifiableFluidTank; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.mui.sync.GTFluidSyncHandler; +import gregtech.api.mui.widget.GhostCircuitSlotWidget; import gregtech.client.renderer.texture.Textures; import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; @@ -46,13 +52,16 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.List; public class MetaTileEntityReservoirHatch extends MetaTileEntityMultiblockNotifiablePart - implements IMultiblockAbilityPart { + implements IMultiblockAbilityPart, + IGhostSlotConfigurable { private static final int FLUID_AMOUNT = 2_000_000_000; private final InfiniteWaterTank fluidTank; + private GhostCircuitItemStackHandler circuitInventory; public MetaTileEntityReservoirHatch(ResourceLocation metaTileEntityId) { super(metaTileEntityId, GTValues.EV, false); @@ -65,6 +74,13 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityReservoirHatch(metaTileEntityId); } + @Override + protected void initializeInventory() { + super.initializeInventory(); + this.circuitInventory = new GhostCircuitItemStackHandler(this); + this.circuitInventory.addNotifiableMetaTileEntity(this); + } + @Override public void update() { super.update(); @@ -114,13 +130,17 @@ protected IItemHandlerModifiable createExportItemHandler() { } @Override - public MultiblockAbility getAbility() { - return MultiblockAbility.IMPORT_FLUIDS; + public @NotNull List> getAbilities() { + return Arrays.asList(MultiblockAbility.IMPORT_FLUIDS, MultiblockAbility.IMPORT_ITEMS); } @Override - public void registerAbilities(List abilityList) { - abilityList.add(fluidTank); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + if (abilityInstances.isKey(MultiblockAbility.IMPORT_FLUIDS)) + abilityInstances.add(fluidTank); + else if (abilityInstances.isKey(MultiblockAbility.IMPORT_ITEMS)) { + abilityInstances.add(circuitInventory); + } } @Override @@ -172,7 +192,11 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .slotGroup("item_inv") .accessibility(false, true)) .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) - .pos(90, 53)); + .pos(90, 53)) + .child(new GhostCircuitSlotWidget() + .slot(circuitInventory, 0) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY) + .pos(124, 62)); } @Override @@ -188,6 +212,58 @@ public void addToolUsages(ItemStack stack, @Nullable World world, List t super.addToolUsages(stack, world, tooltip, advanced); } + @Override + public boolean hasGhostCircuitInventory() { + return true; + } + + @Override + public void setGhostCircuitConfig(int config) { + if (this.circuitInventory.getCircuitValue() == config) { + return; + } + this.circuitInventory.setCircuitValue(config); + if (!getWorld().isRemote) { + markDirty(); + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + this.circuitInventory.write(data); + return super.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + this.circuitInventory.read(data); + super.readFromNBT(data); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeVarInt(this.circuitInventory.getCircuitValue()); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + setGhostCircuitConfig(buf.readVarInt()); + } + + @Override + public void addToMultiBlock(MultiblockControllerBase controllerBase) { + super.addToMultiBlock(controllerBase); + this.circuitInventory.addNotifiableMetaTileEntity(controllerBase); + } + + @Override + public void removeFromMultiBlock(MultiblockControllerBase controllerBase) { + super.removeFromMultiBlock(controllerBase); + this.circuitInventory.removeNotifiableMetaTileEntity(controllerBase); + } + private static class InfiniteWaterTank extends NotifiableFluidTank { public InfiniteWaterTank(int capacity, MetaTileEntity entityToNotify) { diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java index 7f3c732270e..9401664249d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityRotorHolder.java @@ -8,6 +8,7 @@ import gregtech.api.metatileentity.ITieredMetaTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.mui.GTGuiTextures; @@ -165,8 +166,8 @@ void setRotorSpinning(boolean spinning) { } @Override - public void registerAbilities(@NotNull List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java index b1e53f22f4a..23f1ab2899b 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputBus.java @@ -15,6 +15,7 @@ import gregtech.api.gui.widgets.SlotWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -330,8 +331,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List list) { - list.add(this.actualImportItems); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this.actualImportItems); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java index 2bcdc10f542..120b25e8827 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEInputHatch.java @@ -10,6 +10,7 @@ import gregtech.api.gui.widgets.ImageWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.client.renderer.texture.Textures; @@ -270,8 +271,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List list) { - list.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.addAll(Arrays.asList(this.getAEFluidHandler().getInventory())); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java index 9e008b857e3..de44e64b339 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputBus.java @@ -8,10 +8,7 @@ import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; -import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.metatileentity.multiblock.*; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEItemGridWidget; import gregtech.common.inventory.appeng.SerializableItemList; @@ -196,8 +193,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(new InaccessibleInfiniteSlot(this, this.internalBuffer, this.getController())); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(new InaccessibleInfiniteSlot(this, this.internalBuffer, this.getController())); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java index 26a8fcc7947..77ba57bf656 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/appeng/MetaTileEntityMEOutputHatch.java @@ -8,10 +8,7 @@ import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; -import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; -import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.metatileentity.multiblock.*; import gregtech.client.renderer.texture.Textures; import gregtech.common.gui.widget.appeng.AEFluidGridWidget; import gregtech.common.inventory.appeng.SerializableFluidList; @@ -198,8 +195,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List list) { - list.add(new InaccessibleInfiniteTank(this, this.internalBuffer, this.getController())); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(new InaccessibleInfiniteTank(this, this.internalBuffer, this.getController())); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java index dba69e698e8..c70e83674cd 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/hpca/MetaTileEntityHPCAComponent.java @@ -5,6 +5,7 @@ import gregtech.api.capability.IHPCAComponentHatch; import gregtech.api.capability.IHPCAComputationProvider; import gregtech.api.capability.IHPCACoolantProvider; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.unification.material.Materials; @@ -67,8 +68,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(this); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(this); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java index cdcad82843f..bacb525a3aa 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java +++ b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamHatch.java @@ -7,6 +7,7 @@ import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -45,6 +46,7 @@ import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.RichTextWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -128,8 +130,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.addAll(this.importFluids.getFluidTanks()); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.addAll(this.importFluids.getFluidTanks()); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java index 56b15d8c93f..633ca974bac 100644 --- a/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/steam/multiblockpart/MetaTileEntitySteamItemBus.java @@ -2,6 +2,7 @@ import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.metatileentity.multiblock.AbilityInstances; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; import gregtech.api.mui.GTGuiTheme; @@ -56,8 +57,8 @@ public MultiblockAbility getAbility() { } @Override - public void registerAbilities(List abilityList) { - abilityList.add(isExportHatch ? this.exportItems : this.importItems); + public void registerAbilities(@NotNull AbilityInstances abilityInstances) { + abilityInstances.add(isExportHatch ? this.exportItems : this.importItems); } // Override base texture to have a bus with 4 slots, but ULV textures diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java index cc37c7385ca..8e06b8d6f38 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumExtender.java @@ -1,7 +1,7 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.capability.DualHandler; import gregtech.api.capability.GregtechDataCodes; -import gregtech.api.capability.IDualHandler; import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -21,7 +21,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; -public class MetaTileEntityQuantumExtender extends MetaTileEntityQuantumStorage { +public class MetaTileEntityQuantumExtender extends MetaTileEntityQuantumStorage { public MetaTileEntityQuantumExtender(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -69,7 +69,7 @@ public Type getType() { } @Override - public IDualHandler getTypeValue() { + public DualHandler getTypeValue() { return null; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java index 42deb4d91aa..a3ca7fa92d5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumProxy.java @@ -1,6 +1,6 @@ package gregtech.common.metatileentities.storage; -import gregtech.api.capability.IDualHandler; +import gregtech.api.capability.DualHandler; import gregtech.api.capability.IQuantumController; import gregtech.api.gui.ModularUI; import gregtech.api.metatileentity.MetaTileEntity; @@ -24,7 +24,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; -public class MetaTileEntityQuantumProxy extends MetaTileEntityQuantumStorage { +public class MetaTileEntityQuantumProxy extends MetaTileEntityQuantumStorage { public MetaTileEntityQuantumProxy(ResourceLocation metaTileEntityId) { super(metaTileEntityId); @@ -89,7 +89,7 @@ public Type getType() { } @Override - public IDualHandler getTypeValue() { + public DualHandler getTypeValue() { var controller = getPoweredController(); if (controller == null) return null; return controller.getHandler(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java index 4bc6473d713..978fb816c46 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java @@ -1,9 +1,10 @@ package gregtech.common.metatileentities.storage; import gregtech.api.GTValues; +import gregtech.api.capability.DualHandler; import gregtech.api.capability.GregtechDataCodes; -import gregtech.api.capability.IDualHandler; import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.IQuantumController; import gregtech.api.capability.IQuantumStorage; import gregtech.api.capability.impl.EnergyContainerList; @@ -33,6 +34,8 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.ColourMultiplier; @@ -331,7 +334,7 @@ public void rebuildNetwork() { } storage.setDisconnected(); } - handler.rebuildCache(); + handler.markDirty(); onHandlerUpdate(); calculateEnergyUsage(); markDirty(); @@ -440,9 +443,9 @@ public void readFromNBT(NBTTagCompound data) { public T getCapability(@NotNull Capability capability, EnumFacing side) { if (isPowered()) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && handler.hasItemHandlers()) { - return (T) handler.getItemHandlers(); + return (T) handler.getItemDelegate(); } else if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY && handler.hasFluidTanks()) { - return (T) handler.getFluidTanks(); + return (T) handler.getFluidDelegate(); } } @@ -456,22 +459,23 @@ public void addInformation(ItemStack stack, @Nullable World world, @NotNull List } @Override - public IDualHandler getHandler() { + public DualHandler getHandler() { return this.handler; } - // todo use DualHandler instead once the multis ability pr is merged - private class QuantumControllerHandler implements IDualHandler { + private class QuantumControllerHandler extends DualHandler { - // IFluidHandler saved values - private FluidTankList fluidTanks; + private static final IItemHandlerModifiable EMPTY_ITEM = new ItemStackHandler(0); + private static final IMultipleTankHandler EMPTY_TANK = new FluidTankList(false); + private boolean dirty = true; - // IItemHandler saved values - private ItemHandlerList itemHandlers; + public QuantumControllerHandler() { + super(EMPTY_ITEM, EMPTY_TANK, true); + } private void invalidate() { - fluidTanks = new FluidTankList(false); - itemHandlers = new ItemHandlerList(Collections.emptyList()); + fluidDelegate = EMPTY_TANK; + itemDelegate = EMPTY_ITEM; } private void rebuildCache() { @@ -487,34 +491,23 @@ private void rebuildCache() { } // todo allow this "allowSameFluidFill" to be configured in this controller? - this.fluidTanks = new FluidTankList(false, fluidTankList); - this.itemHandlers = new ItemHandlerList(itemHandlerList); + this.fluidDelegate = new FluidTankList(false, fluidTankList); + this.itemDelegate = new ItemHandlerList(itemHandlerList); + this.dirty = false; } - @Override - public boolean hasFluidTanks() { - return getFluidTanks().getTanks() > 0; + public void markDirty() { + this.dirty = true; } - @Override public boolean hasItemHandlers() { - return !getItemHandlers().getBackingHandlers().isEmpty(); + if (dirty) rebuildCache(); + return getSlots() > 0; } - @Override - public FluidTankList getFluidTanks() { - if (fluidTanks == null) { - rebuildCache(); - } - return fluidTanks; - } - - @Override - public ItemHandlerList getItemHandlers() { - if (itemHandlers == null) { - rebuildCache(); - } - return itemHandlers; + public boolean hasFluidTanks() { + if (dirty) rebuildCache(); + return getTanks() > 0; } } } diff --git a/src/test/java/gregtech/api/capability/impl/FluidTankListTest.java b/src/test/java/gregtech/api/capability/impl/FluidTankListTest.java index a734933b9fe..c6a04043724 100644 --- a/src/test/java/gregtech/api/capability/impl/FluidTankListTest.java +++ b/src/test/java/gregtech/api/capability/impl/FluidTankListTest.java @@ -1,7 +1,6 @@ package gregtech.api.capability.impl; import gregtech.Bootstrap; -import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.unification.material.Materials; import gregtech.api.util.OverlayedFluidHandler; @@ -409,7 +408,7 @@ FluidHandlerTester expectContents(@NotNull FluidStack... optionalFluidStacks) { "expected: " + this.tank.getTanks() + ", provided: " + optionalFluidStacks.length); } for (int i = 0; i < optionalFluidStacks.length; i++) { - IMultipleTankHandler.MultiFluidTankEntry tank = this.tank.getTankAt(i); + var tank = this.tank.getTankAt(i); if (!eq(tank.getFluid(), optionalFluidStacks[i])) { throw new AssertionError("Contents of the tank don't match expected state.\n" + "Expected: [\n " + Arrays.stream(optionalFluidStacks)