add crafting preview
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package refinedstorage.apiimpl.autocrafting;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class AutoCraftInfoStack {
|
||||
private ItemStack stack;
|
||||
private int needed;
|
||||
private int stock;
|
||||
private int extras;
|
||||
private boolean cantCraft;
|
||||
|
||||
public AutoCraftInfoStack(ItemStack stack, int needed, int stock) {
|
||||
this.stack = stack;
|
||||
this.needed = needed;
|
||||
this.stock = stock;
|
||||
this.extras = 0;
|
||||
this.cantCraft = false;
|
||||
}
|
||||
|
||||
public void writeToByteBuf(ByteBuf buf) {
|
||||
buf.writeInt(Item.getIdFromItem(stack.getItem()));
|
||||
buf.writeInt(stack.getMetadata());
|
||||
buf.writeInt(needed);
|
||||
buf.writeInt(stock);
|
||||
buf.writeInt(extras);
|
||||
buf.writeBoolean(cantCraft);
|
||||
}
|
||||
|
||||
public static AutoCraftInfoStack fromByteBuf(ByteBuf buf) {
|
||||
Item item = Item.getItemById(buf.readInt());
|
||||
int meta = buf.readInt();
|
||||
int toCraft = buf.readInt();
|
||||
int available = buf.readInt();
|
||||
AutoCraftInfoStack stack = new AutoCraftInfoStack(new ItemStack(item, 1, meta), toCraft, available);
|
||||
stack.extras = buf.readInt();
|
||||
stack.cantCraft = buf.readBoolean();
|
||||
return stack;
|
||||
}
|
||||
|
||||
public void addNeeded(int quantity) {
|
||||
this.needed += quantity;
|
||||
}
|
||||
|
||||
public void addExtras(int quantity) {
|
||||
this.extras += quantity;
|
||||
}
|
||||
|
||||
public int getAvailable() {
|
||||
return this.stock + this.extras - this.needed;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public int getStock() {
|
||||
return stock;
|
||||
}
|
||||
|
||||
public int getNeeded() {
|
||||
return needed;
|
||||
}
|
||||
|
||||
public boolean needsCrafting() {
|
||||
return this.needed > this.stock;
|
||||
}
|
||||
|
||||
public boolean cantCraft() {
|
||||
return this.cantCraft;
|
||||
}
|
||||
|
||||
public int getToCraft() {
|
||||
return this.needed - this.stock;
|
||||
}
|
||||
|
||||
public void setCantCraft(boolean cantCraft) {
|
||||
this.cantCraft = cantCraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return stack.toString() + ", needed=" + needed + ", stock=" + stock + ", extras=" + extras + ", canCraft=" + !cantCraft;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
package refinedstorage.apiimpl.autocrafting;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import refinedstorage.api.network.INetworkMaster;
|
||||
import refinedstorage.api.network.NetworkUtils;
|
||||
import refinedstorage.api.storage.CompareUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class CraftingUtils {
|
||||
public static Collection<AutoCraftInfoStack> getItems(INetworkMaster network, ItemStack stack, int quantity) {
|
||||
AutoCraftInfoData data = new AutoCraftInfoData(network);
|
||||
calcItems(network, stack, quantity, data);
|
||||
return data.values();
|
||||
}
|
||||
|
||||
private static void calcItems(INetworkMaster network, ItemStack stack, int quantity, AutoCraftInfoData data) {
|
||||
quantity = -data.add(stack, quantity);
|
||||
if (quantity > 0) {
|
||||
ICraftingPattern pattern = NetworkUtils.getPattern(network, stack);
|
||||
if (pattern != null) {
|
||||
int quantityPerRequest = pattern.getQuantityPerRequest(stack);
|
||||
while (quantity > 0) {
|
||||
for (ItemStack ingredient : pattern.getInputs()) {
|
||||
calcItems(network, ingredient, ingredient.stackSize, data);
|
||||
}
|
||||
data.get(stack).addExtras(quantityPerRequest);
|
||||
quantity -= quantityPerRequest;
|
||||
}
|
||||
} else {
|
||||
data.get(stack).setCantCraft(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class AutoCraftInfoData {
|
||||
private HashMap<Integer, AutoCraftInfoStack> data;
|
||||
private INetworkMaster network;
|
||||
|
||||
private AutoCraftInfoData(INetworkMaster network) {
|
||||
this.data = new HashMap<>();
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return available stacks, if negative needs crafting
|
||||
*/
|
||||
private int add(ItemStack stack, int quantity) {
|
||||
int hash = NetworkUtils.getItemStackHashCode(stack);
|
||||
if (data.containsKey(hash)) {
|
||||
AutoCraftInfoStack infoStack = data.get(hash);
|
||||
infoStack.addNeeded(quantity);
|
||||
return infoStack.getAvailable();
|
||||
} else {
|
||||
ItemStack networkStack = network.getItemStorage().get(stack, CompareUtils.COMPARE_DAMAGE | CompareUtils.COMPARE_NBT);
|
||||
AutoCraftInfoStack infoStack = new AutoCraftInfoStack(stack, quantity, networkStack == null ? 0 : networkStack.stackSize);
|
||||
data.put(hash, infoStack);
|
||||
return infoStack.getAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
private AutoCraftInfoStack get(ItemStack stack) {
|
||||
return this.data.get(NetworkUtils.getItemStackHashCode(stack));
|
||||
}
|
||||
|
||||
private Collection<AutoCraftInfoStack> values() {
|
||||
return this.data.values();
|
||||
}
|
||||
}
|
||||
}
|
182
src/main/java/refinedstorage/gui/GuiCraftingPreview.java
Normal file
182
src/main/java/refinedstorage/gui/GuiCraftingPreview.java
Normal file
@@ -0,0 +1,182 @@
|
||||
package refinedstorage.gui;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import refinedstorage.RefinedStorage;
|
||||
import refinedstorage.apiimpl.autocrafting.AutoCraftInfoStack;
|
||||
import refinedstorage.network.MessageGridCraftingPreview;
|
||||
import refinedstorage.network.MessageGridCraftingStart;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class GuiCraftingPreview extends GuiBase {
|
||||
private static final int VISIBLE_ROWS = 8;
|
||||
|
||||
private List<AutoCraftInfoStack> stacks;
|
||||
private GuiScreen parent;
|
||||
|
||||
private int hash, quantity;
|
||||
|
||||
private GuiButton startButton;
|
||||
private GuiButton cancelButton;
|
||||
|
||||
public GuiCraftingPreview(GuiScreen parent, Collection<AutoCraftInfoStack> stacks, int hash, int quantity) {
|
||||
super(new Container() {
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer playerIn) {
|
||||
return false;
|
||||
}
|
||||
}, 176, 181);
|
||||
this.stacks = new ArrayList<>(stacks);
|
||||
this.parent = parent;
|
||||
|
||||
this.hash = hash;
|
||||
this.quantity = quantity;
|
||||
|
||||
this.scrollbar = new Scrollbar(157, 20, 12, 59);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(int x, int y) {
|
||||
startButton = addButton(x + 100, y + 150, 50, 20, t("misc.refinedstorage:start"));
|
||||
cancelButton = addButton(x + 20, y + 150, 50, 20, t("gui.cancel"));
|
||||
|
||||
startButton.enabled = stacks.stream().filter(AutoCraftInfoStack::cantCraft).count() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int x, int y) {
|
||||
scrollbar.setEnabled(getRows() > VISIBLE_ROWS);
|
||||
scrollbar.setMaxOffset(getRows() - VISIBLE_ROWS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(int x, int y, int mouseX, int mouseY) {
|
||||
bindTexture("gui/crafting_preview.png");
|
||||
|
||||
drawTexture(x, y, 0, 0, width, height);
|
||||
|
||||
x += 15;
|
||||
y += 20;
|
||||
|
||||
int slot = scrollbar.getOffset() * 2;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (slot < stacks.size()) {
|
||||
AutoCraftInfoStack stack = stacks.get(slot);
|
||||
|
||||
if (stack.cantCraft()) {
|
||||
drawTexture(x, y, 0, 185, 67, 29);
|
||||
}
|
||||
}
|
||||
|
||||
if (i%2 == 1) {
|
||||
x -= 68;
|
||||
y += 30;
|
||||
} else {
|
||||
x += 68;
|
||||
}
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawForeground(int mouseX, int mouseY) {
|
||||
drawString(7, 7, t("gui.refinedstorage:crafting_preview.title"));
|
||||
|
||||
int x = 22;
|
||||
int y = 22;
|
||||
|
||||
int slot = scrollbar.getOffset() * 2;
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
ItemStack hoveringStack = null;
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (slot < stacks.size()) {
|
||||
AutoCraftInfoStack stack = stacks.get(slot);
|
||||
|
||||
drawItem(x, y + 5, stack.getStack());
|
||||
|
||||
float scale = 0.5f;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(scale, scale, 1);
|
||||
|
||||
if (stack.needsCrafting()) {
|
||||
|
||||
String format = stack.cantCraft() ? "gui.refinedstorage:crafting_preview.missing" : "gui.refinedstorage:crafting_preview.to_craft";
|
||||
drawString(calculateOffsetOnScale(x + 20, scale), calculateOffsetOnScale(y + 8, scale), t(format, stack.getToCraft()));
|
||||
}
|
||||
if (stack.getStock() > 0) {
|
||||
drawString(calculateOffsetOnScale(x + 20, scale), calculateOffsetOnScale(y + 13, scale), t("gui.refinedstorage:crafting_preview.available", stack.getStock()));
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if (inBounds(x, y, 16, 16, mouseX, mouseY)) {
|
||||
hoveringStack = stack.getStack();
|
||||
}
|
||||
}
|
||||
|
||||
if (i%2 == 1) {
|
||||
x -= 68;
|
||||
y += 30;
|
||||
} else {
|
||||
x += 68;
|
||||
}
|
||||
|
||||
slot++;
|
||||
}
|
||||
if (hoveringStack != null) {
|
||||
drawTooltip(mouseX, mouseY, hoveringStack.getTooltip(Minecraft.getMinecraft().thePlayer, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char character, int keyCode) throws IOException {
|
||||
if (keyCode == Keyboard.KEY_RETURN && startButton.enabled) {
|
||||
startRequest();
|
||||
} else if (keyCode == Keyboard.KEY_ESCAPE) {
|
||||
close();
|
||||
} else {
|
||||
super.keyTyped(character, keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button) throws IOException {
|
||||
super.actionPerformed(button);
|
||||
|
||||
if (button.id == startButton.id) {
|
||||
startRequest();
|
||||
} else if (button.id == cancelButton.id) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void startRequest() {
|
||||
RefinedStorage.INSTANCE.network.sendToServer(new MessageGridCraftingStart(hash, quantity));
|
||||
close();
|
||||
}
|
||||
|
||||
private int getRows() {
|
||||
return Math.max(0, (int) Math.ceil((float) stacks.size() / 2F));
|
||||
}
|
||||
|
||||
private void close() {
|
||||
FMLClientHandler.instance().showGuiScreen(parent);
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package refinedstorage.gui.grid;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
@@ -10,7 +11,7 @@ import refinedstorage.RefinedStorage;
|
||||
import refinedstorage.container.ContainerCraftingSettings;
|
||||
import refinedstorage.gui.GuiBase;
|
||||
import refinedstorage.gui.grid.stack.ClientStackItem;
|
||||
import refinedstorage.network.MessageGridCraftingStart;
|
||||
import refinedstorage.network.MessageGridCraftingPreview;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -124,13 +125,15 @@ public class GuiCraftingStart extends GuiBase {
|
||||
Integer quantity = Ints.tryParse(amountField.getText());
|
||||
|
||||
if (quantity != null && quantity > 0) {
|
||||
RefinedStorage.INSTANCE.network.sendToServer(new MessageGridCraftingStart(stack.getHash(), quantity));
|
||||
|
||||
close();
|
||||
RefinedStorage.INSTANCE.network.sendToServer(new MessageGridCraftingPreview(stack.getHash(), quantity));
|
||||
}
|
||||
}
|
||||
|
||||
private void close() {
|
||||
FMLClientHandler.instance().showGuiScreen(gui);
|
||||
}
|
||||
|
||||
public GuiGrid getGui() {
|
||||
return gui;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package refinedstorage.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import refinedstorage.RefinedStorage;
|
||||
import refinedstorage.api.network.INetworkMaster;
|
||||
import refinedstorage.apiimpl.autocrafting.AutoCraftInfoStack;
|
||||
import refinedstorage.apiimpl.autocrafting.CraftingUtils;
|
||||
import refinedstorage.container.ContainerGrid;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class MessageGridCraftingPreview extends MessageHandlerPlayerToServer<MessageGridCraftingPreview> implements IMessage {
|
||||
private int hash;
|
||||
private int quantity;
|
||||
|
||||
public MessageGridCraftingPreview() {
|
||||
}
|
||||
|
||||
public MessageGridCraftingPreview(int hash, int quantity) {
|
||||
this.hash = hash;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
hash = buf.readInt();
|
||||
quantity = buf.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeInt(hash);
|
||||
buf.writeInt(quantity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MessageGridCraftingPreview message, EntityPlayerMP player) {
|
||||
Container container = player.openContainer;
|
||||
|
||||
if (container instanceof ContainerGrid) {
|
||||
TileEntity entity = player.getEntityWorld().getTileEntity(((ContainerGrid) container).getGrid().getNetworkPosition());
|
||||
if (entity != null && entity instanceof INetworkMaster) {
|
||||
INetworkMaster network = (INetworkMaster) entity;
|
||||
Collection<AutoCraftInfoStack> stacks = CraftingUtils.getItems(network, network.getItemStorage().get(message.hash), message.quantity);
|
||||
RefinedStorage.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(stacks, message.hash, message.quantity), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package refinedstorage.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
import refinedstorage.apiimpl.autocrafting.AutoCraftInfoStack;
|
||||
import refinedstorage.gui.GuiCraftingPreview;
|
||||
import refinedstorage.gui.grid.GuiCraftingStart;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class MessageGridCraftingPreviewResponse implements IMessage, IMessageHandler<MessageGridCraftingPreviewResponse, IMessage> {
|
||||
|
||||
private Collection<AutoCraftInfoStack> stacks;
|
||||
private int hash, quantity;
|
||||
|
||||
public MessageGridCraftingPreviewResponse() {
|
||||
|
||||
}
|
||||
|
||||
public MessageGridCraftingPreviewResponse(Collection<AutoCraftInfoStack> stacks, int hash, int quantity) {
|
||||
this.stacks = stacks;
|
||||
this.hash = hash;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
this.hash = buf.readInt();
|
||||
this.quantity = buf.readInt();
|
||||
|
||||
this.stacks = new LinkedList<>();
|
||||
int size = buf.readInt();
|
||||
for (int i = 0 ; i < size; i++) {
|
||||
this.stacks.add(AutoCraftInfoStack.fromByteBuf(buf));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeInt(this.hash);
|
||||
buf.writeInt(this.quantity);
|
||||
|
||||
buf.writeInt(stacks.size());
|
||||
for (AutoCraftInfoStack stack : stacks) {
|
||||
stack.writeToByteBuf(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(MessageGridCraftingPreviewResponse message, MessageContext ctx) {
|
||||
GuiScreen screen = Minecraft.getMinecraft().currentScreen;
|
||||
if (screen instanceof GuiCraftingStart) {
|
||||
screen = ((GuiCraftingStart) screen).getGui();
|
||||
}
|
||||
FMLCommonHandler.instance().showGuiScreen(new GuiCraftingPreview(screen, message.stacks, message.hash, message.quantity));
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -69,6 +69,8 @@ public class CommonProxy {
|
||||
RefinedStorage.INSTANCE.network.registerMessage(MessageGridFluidInsertHeld.class, MessageGridFluidInsertHeld.class, id++, Side.SERVER);
|
||||
RefinedStorage.INSTANCE.network.registerMessage(MessageProcessingPatternEncoderClear.class, MessageProcessingPatternEncoderClear.class, id++, Side.SERVER);
|
||||
RefinedStorage.INSTANCE.network.registerMessage(MessageGridFilterUpdate.class, MessageGridFilterUpdate.class, id++, Side.SERVER);
|
||||
RefinedStorage.INSTANCE.network.registerMessage(MessageGridCraftingPreview.class, MessageGridCraftingPreview.class, id++, Side.SERVER);
|
||||
RefinedStorage.INSTANCE.network.registerMessage(MessageGridCraftingPreviewResponse.class, MessageGridCraftingPreviewResponse.class, id++, Side.CLIENT);
|
||||
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler(RefinedStorage.INSTANCE, new GuiHandler());
|
||||
|
||||
|
@@ -41,6 +41,10 @@ gui.refinedstorage:network_transmitter.missing_upgrade=Insert upgrade
|
||||
gui.refinedstorage:fluid_interface=Fluid Interface
|
||||
gui.refinedstorage:fluid_interface.in=In
|
||||
gui.refinedstorage:fluid_interface.out=Out
|
||||
gui.refinedstorage:crafting_preview.title=Crafting Preview
|
||||
gui.refinedstorage:crafting_preview.to_craft=To Craft: %d
|
||||
gui.refinedstorage:crafting_preview.available=Available: %d
|
||||
gui.refinedstorage:crafting_preview.missing=Missing: %d
|
||||
|
||||
misc.refinedstorage:energy_stored=%d / %d RS
|
||||
misc.refinedstorage:energy_usage=Usage: %d RS/t
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Reference in New Issue
Block a user