Fix ME Fluid Interface not requesting crafting for missing fluids (#452)

This commit is contained in:
Eldrinn-Elantey authored and GitHub committed 2026-07-30 19:53:09 +07:00
1 parent 2352510223
commit 8d7bde168d
5 files changed
+179 -13

No files matched your search

@@ -27,9 +27,12 @@ import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.DualHostSettings;
import com.glodblock.github.util.DualityFluidInterface;
import com.glodblock.github.util.Util;
import com.google.common.collect.ImmutableSet;
import appeng.api.config.Actionable;
import appeng.api.config.Upgrades;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -37,6 +40,7 @@ import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IAEStackType;
import appeng.helpers.ICustomButtonDataObject;
import appeng.helpers.ICustomButtonProvider;
@@ -149,6 +153,7 @@ public class PartFluidInterface extends PartInterface implements IDualHost, ICus
config.readFromNBT(data, "ConfigInv");
fluidDuality.loadConfigFromPacket(this.config);
getInternalFluid().readFromNBT(data, "FluidInv");
fluidDuality.readCraftingTrackerFromNBT(data);
}
@Override
@@ -156,6 +161,7 @@ public class PartFluidInterface extends PartInterface implements IDualHost, ICus
super.writeToNBT(data);
config.writeToNBT(data, "ConfigInv");
getInternalFluid().writeToNBT(data, "FluidInv");
fluidDuality.writeCraftingTrackerToNBT(data);
}
@Override
@@ -177,6 +183,26 @@ public class PartFluidInterface extends PartInterface implements IDualHost, ICus
return getInterfaceDuality().getInstalledUpgrades(u);
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return ImmutableSet.<ICraftingLink>builder().addAll(super.getRequestedJobs())
.addAll(fluidDuality.getRequestedJobs()).build();
}
@Override
public IAEStack<?> injectCraftedItems(final ICraftingLink link, final IAEStack<?> items, final Actionable mode) {
if (items instanceof IAEFluidStack) {
return fluidDuality.injectCraftedItems(link, items, mode);
}
return super.injectCraftedItems(link, items, mode);
}
@Override
public void jobStateChange(final ICraftingLink link) {
super.jobStateChange(link);
fluidDuality.jobStateChange(link);
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return fluidDuality.fill(from, resource, doFill);
@@ -28,13 +28,17 @@ import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.DualHostSettings;
import com.glodblock.github.util.DualityFluidInterface;
import com.glodblock.github.util.Util;
import com.google.common.collect.ImmutableSet;
import appeng.api.config.Actionable;
import appeng.api.implementations.items.IMemoryCard;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IAEStackType;
import appeng.api.util.IConfigManager;
import appeng.helpers.DualityInterface;
@@ -118,6 +122,23 @@ public class PartFluidP2PInterface extends PartP2PInterface implements IDualHost
return output;
}
@Override
public void readFromNBT(final NBTTagCompound data) {
super.readFromNBT(data);
config.readFromNBT(data, "ConfigInv");
dualityFluid.loadConfigFromPacket(this.config);
dualityFluid.getInternalFluid().readFromNBT(data, "FluidInv");
dualityFluid.readCraftingTrackerFromNBT(data);
}
@Override
public void writeToNBT(final NBTTagCompound data) {
super.writeToNBT(data);
config.writeToNBT(data, "ConfigInv");
dualityFluid.getInternalFluid().writeToNBT(data, "FluidInv");
dualityFluid.writeCraftingTrackerToNBT(data);
}
@Override
public TickingRequest getTickingRequest(IGridNode node) {
TickingRequest item = duality.getTickingRequest(node);
@@ -140,6 +161,26 @@ public class PartFluidP2PInterface extends PartP2PInterface implements IDualHost
}
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return ImmutableSet.<ICraftingLink>builder().addAll(super.getRequestedJobs())
.addAll(dualityFluid.getRequestedJobs()).build();
}
@Override
public IAEStack<?> injectCraftedItems(final ICraftingLink link, final IAEStack<?> items, final Actionable mode) {
if (items instanceof IAEFluidStack) {
return dualityFluid.injectCraftedItems(link, items, mode);
}
return super.injectCraftedItems(link, items, mode);
}
@Override
public void jobStateChange(final ICraftingLink link) {
super.jobStateChange(link);
dualityFluid.jobStateChange(link);
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return dualityFluid.fill(from, resource, doFill);
@@ -28,11 +28,14 @@ import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.DualHostSettings;
import com.glodblock.github.util.DualityFluidInterface;
import com.glodblock.github.util.Util;
import com.google.common.collect.ImmutableSet;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.config.SidelessMode;
import appeng.api.config.Upgrades;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -40,6 +43,7 @@ import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IAEStackType;
import appeng.api.util.IConfigManager;
import appeng.helpers.ICustomButtonDataObject;
@@ -180,12 +184,14 @@ public class TileFluidInterface extends TileInterface implements IDualHost, ICus
config.readFromNBT(data, "ConfigInv");
fluidDuality.loadConfigFromPacket(this.config);
getInternalFluid().readFromNBT(data, "FluidInv");
fluidDuality.readCraftingTrackerFromNBT(data);
}
@TileEvent(TileEventType.WORLD_NBT_WRITE)
public NBTTagCompound writeToNBTEvent(NBTTagCompound data) {
config.writeToNBT(data, "ConfigInv");
getInternalFluid().writeToNBT(data, "FluidInv");
fluidDuality.writeCraftingTrackerToNBT(data);
return data;
}
@@ -216,6 +222,26 @@ public class TileFluidInterface extends TileInterface implements IDualHost, ICus
return getInterfaceDuality().getInstalledUpgrades(u);
}
@Override
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return ImmutableSet.<ICraftingLink>builder().addAll(super.getRequestedJobs())
.addAll(fluidDuality.getRequestedJobs()).build();
}
@Override
public IAEStack<?> injectCraftedItems(final ICraftingLink link, final IAEStack<?> items, final Actionable mode) {
if (items instanceof IAEFluidStack) {
return fluidDuality.injectCraftedItems(link, items, mode);
}
return super.injectCraftedItems(link, items, mode);
}
@Override
public void jobStateChange(final ICraftingLink link) {
super.jobStateChange(link);
fluidDuality.jobStateChange(link);
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return fluidDuality.fill(from, resource, doFill);
@@ -6,7 +6,6 @@ import static appeng.util.item.AEItemStackType.ITEM_STACK_TYPE;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@@ -26,12 +25,14 @@ import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.AEFluidInventory;
import com.glodblock.github.inventory.IAEFluidInventory;
import com.glodblock.github.inventory.IAEFluidTank;
import com.google.common.collect.ImmutableSet;
import appeng.api.config.Actionable;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.BaseActionSource;
@@ -46,10 +47,12 @@ import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.data.AEStackTypeRegistry;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IAEStackType;
import appeng.api.util.IConfigManager;
import appeng.core.settings.TickRates;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.MultiCraftingTracker;
import appeng.me.GridAccessException;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.storage.MEMonitorIFluidHandler;
@@ -75,6 +78,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
private final IAEFluidStack[] requireWork;
private int isWorking = -1;
private final Map<IAEStackType<?>, MEMonitorPassThrough<?>> monitorMap;
private final MultiCraftingTracker craftingTracker;
public DualityFluidInterface(final AENetworkProxy networkProxy, final IInterfaceHost ih) {
this.gridProxy = networkProxy;
@@ -94,6 +98,8 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
for (int i = 0; i < 6; ++i) {
this.requireWork[i] = null;
}
this.craftingTracker = new MultiCraftingTracker(this.iHost, NUMBER_OF_TANKS);
}
public IAEFluidStack getStandardFluid(IAEFluidStack fluid) {
@@ -147,6 +153,18 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
this.readConfig();
}
public void writeCraftingTrackerToNBT(NBTTagCompound data) {
final NBTTagCompound tracker = new NBTTagCompound();
this.craftingTracker.writeToNBT(tracker);
data.setTag("fluidCraftingLinks", tracker);
}
public void readCraftingTrackerFromNBT(NBTTagCompound data) {
if (data.hasKey("fluidCraftingLinks")) {
this.craftingTracker.readFromNBT(data.getCompoundTag("fluidCraftingLinks"));
}
}
public void writeConfigToNBT(NBTTagCompound data, String name) {
this.config.writeToNBT(data, name);
}
@@ -182,7 +200,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
@Override
public int getInstalledUpgrades(Upgrades u) {
return 0;
return this.iHost.getInstalledUpgrades(u);
}
@Override
@@ -326,9 +344,11 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
}
IAEFluidStack toStore;
if (work.getStackSize() > 0L) {
if ((long) this.tanks.fill(slot, work.getFluidStack(), false) != work.getStackSize()) {
if (this.craftingTracker.isBusy(slot)) {
changed = this.handleCrafting(slot, work);
} else if ((long) this.tanks.fill(slot, work.getFluidStack(), false) != work.getStackSize()) {
changed = true;
} else if (Objects.requireNonNull(getFluidGrid()).getStorageList().findPrecise(work) != null) {
} else {
toStore = dest.extractItems(work, Actionable.MODULATE, this.mySource);
if (toStore != null) {
changed = true;
@@ -336,6 +356,8 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if ((long) filled != toStore.getStackSize()) {
throw new IllegalStateException("bad attempt at managing tanks. ( fill )");
}
} else {
changed = this.handleCrafting(slot, work);
}
}
} else if (work.getStackSize() < 0L) {
@@ -365,6 +387,57 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
return changed;
}
private boolean handleCrafting(final int slot, final IAEFluidStack fluidStack) {
try {
if (this.getInstalledUpgrades(Upgrades.CRAFTING) > 0 && fluidStack != null) {
return this.craftingTracker.handleCrafting(
slot,
fluidStack.getStackSize(),
(IAEStack<?>) fluidStack,
this.iHost.getTileEntity().getWorldObj(),
this.gridProxy.getGrid(),
this.gridProxy.getCrafting(),
this.mySource);
}
} catch (final GridAccessException e) {
// :P
}
return false;
}
public ImmutableSet<ICraftingLink> getRequestedJobs() {
return this.craftingTracker.getRequestedJobs();
}
public IAEStack<?> injectCraftedItems(final ICraftingLink link, final IAEStack<?> acquired, final Actionable mode) {
final int slot = this.craftingTracker.getSlot(link);
if (acquired instanceof IAEFluidStack afs && slot >= 0 && slot < NUMBER_OF_TANKS) {
if (mode == Actionable.SIMULATE) {
final int filled = this.tanks.fill(slot, afs.getFluidStack(), false);
return filled >= afs.getFluidStack().amount ? null
: AEFluidStack.create(drainRemainder(afs.getFluidStack(), filled));
} else {
final int filled = this.tanks.fill(slot, afs.getFluidStack(), true);
this.updatePlan(slot);
return filled >= afs.getFluidStack().amount ? null
: AEFluidStack.create(drainRemainder(afs.getFluidStack(), filled));
}
}
return acquired;
}
private static FluidStack drainRemainder(final FluidStack original, final int accepted) {
final FluidStack remainder = original.copy();
remainder.amount -= accepted;
return remainder;
}
public void jobStateChange(final ICraftingLink link) {
this.craftingTracker.jobStateChange(link);
}
private void updatePlan(int slot) {
IAEFluidStack req = this.config.getFluidInSlot(slot);
IAEFluidStack stored = this.tanks.getFluidInSlot(slot);