unify item requests into one method

This commit is contained in:
Ellpeck 2020-05-09 16:27:49 +02:00
parent d33a93e029
commit ede06585f7
5 changed files with 55 additions and 56 deletions

View file

@ -1,5 +1,6 @@
package de.ellpeck.prettypipes.network;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraftforge.common.util.INBTSerializable;
@ -9,13 +10,11 @@ import java.util.Collection;
public class NetworkLock implements INBTSerializable<CompoundNBT> {
public NetworkLocation location;
public int slot;
public int amount;
public ItemStack stack;
public NetworkLock(NetworkLocation location, int slot, int amount) {
public NetworkLock(NetworkLocation location, ItemStack stack) {
this.location = location;
this.slot = slot;
this.amount = amount;
this.stack = stack;
}
public NetworkLock(CompoundNBT nbt) {
@ -26,15 +25,13 @@ public class NetworkLock implements INBTSerializable<CompoundNBT> {
public CompoundNBT serializeNBT() {
CompoundNBT nbt = new CompoundNBT();
nbt.put("location", this.location.serializeNBT());
nbt.putInt("slot", this.slot);
nbt.putInt("amount", this.amount);
nbt.put("stack", this.stack.write(new CompoundNBT()));
return nbt;
}
@Override
public void deserializeNBT(CompoundNBT nbt) {
this.location = new NetworkLocation(nbt.getCompound("location"));
this.slot = nbt.getInt("slot");
this.amount = nbt.getInt("amount");
this.stack = ItemStack.read(nbt.getCompound("stack"));
}
}

View file

@ -177,6 +177,30 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return true;
}
public boolean requestItem(BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) {
List<NetworkLocation> locations = this.getOrderedNetworkItems(destPipe);
for (NetworkLocation location : locations) {
if (this.requestItem(location, destPipe, destInventory, stack, amount, equalityTypes))
return true;
}
return false;
}
public boolean requestItem(NetworkLocation location, BlockPos destPipe, BlockPos destInventory, ItemStack stack, int amount, ItemEqualityType... equalityTypes) {
if (location.pipePos.equals(destPipe))
return false;
for (int slot : location.getStackSlots(this.world, stack, equalityTypes)) {
// try to extract from that location's inventory and send the item
IItemHandler handler = location.getItemHandler(this.world);
ItemStack extracted = handler.extractItem(slot, amount, true);
if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, speed -> new PipeItem(extracted, speed))) {
handler.extractItem(slot, extracted.getCount(), false);
return true;
}
}
return false;
}
public PipeTileEntity getPipe(BlockPos pos) {
PipeTileEntity tile = this.tileCache.get(pos);
if (tile == null || tile.isRemoved()) {
@ -223,10 +247,10 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundNBT>, GraphL
return this.networkLocks.get(pos);
}
public int getLockedAmount(BlockPos pos, int slot) {
public int getLockedAmount(BlockPos pos, ItemStack stack, ItemEqualityType... equalityTypes) {
return this.getNetworkLocks(pos).stream()
.filter(l -> l.slot == slot)
.mapToInt(l -> l.amount).sum();
.filter(l -> ItemEqualityType.compareItems(l.stack, stack, equalityTypes))
.mapToInt(l -> l.stack.getCount()).sum();
}
private void refreshNode(BlockPos pos, BlockState state) {

View file

@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.items.ModuleTier;
import de.ellpeck.prettypipes.misc.ItemEqualityType;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.NetworkLocation;
import de.ellpeck.prettypipes.network.PipeItem;
@ -39,7 +40,6 @@ public class RetrievalModuleItem extends ModuleItem {
if (!tile.canWork())
return;
PipeNetwork network = PipeNetwork.get(tile.getWorld());
List<NetworkLocation> locations = null;
ItemFilter filter = new ItemFilter(this.filterSlots, module, tile);
filter.isWhitelist = true;
@ -53,22 +53,8 @@ public class RetrievalModuleItem extends ModuleItem {
BlockPos dest = tile.getAvailableDestination(copy, true, this.preventOversending);
if (dest == null)
continue;
// loop through locations to find a location that has the item
if (locations == null)
locations = network.getOrderedNetworkItems(tile.getPos());
for (NetworkLocation location : locations) {
if (location.pipePos.equals(tile.getPos()))
continue;
for (int slot : location.getStackSlots(tile.getWorld(), filtered, filter.getEqualityTypes())) {
// try to extract from that location's inventory and send the item
IItemHandler handler = location.getItemHandler(tile.getWorld());
ItemStack stack = handler.extractItem(slot, this.maxExtraction, true);
if (network.routeItemToLocation(location.pipePos, location.getPos(), tile.getPos(), dest, speed -> new PipeItem(stack, speed))) {
handler.extractItem(slot, stack.getCount(), false);
return;
}
}
}
if (network.requestItem(tile.getPos(), dest, filtered, this.maxExtraction, filter.getEqualityTypes()))
break;
}
}

View file

@ -118,13 +118,11 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
int available = 0;
if (item != null) {
for (NetworkLocation location : item.getLocations()) {
for (int slot : location.getStackSlots(this.world, stack.stack, ItemEqualityType.NBT)) {
ItemStack inSlot = location.getItemHandler(this.world).extractItem(slot, Integer.MAX_VALUE, true);
if (inSlot.isEmpty())
continue;
inSlot.shrink(network.getLockedAmount(location.getPos(), slot));
available += inSlot.getCount();
}
int amount = location.getItemAmount(this.world, stack.stack, ItemEqualityType.NBT);
if (amount <= 0)
continue;
amount -= network.getLockedAmount(location.getPos(), stack.stack, ItemEqualityType.NBT);
available += amount;
}
// divide the total by the amount required to get the amount that
// we have available for each crafting slot that contains this item

View file

@ -84,12 +84,8 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
if (!this.pendingRequests.isEmpty()) {
NetworkLock request = this.pendingRequests.remove();
network.resolveNetworkLock(request);
IItemHandler handler = request.location.getItemHandler(this.world);
ItemStack extracted = handler.extractItem(request.slot, request.amount, true);
if (network.routeItemToLocation(request.location.pipePos, request.location.getPos(), pipe.getPos(), this.pos, speed -> new PipeItem(extracted, speed))) {
handler.extractItem(request.slot, extracted.getCount(), false);
if (network.requestItem(request.location, pipe.getPos(), this.pos, request.stack, request.stack.getCount(), ItemEqualityType.NBT))
update = true;
}
}
}
@ -154,22 +150,20 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
NetworkItem item = this.networkItems.get(equatable);
if (item != null) {
int remain = stack.getCount();
locations:
for (NetworkLocation location : item.getLocations()) {
for (int slot : location.getStackSlots(this.world, stack, ItemEqualityType.NBT)) {
ItemStack inSlot = location.getItemHandler(this.world).extractItem(slot, Integer.MAX_VALUE, true);
if (inSlot.isEmpty())
continue;
inSlot.shrink(network.getLockedAmount(location.getPos(), slot));
if (inSlot.getCount() > 0) {
int extract = Math.min(inSlot.getCount(), remain);
NetworkLock lock = new NetworkLock(location, slot, extract);
this.pendingRequests.add(lock);
network.createNetworkLock(lock);
remain -= extract;
if (remain <= 0)
break locations;
}
int amount = location.getItemAmount(this.world, stack, ItemEqualityType.NBT);
if (amount <= 0)
continue;
amount -= network.getLockedAmount(location.getPos(), stack, ItemEqualityType.NBT);
if (amount > 0) {
if (remain < amount)
amount = remain;
NetworkLock lock = new NetworkLock(location, stack);
this.pendingRequests.add(lock);
network.createNetworkLock(lock);
remain -= amount;
if (remain <= 0)
break;
}
}
return stack.getCount() - remain;