mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-12-22 23:39:22 +01:00
finished the crafting terminal!
This commit is contained in:
parent
8bd5a0cae3
commit
f9c5ea86f7
6 changed files with 115 additions and 26 deletions
|
@ -8,6 +8,7 @@ import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer;
|
|||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
|
||||
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem;
|
||||
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
|
||||
import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -109,6 +110,11 @@ public class PacketButton {
|
|||
STACK_SIZE_AMOUNT((pos, data, player) -> {
|
||||
AbstractPipeContainer<?> container = (AbstractPipeContainer<?>) player.openContainer;
|
||||
StackSizeModuleItem.setMaxStackSize(container.moduleStack, data[0]);
|
||||
}),
|
||||
CRAFT_TERMINAL_REQUEST((pos, data, player) -> {
|
||||
CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, player.world, pos);
|
||||
boolean all = data[0] > 0;
|
||||
tile.requestCraftingItems(player, all);
|
||||
});
|
||||
|
||||
public final TriConsumer<BlockPos, int[], PlayerEntity> action;
|
||||
|
|
|
@ -27,20 +27,23 @@ public class CraftingTerminalBlock extends ItemTerminalBlock {
|
|||
BlockPos pos = pipePos.offset(direction);
|
||||
CraftingTerminalTileEntity tile = Utility.getTileEntity(CraftingTerminalTileEntity.class, world, pos);
|
||||
if (tile != null) {
|
||||
int lowestFitting = -1;
|
||||
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
|
||||
ItemStack stack = tile.getRequestedCraftItem(i);
|
||||
if (!ItemHandlerHelper.canItemStacksStackRelaxed(stack, item.stack))
|
||||
continue;
|
||||
if (lowestFitting < 0 || stack.getCount() < tile.getRequestedCraftItem(lowestFitting).getCount())
|
||||
lowestFitting = i;
|
||||
}
|
||||
ItemStack remain = item.stack;
|
||||
if (lowestFitting >= 0) {
|
||||
remain = tile.craftItems.insertItem(lowestFitting, item.stack, false);
|
||||
if (remain.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
int lowestFitting = -1;
|
||||
do {
|
||||
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
|
||||
ItemStack stack = tile.getRequestedCraftItem(i);
|
||||
if (!ItemHandlerHelper.canItemStacksStackRelaxed(stack, remain))
|
||||
continue;
|
||||
if (lowestFitting < 0 || stack.getCount() < tile.getRequestedCraftItem(lowestFitting).getCount())
|
||||
lowestFitting = i;
|
||||
}
|
||||
if (lowestFitting >= 0) {
|
||||
remain = tile.craftItems.insertItem(lowestFitting, remain, false);
|
||||
if (remain.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
while (lowestFitting >= 0);
|
||||
return ItemHandlerHelper.insertItemStacked(tile.items, remain, false);
|
||||
}
|
||||
return item.stack;
|
||||
|
|
|
@ -2,6 +2,12 @@ package de.ellpeck.prettypipes.terminal;
|
|||
|
||||
import de.ellpeck.prettypipes.PrettyPipes;
|
||||
import de.ellpeck.prettypipes.Registry;
|
||||
import de.ellpeck.prettypipes.misc.EquatableItemStack;
|
||||
import de.ellpeck.prettypipes.misc.ItemEqualityType;
|
||||
import de.ellpeck.prettypipes.network.NetworkItem;
|
||||
import de.ellpeck.prettypipes.network.NetworkLocation;
|
||||
import de.ellpeck.prettypipes.network.NetworkLock;
|
||||
import de.ellpeck.prettypipes.network.PipeNetwork;
|
||||
import de.ellpeck.prettypipes.terminal.containers.CraftingTerminalContainer;
|
||||
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -10,10 +16,18 @@ import net.minecraft.inventory.container.Container;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
|
||||
|
||||
|
@ -28,6 +42,68 @@ public class CraftingTerminalTileEntity extends ItemTerminalTileEntity {
|
|||
return this.craftItems.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
public void requestCraftingItems(PlayerEntity player, boolean all) {
|
||||
PipeNetwork network = PipeNetwork.get(this.world);
|
||||
network.startProfile("terminal_request_crafting");
|
||||
this.updateItems();
|
||||
|
||||
// this is the amount of items required for each ingredient when crafting ONE
|
||||
Map<EquatableItemStack, MutableInt> requiredItems = new HashMap<>();
|
||||
for (int i = 0; i < this.craftItems.getSlots(); i++) {
|
||||
ItemStack requested = this.getRequestedCraftItem(i);
|
||||
if (requested.isEmpty())
|
||||
continue;
|
||||
MutableInt amount = requiredItems.computeIfAbsent(new EquatableItemStack(requested), s -> new MutableInt());
|
||||
amount.add(1);
|
||||
}
|
||||
// the highest amount we can craft with the items we have
|
||||
int lowestAvailable = Integer.MAX_VALUE;
|
||||
for (Map.Entry<EquatableItemStack, MutableInt> entry : requiredItems.entrySet()) {
|
||||
EquatableItemStack stack = entry.getKey();
|
||||
NetworkItem item = this.networkItems.get(stack);
|
||||
if (item != null) {
|
||||
// total amount of available items of this type
|
||||
int available = 0;
|
||||
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();
|
||||
}
|
||||
}
|
||||
// divide the total by the amount required to get the amount that
|
||||
// we have available for each crafting slot that contains this item
|
||||
available /= entry.getValue().intValue();
|
||||
int fit = stack.stack.getMaxStackSize() - stack.stack.getCount();
|
||||
if (available > fit)
|
||||
available = fit;
|
||||
if (available < lowestAvailable)
|
||||
lowestAvailable = available;
|
||||
} else {
|
||||
lowestAvailable = 0;
|
||||
}
|
||||
if (lowestAvailable <= 0)
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", stack.stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.RED)));
|
||||
}
|
||||
if (lowestAvailable > 0) {
|
||||
// if we're only crafting one item, pretend we only have enough for one
|
||||
if (!all)
|
||||
lowestAvailable = 1;
|
||||
for (int i = 0; i < this.craftItems.getSlots(); i++) {
|
||||
ItemStack requested = this.getRequestedCraftItem(i);
|
||||
if (requested.isEmpty())
|
||||
continue;
|
||||
requested = requested.copy();
|
||||
requested.setCount(lowestAvailable);
|
||||
this.requestItemImpl(requested);
|
||||
}
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".sending_ingredients", lowestAvailable).setStyle(new Style().setColor(TextFormatting.GREEN)));
|
||||
}
|
||||
network.endProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.put("craft_items", this.craftItems.serializeNBT());
|
||||
|
|
|
@ -138,8 +138,19 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
public void requestItem(PlayerEntity player, ItemStack stack) {
|
||||
PipeNetwork network = PipeNetwork.get(this.world);
|
||||
network.startProfile("terminal_request_item");
|
||||
EquatableItemStack equatable = new EquatableItemStack(stack);
|
||||
this.updateItems();
|
||||
int requested = this.requestItemImpl(stack);
|
||||
if (requested > 0) {
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".sending", requested, stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.GREEN)));
|
||||
} else {
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.RED)));
|
||||
}
|
||||
network.endProfile();
|
||||
}
|
||||
|
||||
protected int requestItemImpl(ItemStack stack) {
|
||||
PipeNetwork network = PipeNetwork.get(this.world);
|
||||
EquatableItemStack equatable = new EquatableItemStack(stack);
|
||||
NetworkItem item = this.networkItems.get(equatable);
|
||||
if (item != null) {
|
||||
int remain = stack.getCount();
|
||||
|
@ -161,11 +172,9 @@ public class ItemTerminalTileEntity extends TileEntity implements INamedContaine
|
|||
}
|
||||
}
|
||||
}
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".sending", stack.getCount() - remain, stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.GREEN)));
|
||||
} else {
|
||||
player.sendMessage(new TranslationTextComponent("info." + PrettyPipes.ID + ".not_found", stack.getDisplayName()).setStyle(new Style().setColor(TextFormatting.RED)));
|
||||
return stack.getCount() - remain;
|
||||
}
|
||||
network.endProfile();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private PlayerEntity[] getLookingPlayers() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package de.ellpeck.prettypipes.terminal.containers;
|
||||
|
||||
import de.ellpeck.prettypipes.PrettyPipes;
|
||||
import de.ellpeck.prettypipes.packets.PacketButton;
|
||||
import de.ellpeck.prettypipes.packets.PacketHandler;
|
||||
import de.ellpeck.prettypipes.packets.PacketRequest;
|
||||
import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity;
|
||||
|
@ -25,15 +26,8 @@ public class CraftingTerminalGui extends ItemTerminalGui {
|
|||
protected void init() {
|
||||
super.init();
|
||||
this.requestButton = this.addButton(new Button(this.guiLeft + 8, this.guiTop + 100, 50, 20, I18n.format("info." + PrettyPipes.ID + ".request"), button -> {
|
||||
CraftingTerminalTileEntity tile = this.getCraftingContainer().getTile();
|
||||
for (int i = 0; i < tile.craftItems.getSlots(); i++) {
|
||||
ItemStack stack = tile.getRequestedCraftItem(i);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
stack = stack.copy();
|
||||
stack.setCount(1);
|
||||
PacketHandler.sendToServer(new PacketRequest(this.container.tile.getPos(), stack, 1));
|
||||
}
|
||||
int all = hasShiftDown() ? 1 : 0;
|
||||
PacketHandler.sendToServer(new PacketButton(this.container.tile.getPos(), PacketButton.ButtonResult.CRAFT_TERMINAL_REQUEST, all));
|
||||
}));
|
||||
this.requestButton.active = !this.getCraftingContainer().craftInventory.isEmpty();
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
"info.prettypipes.request": "Request",
|
||||
"info.prettypipes.not_found": "%s not found",
|
||||
"info.prettypipes.sending": "Sending %s %s",
|
||||
"info.prettypipes.sending_ingredients": "Sending %s sets of ingredients",
|
||||
"info.prettypipes.order": "Order by %s",
|
||||
"info.prettypipes.order.amount": "Amount",
|
||||
"info.prettypipes.order.name": "Name",
|
||||
|
|
Loading…
Reference in a new issue