From 8fac3dd7e960e99aae80b53cc490ea50407ee756 Mon Sep 17 00:00:00 2001 From: Juuxel <6596629+Juuxel@users.noreply.github.com> Date: Sun, 29 Mar 2020 22:15:20 +0300 Subject: Make CottonCraftingController extend ScreenHandler directly, rename Closes #39. --- .../cotton/gui/CottonCraftingController.java | 450 --------------------- .../cotton/gui/CottonInventoryController.java | 402 ++++++++++++++++++ .../cotton/gui/client/CottonInventoryScreen.java | 2 +- 3 files changed, 403 insertions(+), 451 deletions(-) delete mode 100644 src/main/java/io/github/cottonmc/cotton/gui/CottonCraftingController.java create mode 100644 src/main/java/io/github/cottonmc/cotton/gui/CottonInventoryController.java diff --git a/src/main/java/io/github/cottonmc/cotton/gui/CottonCraftingController.java b/src/main/java/io/github/cottonmc/cotton/gui/CottonCraftingController.java deleted file mode 100644 index ec0cdc9..0000000 --- a/src/main/java/io/github/cottonmc/cotton/gui/CottonCraftingController.java +++ /dev/null @@ -1,450 +0,0 @@ -package io.github.cottonmc.cotton.gui; - -import java.util.ArrayList; - -import javax.annotation.Nullable; - -import io.github.cottonmc.cotton.gui.client.BackgroundPainter; -import io.github.cottonmc.cotton.gui.client.LibGuiClient; -import io.github.cottonmc.cotton.gui.widget.*; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.InventoryProvider; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.Inventory; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.RecipeFinder; -import net.minecraft.recipe.RecipeInputProvider; -import net.minecraft.recipe.RecipeType; -import net.minecraft.screen.*; -import net.minecraft.screen.slot.Slot; -import net.minecraft.screen.slot.SlotActionType; -import net.minecraft.world.World; - -public class CottonCraftingController extends AbstractRecipeScreenHandler implements GuiDescription { - - protected Inventory blockInventory; - protected PlayerInventory playerInventory; - protected RecipeType recipeType; - protected World world; - protected PropertyDelegate propertyDelegate; - - protected WPanel rootPanel = new WGridPanel(); - protected int titleColor = WLabel.DEFAULT_TEXT_COLOR; - protected int darkTitleColor = WLabel.DEFAULT_DARKMODE_TEXT_COLOR; - - protected WWidget focus; - - public CottonCraftingController(RecipeType recipeType, int syncId, PlayerInventory playerInventory) { - super(null, syncId); - this.blockInventory = null; - this.playerInventory = playerInventory; - this.recipeType = recipeType; - this.world = playerInventory.player.world; - this.propertyDelegate = null;//new ArrayPropertyDelegate(1); - } - - public CottonCraftingController(RecipeType recipeType, int syncId, PlayerInventory playerInventory, Inventory blockInventory, PropertyDelegate propertyDelegate) { - super(null, syncId); - this.blockInventory = blockInventory; - this.playerInventory = playerInventory; - this.recipeType = recipeType; - this.world = playerInventory.player.world; - this.propertyDelegate = propertyDelegate; - if (propertyDelegate!=null && propertyDelegate.size()>0) this.addProperties(propertyDelegate); - } - - public WPanel getRootPanel() { - return rootPanel; - } - - public int getTitleColor() { - return LibGuiClient.config.darkMode ? darkTitleColor : titleColor; - } - - public CottonCraftingController setRootPanel(WPanel panel) { - this.rootPanel = panel; - return this; - } - - public CottonCraftingController setTitleColor(int color) { - this.titleColor = color; - return this; - } - - @Environment(EnvType.CLIENT) - public void addPainters() { - if (this.rootPanel!=null) { - this.rootPanel.setBackgroundPainter(BackgroundPainter.VANILLA); - } - } - - public void addSlotPeer(ValidatedSlot slot) { - this.addSlot(slot); - } - - @Override - public ItemStack onSlotClick(int slotNumber, int button, SlotActionType action, PlayerEntity player) { - if (action==SlotActionType.QUICK_MOVE) { - - if (slotNumber < 0) { - return ItemStack.EMPTY; - } - - if (slotNumber>=this.slots.size()) return ItemStack.EMPTY; - Slot slot = this.slots.get(slotNumber); - if (slot == null || !slot.canTakeItems(player)) { - return ItemStack.EMPTY; - } - - ItemStack remaining = ItemStack.EMPTY; - if (slot != null && slot.hasStack()) { - ItemStack toTransfer = slot.getStack(); - remaining = toTransfer.copy(); - //if (slot.inventory==blockInventory) { - if (blockInventory!=null) { - if (slot.inventory==blockInventory) { - //Try to transfer the item from the block into the player's inventory - if (!this.insertItem(toTransfer, this.playerInventory, true)) { - return ItemStack.EMPTY; - } - } else if (!this.insertItem(toTransfer, this.blockInventory, false)) { //Try to transfer the item from the player to the block - return ItemStack.EMPTY; - } - } else { - //There's no block, just swap between the player's storage and their hotbar - if (!swapHotbar(toTransfer, slotNumber, this.playerInventory)) { - return ItemStack.EMPTY; - } - } - - if (toTransfer.isEmpty()) { - slot.setStack(ItemStack.EMPTY); - } else { - slot.markDirty(); - } - } - - return remaining; - } else { - return super.onSlotClick(slotNumber, button, action, player); - } - } - - /** WILL MODIFY toInsert! Returns true if anything was inserted. */ - private boolean insertIntoExisting(ItemStack toInsert, Slot slot) { - ItemStack curSlotStack = slot.getStack(); - if (!curSlotStack.isEmpty() && canStacksCombine(toInsert, curSlotStack)) { - int combinedAmount = curSlotStack.getCount() + toInsert.getCount(); - if (combinedAmount <= toInsert.getMaxCount()) { - toInsert.setCount(0); - curSlotStack.setCount(combinedAmount); - slot.markDirty(); - return true; - } else if (curSlotStack.getCount() < toInsert.getMaxCount()) { - toInsert.decrement(toInsert.getMaxCount() - curSlotStack.getCount()); - curSlotStack.setCount(toInsert.getMaxCount()); - slot.markDirty(); - return true; - } - } - return false; - } - - /** WILL MODIFY toInsert! Returns true if anything was inserted. */ - private boolean insertIntoEmpty(ItemStack toInsert, Slot slot) { - ItemStack curSlotStack = slot.getStack(); - if (curSlotStack.isEmpty() && slot.canInsert(toInsert)) { - if (toInsert.getCount() > slot.getMaxStackAmount()) { - slot.setStack(toInsert.split(slot.getMaxStackAmount())); - } else { - slot.setStack(toInsert.split(toInsert.getCount())); - } - - slot.markDirty(); - return true; - } - - return false; - } - - private boolean insertItem(ItemStack toInsert, Inventory inventory, boolean walkBackwards) { - //Make a unified list of slots *only from this inventory* - ArrayList inventorySlots = new ArrayList<>(); - for(Slot slot : slots) { - if (slot.inventory==inventory) inventorySlots.add(slot); - } - if (inventorySlots.isEmpty()) return false; - - //Try to insert it on top of existing stacks - boolean inserted = false; - if (walkBackwards) { - for(int i=inventorySlots.size()-1; i>=0; i--) { - Slot curSlot = inventorySlots.get(i); - if (insertIntoExisting(toInsert, curSlot)) inserted = true; - if (toInsert.isEmpty()) break; - } - } else { - for(int i=0; i=0; i--) { - Slot curSlot = inventorySlots.get(i); - if (insertIntoEmpty(toInsert, curSlot)) inserted = true; - if (toInsert.isEmpty()) break; - } - } else { - for(int i=0; i storageSlots = new ArrayList<>(); - ArrayList hotbarSlots = new ArrayList<>(); - boolean swapToStorage = true; - boolean inserted = false; - - for(Slot slot : slots) { - if (slot.inventory==inventory && slot instanceof ValidatedSlot) { - int index = ((ValidatedSlot)slot).getInventoryIndex(); - if (PlayerInventory.isValidHotbarIndex(index)) { - hotbarSlots.add(slot); - } else { - storageSlots.add(slot); - if (index==slotNumber) swapToStorage = false; - } - } - } - if (storageSlots.isEmpty() || hotbarSlots.isEmpty()) return false; - - if (swapToStorage) { - //swap from hotbar to storage - for(int i=0; i=wx && x=wy && y { - BlockState state = world.getBlockState(pos); - Block b = state.getBlock(); - - if (b instanceof InventoryProvider) { - return ((InventoryProvider)b).getInventory(state, world, pos); - } - - BlockEntity be = world.getBlockEntity(pos); - if (be!=null) { - if (be instanceof InventoryProvider) { - return ((InventoryProvider)be).getInventory(state, world, pos); - } else if (be instanceof Inventory) { - return (Inventory)be; - } - } - - return EmptyInventory.INSTANCE; - }).orElse(EmptyInventory.INSTANCE); - } - - public static PropertyDelegate getBlockPropertyDelegate(ScreenHandlerContext ctx) { - return ctx.run((world, pos) -> { - BlockState state = world.getBlockState(pos); - Block block = state.getBlock(); - if (block instanceof PropertyDelegateHolder) { - return ((PropertyDelegateHolder)block).getPropertyDelegate(); - } - BlockEntity be = world.getBlockEntity(pos); - if (be!=null && be instanceof PropertyDelegateHolder) { - return ((PropertyDelegateHolder)be).getPropertyDelegate(); - } - - return new ArrayPropertyDelegate(0); - }).orElse(new ArrayPropertyDelegate(0)); - } - - //extends CraftingContainer { - @Override - public void populateRecipeFinder(RecipeFinder recipeFinder) { - if (this.blockInventory instanceof RecipeInputProvider) { - ((RecipeInputProvider)this.blockInventory).provideRecipeInputs(recipeFinder); - } - } - - @Override - public void clearCraftingSlots() { - if (this.blockInventory!=null) this.blockInventory.clear(); - } - - @Override - public boolean matches(Recipe recipe) { - if (blockInventory==null || world==null) return false; - return false; //TODO recipe support - } - - @Override - public int getCraftingResultSlotIndex() { - return -1; - } - - @Override - public int getCraftingWidth() { - return 1; - } - - @Override - public int getCraftingHeight() { - return 1; - } - - @Override - @Environment(EnvType.CLIENT) - public int getCraftingSlotCount() { - return 1; - } - - //(implied) extends Container { - @Override - public boolean canUse(PlayerEntity entity) { - return (blockInventory!=null) ? blockInventory.canPlayerUseInv(entity) : true; - } - //} - //} - - @Override - public boolean isFocused(WWidget widget) { - return focus == widget; - } - - @Override - public WWidget getFocus() { - return focus; - } - - @Override - public void requestFocus(WWidget widget) { - //TODO: Are there circumstances where focus can't be stolen? - if (focus==widget) return; //Nothing happens if we're already focused - if (!widget.canFocus()) return; //This is kind of a gotcha but needs to happen - if (focus!=null) focus.onFocusLost(); - focus = widget; - focus.onFocusGained(); - } - - @Override - public void releaseFocus(WWidget widget) { - if (focus==widget) { - focus = null; - widget.onFocusLost(); - } - } -} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/CottonInventoryController.java b/src/main/java/io/github/cottonmc/cotton/gui/CottonInventoryController.java new file mode 100644 index 0000000..87dfd34 --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/CottonInventoryController.java @@ -0,0 +1,402 @@ +package io.github.cottonmc.cotton.gui; + +import java.util.ArrayList; + +import javax.annotation.Nullable; + +import io.github.cottonmc.cotton.gui.client.BackgroundPainter; +import io.github.cottonmc.cotton.gui.client.LibGuiClient; +import io.github.cottonmc.cotton.gui.widget.*; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.InventoryProvider; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.*; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.world.World; + +public class CottonInventoryController extends ScreenHandler implements GuiDescription { + + protected Inventory blockInventory; + protected PlayerInventory playerInventory; + protected World world; + protected PropertyDelegate propertyDelegate; + + protected WPanel rootPanel = new WGridPanel(); + protected int titleColor = WLabel.DEFAULT_TEXT_COLOR; + protected int darkTitleColor = WLabel.DEFAULT_DARKMODE_TEXT_COLOR; + + protected WWidget focus; + + public CottonInventoryController(int syncId, PlayerInventory playerInventory) { + super(null, syncId); + this.blockInventory = null; + this.playerInventory = playerInventory; + this.world = playerInventory.player.world; + this.propertyDelegate = null;//new ArrayPropertyDelegate(1); + } + + public CottonInventoryController(int syncId, PlayerInventory playerInventory, Inventory blockInventory, PropertyDelegate propertyDelegate) { + super(null, syncId); + this.blockInventory = blockInventory; + this.playerInventory = playerInventory; + this.world = playerInventory.player.world; + this.propertyDelegate = propertyDelegate; + if (propertyDelegate!=null && propertyDelegate.size()>0) this.addProperties(propertyDelegate); + } + + public WPanel getRootPanel() { + return rootPanel; + } + + public int getTitleColor() { + return LibGuiClient.config.darkMode ? darkTitleColor : titleColor; + } + + public CottonInventoryController setRootPanel(WPanel panel) { + this.rootPanel = panel; + return this; + } + + public CottonInventoryController setTitleColor(int color) { + this.titleColor = color; + return this; + } + + @Environment(EnvType.CLIENT) + public void addPainters() { + if (this.rootPanel!=null) { + this.rootPanel.setBackgroundPainter(BackgroundPainter.VANILLA); + } + } + + public void addSlotPeer(ValidatedSlot slot) { + this.addSlot(slot); + } + + @Override + public ItemStack onSlotClick(int slotNumber, int button, SlotActionType action, PlayerEntity player) { + if (action==SlotActionType.QUICK_MOVE) { + + if (slotNumber < 0) { + return ItemStack.EMPTY; + } + + if (slotNumber>=this.slots.size()) return ItemStack.EMPTY; + Slot slot = this.slots.get(slotNumber); + if (slot == null || !slot.canTakeItems(player)) { + return ItemStack.EMPTY; + } + + ItemStack remaining = ItemStack.EMPTY; + if (slot != null && slot.hasStack()) { + ItemStack toTransfer = slot.getStack(); + remaining = toTransfer.copy(); + //if (slot.inventory==blockInventory) { + if (blockInventory!=null) { + if (slot.inventory==blockInventory) { + //Try to transfer the item from the block into the player's inventory + if (!this.insertItem(toTransfer, this.playerInventory, true)) { + return ItemStack.EMPTY; + } + } else if (!this.insertItem(toTransfer, this.blockInventory, false)) { //Try to transfer the item from the player to the block + return ItemStack.EMPTY; + } + } else { + //There's no block, just swap between the player's storage and their hotbar + if (!swapHotbar(toTransfer, slotNumber, this.playerInventory)) { + return ItemStack.EMPTY; + } + } + + if (toTransfer.isEmpty()) { + slot.setStack(ItemStack.EMPTY); + } else { + slot.markDirty(); + } + } + + return remaining; + } else { + return super.onSlotClick(slotNumber, button, action, player); + } + } + + /** WILL MODIFY toInsert! Returns true if anything was inserted. */ + private boolean insertIntoExisting(ItemStack toInsert, Slot slot) { + ItemStack curSlotStack = slot.getStack(); + if (!curSlotStack.isEmpty() && canStacksCombine(toInsert, curSlotStack)) { + int combinedAmount = curSlotStack.getCount() + toInsert.getCount(); + if (combinedAmount <= toInsert.getMaxCount()) { + toInsert.setCount(0); + curSlotStack.setCount(combinedAmount); + slot.markDirty(); + return true; + } else if (curSlotStack.getCount() < toInsert.getMaxCount()) { + toInsert.decrement(toInsert.getMaxCount() - curSlotStack.getCount()); + curSlotStack.setCount(toInsert.getMaxCount()); + slot.markDirty(); + return true; + } + } + return false; + } + + /** WILL MODIFY toInsert! Returns true if anything was inserted. */ + private boolean insertIntoEmpty(ItemStack toInsert, Slot slot) { + ItemStack curSlotStack = slot.getStack(); + if (curSlotStack.isEmpty() && slot.canInsert(toInsert)) { + if (toInsert.getCount() > slot.getMaxStackAmount()) { + slot.setStack(toInsert.split(slot.getMaxStackAmount())); + } else { + slot.setStack(toInsert.split(toInsert.getCount())); + } + + slot.markDirty(); + return true; + } + + return false; + } + + private boolean insertItem(ItemStack toInsert, Inventory inventory, boolean walkBackwards) { + //Make a unified list of slots *only from this inventory* + ArrayList inventorySlots = new ArrayList<>(); + for(Slot slot : slots) { + if (slot.inventory==inventory) inventorySlots.add(slot); + } + if (inventorySlots.isEmpty()) return false; + + //Try to insert it on top of existing stacks + boolean inserted = false; + if (walkBackwards) { + for(int i=inventorySlots.size()-1; i>=0; i--) { + Slot curSlot = inventorySlots.get(i); + if (insertIntoExisting(toInsert, curSlot)) inserted = true; + if (toInsert.isEmpty()) break; + } + } else { + for(int i=0; i=0; i--) { + Slot curSlot = inventorySlots.get(i); + if (insertIntoEmpty(toInsert, curSlot)) inserted = true; + if (toInsert.isEmpty()) break; + } + } else { + for(int i=0; i storageSlots = new ArrayList<>(); + ArrayList hotbarSlots = new ArrayList<>(); + boolean swapToStorage = true; + boolean inserted = false; + + for(Slot slot : slots) { + if (slot.inventory==inventory && slot instanceof ValidatedSlot) { + int index = ((ValidatedSlot)slot).getInventoryIndex(); + if (PlayerInventory.isValidHotbarIndex(index)) { + hotbarSlots.add(slot); + } else { + storageSlots.add(slot); + if (index==slotNumber) swapToStorage = false; + } + } + } + if (storageSlots.isEmpty() || hotbarSlots.isEmpty()) return false; + + if (swapToStorage) { + //swap from hotbar to storage + for(int i=0; i=wx && x=wy && y { + BlockState state = world.getBlockState(pos); + Block b = state.getBlock(); + + if (b instanceof InventoryProvider) { + return ((InventoryProvider)b).getInventory(state, world, pos); + } + + BlockEntity be = world.getBlockEntity(pos); + if (be!=null) { + if (be instanceof InventoryProvider) { + return ((InventoryProvider)be).getInventory(state, world, pos); + } else if (be instanceof Inventory) { + return (Inventory)be; + } + } + + return EmptyInventory.INSTANCE; + }).orElse(EmptyInventory.INSTANCE); + } + + public static PropertyDelegate getBlockPropertyDelegate(ScreenHandlerContext ctx) { + return ctx.run((world, pos) -> { + BlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + if (block instanceof PropertyDelegateHolder) { + return ((PropertyDelegateHolder)block).getPropertyDelegate(); + } + BlockEntity be = world.getBlockEntity(pos); + if (be!=null && be instanceof PropertyDelegateHolder) { + return ((PropertyDelegateHolder)be).getPropertyDelegate(); + } + + return new ArrayPropertyDelegate(0); + }).orElse(new ArrayPropertyDelegate(0)); + } + + //extends ScreenHandler { + @Override + public boolean canUse(PlayerEntity entity) { + return (blockInventory!=null) ? blockInventory.canPlayerUseInv(entity) : true; + } + //} + + @Override + public boolean isFocused(WWidget widget) { + return focus == widget; + } + + @Override + public WWidget getFocus() { + return focus; + } + + @Override + public void requestFocus(WWidget widget) { + //TODO: Are there circumstances where focus can't be stolen? + if (focus==widget) return; //Nothing happens if we're already focused + if (!widget.canFocus()) return; //This is kind of a gotcha but needs to happen + if (focus!=null) focus.onFocusLost(); + focus = widget; + focus.onFocusGained(); + } + + @Override + public void releaseFocus(WWidget widget) { + if (focus==widget) { + focus = null; + widget.onFocusLost(); + } + } +} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java index 83c1837..a9597dc 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java @@ -4,7 +4,7 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.render.DiffuseLighting; import org.lwjgl.glfw.GLFW; -import io.github.cottonmc.cotton.gui.CottonCraftingController; +import io.github.cottonmc.cotton.gui.CottonInventoryController; import io.github.cottonmc.cotton.gui.widget.WPanel; import io.github.cottonmc.cotton.gui.widget.WWidget; import net.minecraft.client.MinecraftClient; -- cgit