fixed items getting lost with the new system

This commit is contained in:
Ellpeck 2020-05-09 20:12:50 +02:00
parent ede06585f7
commit 0af5ccde77
5 changed files with 61 additions and 15 deletions

View file

@ -114,6 +114,18 @@ public final class Utility {
return items; return items;
} }
public static List<ItemStack> splitStackToFitMax(ItemStack stack) {
List<ItemStack> ret = new ArrayList<>();
int amount = stack.getCount();
while (amount > 0) {
ItemStack copy = stack.copy();
copy.setCount(Math.min(amount, stack.getMaxStackSize()));
ret.add(copy);
amount -= copy.getCount();
}
return ret;
}
public interface IMergeItemStack { public interface IMergeItemStack {
boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection); boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection);
} }

View file

@ -6,9 +6,14 @@ import net.minecraft.nbt.ListNBT;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import java.util.Collection; import java.util.Collection;
import java.util.Objects;
import java.util.UUID;
public class NetworkLock implements INBTSerializable<CompoundNBT> { public class NetworkLock implements INBTSerializable<CompoundNBT> {
// identify locks by UUID since network locks can't be identified by location and locked item alone
// (two locks could be set for the same item and the same amount if it exists twice in the chest)
private UUID lockId = UUID.randomUUID();
public NetworkLocation location; public NetworkLocation location;
public ItemStack stack; public ItemStack stack;
@ -24,6 +29,7 @@ public class NetworkLock implements INBTSerializable<CompoundNBT> {
@Override @Override
public CompoundNBT serializeNBT() { public CompoundNBT serializeNBT() {
CompoundNBT nbt = new CompoundNBT(); CompoundNBT nbt = new CompoundNBT();
nbt.putUniqueId("id", this.lockId);
nbt.put("location", this.location.serializeNBT()); nbt.put("location", this.location.serializeNBT());
nbt.put("stack", this.stack.write(new CompoundNBT())); nbt.put("stack", this.stack.write(new CompoundNBT()));
return nbt; return nbt;
@ -31,7 +37,22 @@ public class NetworkLock implements INBTSerializable<CompoundNBT> {
@Override @Override
public void deserializeNBT(CompoundNBT nbt) { public void deserializeNBT(CompoundNBT nbt) {
this.lockId = nbt.getUniqueId("id");
this.location = new NetworkLocation(nbt.getCompound("location")); this.location = new NetworkLocation(nbt.getCompound("location"));
this.stack = ItemStack.read(nbt.getCompound("stack")); this.stack = ItemStack.read(nbt.getCompound("stack"));
} }
@Override
public boolean equals(Object o) {
if (o instanceof NetworkLock) {
NetworkLock that = (NetworkLock) o;
return this.lockId.equals(that.lockId);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(this.lockId);
}
} }

View file

@ -177,28 +177,35 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return true; return true;
} }
public boolean requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) { public ItemStack requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
List<NetworkLocation> locations = this.getOrderedNetworkItems(destPipe); List<NetworkLocation> locations = this.getOrderedNetworkItems(destPipe);
if (locations.isEmpty())
return stack;
ItemStack remain = stack.copy();
for (NetworkLocation location : locations) { for (NetworkLocation location : locations) {
if (this.requestItem(location, destPipe, destInventory, stack, amount, equalityTypes)) remain = this.requestItem(location, destPipe, destInventory, remain, equalityTypes);
return true; if (remain.isEmpty())
break;
} }
return false; return remain;
} }
public boolean requestItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) { public ItemStack requestItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, ItemEqualityType... equalityTypes) {
if (location.pipePos.equals(destPipe)) if (location.pipePos.equals(destPipe))
return false; return stack;
ItemStack remain = stack.copy();
for (int slot : location.getStackSlots(this.world, stack, equalityTypes)) { for (int slot : location.getStackSlots(this.world, stack, equalityTypes)) {
// try to extract from that location's inventory and send the item // try to extract from that location's inventory and send the item
IItemHandler handler = location.getItemHandler(this.world); IItemHandler handler = location.getItemHandler(this.world);
ItemStack extracted = handler.extractItem(slot, amount, true); ItemStack extracted = handler.extractItem(slot, remain.getCount(), true);
if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, speed -> new PipeItem(extracted, speed))) { if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, speed -> new PipeItem(extracted, speed))) {
handler.extractItem(slot, extracted.getCount(), false); handler.extractItem(slot, extracted.getCount(), false);
return true; remain.shrink(extracted.getCount());
if (remain.isEmpty())
break;
} }
} }
return false; return remain;
} }
public PipeTileEntity getPipe(BlockPos pos) { public PipeTileEntity getPipe(BlockPos pos) {

View file

@ -53,7 +53,7 @@ public class RetrievalModuleItem extends ModuleItem {
BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending); BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending);
if (dest == null) if (dest == null)
continue; continue;
if (network.requestItem(tile.getPos(), dest, filtered, this.maxExtraction, filter.getEqualityTypes())) if (network.requestItem(tile.getPos(), dest, copy, filter.getEqualityTypes()).isEmpty())
break; break;
} }
} }

View file

@ -84,7 +84,7 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
if (!this.pendingRequests.isEmpty()) { if (!this.pendingRequests.isEmpty()) {
NetworkLock request = this.pendingRequests.remove(); NetworkLock request = this.pendingRequests.remove();
network.resolveNetworkLock(request); network.resolveNetworkLock(request);
if (network.requestItem(request.location, pipe.getPos(), this.pos, request.stack, request.stack.getCount(), ItemEqualityType.NBT)) network.requestItem(request.location, pipe.getPos(), this.pos, request.stack, ItemEqualityType.NBT);
update = true; update = true;
} }
} }
@ -158,10 +158,16 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
if (amount > 0) { if (amount > 0) {
if (remain < amount) if (remain < amount)
amount = remain; amount = remain;
NetworkLock lock = new NetworkLock(location, stack); remain -= amount;
while (amount > 0) {
ItemStack copy = stack.copy();
copy.setCount(Math.min(stack.getMaxStackSize(), amount));
NetworkLock lock = new NetworkLock(location, copy);
this.pendingRequests.add(lock); this.pendingRequests.add(lock);
network.createNetworkLock(lock); network.createNetworkLock(lock);
remain -= amount; amount -= copy.getCount();
}
if (remain <= 0) if (remain <= 0)
break; break;
} }