|
|
@@ -0,0 +1,203 @@
|
|
|
+package me.lethunderhawk.profile.data.sacks.foraging;
|
|
|
+
|
|
|
+import me.lethunderhawk.fluxapi.FluxService;
|
|
|
+import me.lethunderhawk.fluxapi.profile.ProfileManager;
|
|
|
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
|
|
|
+import me.lethunderhawk.fluxapi.util.itemdesign.ItemOptions;
|
|
|
+import me.lethunderhawk.fluxapi.util.itemdesign.LoreDesigner;
|
|
|
+import me.lethunderhawk.profile.data.sacks.Sack;
|
|
|
+import me.lethunderhawk.util.StringUtil;
|
|
|
+import net.kyori.adventure.text.Component;
|
|
|
+import net.kyori.adventure.text.format.NamedTextColor;
|
|
|
+import org.bukkit.Material;
|
|
|
+import org.bukkit.entity.Player;
|
|
|
+import org.bukkit.event.inventory.ClickType;
|
|
|
+import org.bukkit.inventory.ItemStack;
|
|
|
+import org.bukkit.inventory.PlayerInventory;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+public class ForagingSackGUI extends InventoryGUI {
|
|
|
+ private int currentPage = 0;
|
|
|
+ private List<Material> materials;
|
|
|
+ private Sack sack;
|
|
|
+ private Player player;
|
|
|
+
|
|
|
+ public ForagingSackGUI(Player p, int page) {
|
|
|
+ super("Your Foraging Sack", calculateSize(p), p);
|
|
|
+ this.currentPage = page;
|
|
|
+ }
|
|
|
+ private static int calculateSize(Player p) {
|
|
|
+ // Always minimum 4 rows (36)
|
|
|
+ return 54;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void performAdditionalComputationOnPlayer(Player player) {
|
|
|
+ sack = FluxService.get(ProfileManager.class)
|
|
|
+ .getProfile(player.getUniqueId())
|
|
|
+ .getSubProfile("foraging_sack", ForagingSack.class);
|
|
|
+
|
|
|
+ this.player = player;
|
|
|
+ this.materials = new ArrayList<>(sack.getAssociatedSackMap().keySet());
|
|
|
+ }
|
|
|
+
|
|
|
+ private int getItemsPerPage() {
|
|
|
+ int rows = getInventory().getSize() / 9;
|
|
|
+ int usableRows = rows - 2; // remove top & bottom border
|
|
|
+ return usableRows * 7;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addSackItem(int slot, Material material) {
|
|
|
+
|
|
|
+ String materialName = StringUtil.toCamelCase(material.name());
|
|
|
+
|
|
|
+ List<Component> lore = LoreDesigner.createLore(
|
|
|
+ "<dark_gray>Foraging Sack </dark_gray>" +
|
|
|
+ "<br><br>" +
|
|
|
+ "Stored: " +
|
|
|
+ (sack.getMaterialAmount(material) == 0
|
|
|
+ ? "<dark_gray>0</dark_gray>"
|
|
|
+ : "<yellow>" + sack.getMaterialAmount(material) + "</yellow>")
|
|
|
+ + "/" + sack.getMaxMaterialAmount(material) +
|
|
|
+ "<br><br><aqua>Right-Click for stack!</aqua>" +
|
|
|
+ "<br><yellow>Click to pickup!</yellow>",
|
|
|
+ "This is a string long enough to have everything inside of it",
|
|
|
+ NamedTextColor.GRAY
|
|
|
+ );
|
|
|
+
|
|
|
+ setItemWithClickAction(slot,
|
|
|
+ new ItemOptions(material)
|
|
|
+ .setName(Component.text(materialName, NamedTextColor.GREEN))
|
|
|
+ .setLore(lore)
|
|
|
+ .buildItemStack(),
|
|
|
+ (p, type) -> doSackAction(type, material)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doSackAction(ClickType type, Material material) {
|
|
|
+
|
|
|
+ int amountToTake = 1;
|
|
|
+
|
|
|
+ if (type == ClickType.RIGHT || type == ClickType.SHIFT_RIGHT) {
|
|
|
+ amountToTake = 64;
|
|
|
+ }
|
|
|
+
|
|
|
+ int removed = sack.takeOutItem(material, amountToTake);
|
|
|
+
|
|
|
+ if (removed > 0) {
|
|
|
+ ItemStack stack = new ItemStack(material, removed);
|
|
|
+ HashMap<Integer, ItemStack> leftover = player.getInventory().addItem(stack);
|
|
|
+
|
|
|
+ // If inventory full → return items back into sack
|
|
|
+ if (!leftover.isEmpty()) {
|
|
|
+ int notStored = leftover.values().stream()
|
|
|
+ .mapToInt(ItemStack::getAmount)
|
|
|
+ .sum();
|
|
|
+ sack.addItem(material, notStored);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ player.updateInventory();
|
|
|
+ update();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void buildContent() {
|
|
|
+
|
|
|
+ getInventory().clear();
|
|
|
+ fillGlassPaneBackground();
|
|
|
+
|
|
|
+ int itemsPerPage = getItemsPerPage();
|
|
|
+ int startIndex = currentPage * itemsPerPage;
|
|
|
+ int endIndex = Math.min(startIndex + itemsPerPage, materials.size());
|
|
|
+
|
|
|
+ int slot = 10;
|
|
|
+
|
|
|
+ for (int index = startIndex; index < endIndex; index++) {
|
|
|
+
|
|
|
+ if (slot % 9 == 8) {
|
|
|
+ slot += 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ addSackItem(slot, materials.get(index));
|
|
|
+ slot++;
|
|
|
+ }
|
|
|
+
|
|
|
+ setCloseButton(getInventory().getSize() - 5);
|
|
|
+ setAddAllItemsItem();
|
|
|
+
|
|
|
+ addPaginationButtons();
|
|
|
+ }
|
|
|
+ private void addPaginationButtons() {
|
|
|
+
|
|
|
+ int itemsPerPage = getItemsPerPage();
|
|
|
+ int totalPages = (int) Math.ceil((double) materials.size() / itemsPerPage);
|
|
|
+
|
|
|
+ if (currentPage > 0) {
|
|
|
+ setItemWithClickAction(
|
|
|
+ getInventory().getSize() - 9,
|
|
|
+ new ItemStack(Material.ARROW),
|
|
|
+ (p, t) -> openPage(currentPage - 1)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentPage < totalPages - 1) {
|
|
|
+ setItemWithClickAction(
|
|
|
+ getInventory().getSize() - 1,
|
|
|
+ new ItemStack(Material.ARROW),
|
|
|
+ (p, t) -> openPage(currentPage + 1)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private void openPage(int page) {
|
|
|
+ ForagingSackGUI newGui = new ForagingSackGUI(player, page);
|
|
|
+ //newGui.performAdditionalComputationOnPlayer(player); // Recompute the materials for the new page
|
|
|
+ openNext(player, newGui); // Open the new GUI
|
|
|
+ newGui.update(); // Ensure the content is displayed immediately.
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void setAddAllItemsItem() {
|
|
|
+ setItemWithClickAction(getInventory().getSize() - 4,
|
|
|
+ new ItemOptions(Material.CAULDRON)
|
|
|
+ .setName(Component.text("Add all items into the Sack", NamedTextColor.GREEN))
|
|
|
+ .setLore(LoreDesigner.createLore(
|
|
|
+ "<br>Allows you to put all items from your inventory into the sack",
|
|
|
+ "This is an example width reference",
|
|
|
+ NamedTextColor.DARK_GRAY)
|
|
|
+ )
|
|
|
+ .buildItemStack(), this::putAllItemsIn);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void putAllItemsIn(Player player, ClickType type) {
|
|
|
+
|
|
|
+ PlayerInventory inv = player.getInventory();
|
|
|
+
|
|
|
+ for (ItemStack stack : inv.getContents()) {
|
|
|
+
|
|
|
+ if (stack == null) continue;
|
|
|
+ if (stack.getType() == Material.AIR) continue;
|
|
|
+
|
|
|
+ Material material = stack.getType();
|
|
|
+ int amount = stack.getAmount();
|
|
|
+
|
|
|
+ // Try adding to sack
|
|
|
+ int leftover = sack.addItem(material, amount);
|
|
|
+
|
|
|
+ int successfullyAdded = amount - leftover;
|
|
|
+
|
|
|
+ if (successfullyAdded > 0) {
|
|
|
+ stack.setAmount(leftover); // leave leftover in inventory
|
|
|
+ }
|
|
|
+ }
|
|
|
+ player.updateInventory();
|
|
|
+ update();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void update() {
|
|
|
+ buildContent();
|
|
|
+ }
|
|
|
+}
|