package com.lifeknight.relaymchub.player; import com.lifeknight.relaymchub.Main; import com.lifeknight.relaymcutils.RelayMCUtils; import com.lifeknight.relaymcutils.player.*; import com.lifeknight.relayutils.basic.Miscellaneous; import com.lifeknight.relayutils.basic.SwearUtils; import com.lifeknight.relayutils.basic.Text; import com.lifeknight.relayutils.filter.ChatFilter; import com.lifeknight.relayutils.player.Group; import com.lifeknight.relayutils.utilities.ItemUtilities; import net.kyori.adventure.text.Component; import org.bukkit.*; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; import java.util.*; import java.util.function.Consumer; import static org.bukkit.ChatColor.*; public class EditCustomKitGUI extends SmartGUI { public static final String DEFAULT_NAME = "Untitled Kit"; public static final int HELMET = 10; public static final int CHESTPLATE = 11; public static final int LEGGINGS = 12; public static final int BOOTS = 13; public static final int OFF_HAND = 15; public static final int REPRESENTATIVE = -7; public static final int INVENTORY_START = 18; public static final int INVENTORY_END = 44; public static final int HOTBAR_START = 45; public static final int HOTBAR_END = 53; public final HubPlayer owner; public final Kit originalKit; public String id; protected final CustomDuelsKit customDuelsKit; protected final HubGameSettings gameSettings; private final String originalId; boolean shared = false; public String name = DEFAULT_NAME; protected ItemStack representative = new ItemStack(Material.RED_BANNER); protected ItemStack helmet = null; protected ItemStack chestplate = null; protected ItemStack leggings = null; protected ItemStack boots = null; protected ItemStack offHand = null; protected ItemStack[] inventory = new ItemStack[27]; protected ItemStack[] hotbar = new ItemStack[9]; protected ItemStack clipboard = null; protected DuelMap map = null; protected String customMap = null; private final List<UUID> creators = new ArrayList<>(); public String publicCustomMap = null; private boolean deleted = false; public EditCustomKitGUI(CustomDuelsKit customDuelsKit, HubPlayer owner, int id) { super("Custom Kit", 6, false); this.customDuelsKit = customDuelsKit; this.originalKit = customDuelsKit == null ? null : customDuelsKit.getKit(); if (this.customDuelsKit != null) { if (!this.customDuelsKit.getOwner().equals(owner.getUUID())) { this.creators.add(this.customDuelsKit.getOwner()); } for (UUID creator : this.customDuelsKit.getCreators()) { if (!creator.equals(owner.getUUID())) { creators.add(creator); } } if (this.customDuelsKit.getPublicCustomMap() != null && !this.customDuelsKit.getPublicCustomMap().isEmpty()) { this.publicCustomMap = this.customDuelsKit.getPublicCustomMap(); } } this.originalId = this.customDuelsKit == null ? null : this.customDuelsKit.getId(); this.owner = owner; this.gameSettings = HubPlayer.getDefaultCustomDuelsGameSettings(); if (customDuelsKit != null) { this.gameSettings.applyFromJson(customDuelsKit.getGameSettings()); if (!customDuelsKit.getMaps().isEmpty()) { this.map = DuelMap.getDuelMap(customDuelsKit.getMaps().get(0)); if (this.map == null) { this.customMap = customDuelsKit.getMaps().get(0); } } } if (this.customDuelsKit != null) { this.name = customDuelsKit.getKit().name; if (this.customDuelsKit.isVisible()) { this.id = CustomDuelsKit.generateNewId(); } else { this.id = customDuelsKit.getId(); } } else { this.id = CustomDuelsKit.generateNewId(); this.name = "Kit #" + (this.owner.getCustomDuelKits().size() + 1); } this.setFromOriginal(); this.fill(); this.owner.openGui(this); this.owner.setLastCustomKitGui(this); } public ItemStack getFromKitItem(KitItem kitItem) { return kitItem == null ? null : kitItem.itemStack; } public void setFromKit(Kit kit) { this.helmet = this.getFromKitItem(kit.helmet); this.chestplate = this.getFromKitItem(kit.chestplate); this.leggings = this.getFromKitItem(kit.leggings); this.boots = this.getFromKitItem(kit.boots); this.offHand = null; if (kit.representative != null) { this.representative = this.getFromKitItem(kit.representative); } this.inventory = new ItemStack[27]; this.hotbar = new ItemStack[9]; for (KitItem item : kit.items) { if (item.slot >= 0) { if (item.slot < 9) { this.hotbar[item.slot] = item.itemStack; } else if (item.slot < 36) { this.inventory[item.slot - 9] = item.itemStack; } else if (item.slot == 40) { this.offHand = item.itemStack; } } } this.fill(); } public void setFromOriginal() { if (this.hasOriginal()) { this.setFromKit(this.originalKit); } else { this.representative = new ItemStack(Material.RED_BANNER); this.helmet = null; this.chestplate = null; this.leggings = null; this.boots = null; this.offHand = null; this.inventory = new ItemStack[27]; this.hotbar = new ItemStack[9]; } } public void fill() { this.owner.isCreatingCustomKit = true; ItemStack armorEmpty = new ItemStack(Material.RED_STAINED_GLASS_PANE); this.add(HELMET, this.helmet == null ? armorEmpty : this.helmet.clone(), (player, b, b2) -> this.editSlot(HELMET, b, b2), this.helmet == null ? GOLD + "Helmet" : ""); this.add(CHESTPLATE, this.chestplate == null ? armorEmpty : this.chestplate.clone(), (player, b, b2) -> this.editSlot(CHESTPLATE, b, b2), this.chestplate == null ? GOLD + "Chestplate" : this.chestplate.getItemMeta().getDisplayName()); this.add(LEGGINGS, this.leggings == null ? armorEmpty : this.leggings.clone(), (player, b, b2) -> this.editSlot(LEGGINGS, b, b2), this.leggings == null ? GOLD + "Leggings" : this.leggings.getItemMeta().getDisplayName()); this.add(BOOTS, this.boots == null ? armorEmpty : this.boots.clone(), (player, b, b2) -> this.editSlot(BOOTS, b, b2), this.boots == null ? GOLD + "Boots" : this.boots.getItemMeta().getDisplayName()); this.add(OFF_HAND, this.offHand == null ? new ItemStack(Material.LIME_STAINED_GLASS_PANE) : this.offHand.clone(), (player, b, b2) -> this.editSlot(OFF_HAND, b, b2), this.offHand == null ? AQUA + "Offhand" : this.offHand.getItemMeta().getDisplayName()); //this.add(REPRESENTATIVE, this.representative == null ? armorEmpty : this.representative.clone(), (player, b, b2) -> this.editSlot(REPRESENTATIVE, b, b2), RED + "Kit Icon"); for (int i = INVENTORY_START; i <= INVENTORY_END; i++) { int finalI = i; int index; if (finalI < 27) { index = finalI % 9 + 18; } else if (finalI < 36) { index = finalI % 9 + 9; } else { index = finalI % 9; } ItemStack itemStack = this.inventory[index]; this.add(i, itemStack == null ? new ItemStack(Material.LIGHT_BLUE_STAINED_GLASS_PANE) : itemStack, (player, b, b2) -> this.editSlot(finalI, b, b2), itemStack == null ? YELLOW + "Inventory" : itemStack.getItemMeta().getDisplayName()); } for (int i = HOTBAR_START; i <= HOTBAR_END; i++) { int finalI = i; ItemStack itemStack = this.hotbar[finalI % 9]; this.add(i, itemStack == null ? new ItemStack(Material.BLUE_STAINED_GLASS_PANE) : itemStack, (player, b, b2) -> this.editSlot(finalI, b, b2), itemStack == null ? LIGHT_PURPLE + "Hotbar" : itemStack.getItemMeta().getDisplayName()); } this.add(0, Material.PAINTING, (player, b, b2) -> { { this.close(this.owner.getPlayer()); this.owner.sendSuccessMessage("Your kit has been saved and selected."); this.owner.playSuccessSound(); this.owner.isCreatingCustomKit = false; } }, GREEN + "Save"); this.add(1, Material.WRITABLE_BOOK, (player, b, b1) -> { if (this.owner.shareCustomKit(this.getAsKit(), this.originalId)) { this.shared = true; this.owner.closeInventory(); } }, GREEN + "Share Kit", GRAY + "Share this kit."); this.add(17, Material.BOOK, (player, b, b2) -> { }, LIGHT_PURPLE + "Usage", GRAY + "Left-Click a slot to set an item.", GRAY + "Right-Click a slot to edit an item.", GRAY + "Right-Click an empty slot to use a preset.", GRAY + "Shift Right-Click a slot to copy or paste.", GRAY + "Shift Left-Click a slot to clear."); this.add(2, Material.NAME_TAG, (player, b, b2) -> this.showLabelMenu(), AQUA + "Edit Label", GRAY + "Change the name and icon of this kit."); /* this.add(1, Material.WRITABLE_BOOK, (player, b, b2) -> { this.showLabelMenu(); }, LIGHT_PURPLE + "Label", GRAY + "Change the name and kit icon of this kit."); */ //this.add(5, Material.NETHERITE_SCRAP, (player, b, b2) -> this.reset(), YELLOW + "Reset", GRAY + "Revert this kit to its state before you changed anything."); //this.add(6, Material.BARRIER, (player, b, b2) -> this.cancel(), RED + "Cancel"); this.add(5, Material.COMMAND_BLOCK, (player, b, b1) -> this.editCreative(), GOLD + "Creative Editor", GRAY + "Edit your kit in creative mode."); this.add(6, Material.MAP, (player, b, b1) -> this.selectMap(), GOLD + "Map", GRAY + "Select a map to play on."); this.add(7, Material.COMPARATOR, (player, b, b2) -> this.editSettings(), AQUA + "Settings", GRAY + "Edit game settings."); this.add(8, Material.REDSTONE, (player, b, b2) -> this.delete(), DARK_RED + "Delete"); } protected void editCreative() { this.close(this.owner.getPlayer()); this.owner.getSmartPlayer().clear(); this.getAsKit().getKit().giveItemsToPlayer(this.owner.getPlayer(), true); this.owner.getSmartPlayer().setGameMode(GameMode.CREATIVE); RelayMCUtils.scheduleSyncDelayedTask(() -> this.owner.setCreatingCustomKitCreative(true), 0.1); this.owner.sendInfoMessage("Open your inventory to begin editing your kit."); this.owner.sendMessage("%sOnce you have finished, close your inventory to the Kit Editor.", AQUA); } protected void editSettings() { this.owner.openGui(this.gameSettings.getGUI(this.owner.getHighestGroup(), this)); this.owner.playClickSound(); } protected void selectMap() { SmartGUI mapSelector = new SmartGUI("Map", 6, false) { @Override public void onClose() { save(); } @Override public void open(Player player) { this.fill(); super.open(player); } public void fill() { clearAll(); for (int i = 0; i < DuelMap.getDuelMaps().length; i++) { DuelMap duelMap = DuelMap.getDuelMaps()[i]; int row = i / 7; int index = 9 * (row + 1) + i % 7 + 1; add(index, map == duelMap ? ItemUtilities.enchanted(duelMap.getRepresentative()) : new ItemStack(duelMap.getRepresentative()), (player, b, b1) -> { if (map != duelMap) { map = duelMap; customMap = null; fill(); } owner.playSuccessSound(); }, AQUA + duelMap.getName()); } add(0, Material.ARROW, (player, b, b1) -> back(), RED + "Back"); final int startIndex = 45; for (int i = 0; i < 5; i++) { List<CustomMap> customMaps = Miscellaneous.getList(owner.getCustomMaps()); if (i < customMaps.size()) { CustomMap customMapObj = customMaps.get(i); add(startIndex + i, customMapObj.getId().equals(customMap) ? ItemUtilities.enchanted(customMapObj.getRepresentative()) : new ItemStack(customMapObj.getRepresentative()), (player, b, b1) -> { if (b1) { owner.editSocialSettings(customMapObj, false); } else { if (b) { owner.editCustomMap(customMapObj, false); customMap = customMapObj.getId(); map = null; } else { if (!customMapObj.getId().equalsIgnoreCase(customMap)) { customMap = customMapObj.getId(); map = null; fill(); } owner.playSuccessSound(); } } }, AQUA + customMapObj.getName(), (customMapObj.getId().equalsIgnoreCase(customMap) ? GREEN + "Selected" : GRAY + "Left-click to select."), GRAY + "Right-click to edit.", GRAY + "Shift-click to edit settings."); } else { if (i == 0 || owner.isInGroupOrHigher(Group.CHAMPION)) { add(startIndex + i, Material.OAK_BUTTON, (((player, b, b1) -> createCustomMap())), GREEN + "Create Custom Map", GRAY + "Make your own map."); } else { add(startIndex + i, Material.STONE_BUTTON, (player, b, b1) -> owner.playErrorSound(), ChatColor.RED + ChatColor.BOLD.toString() + "CREATE MAP", GRAY + ITALIC.toString() + "Upgrade to Premium to unlock this slot."); } } } final boolean[] hasPublicMap = {publicCustomMap != null}; CustomMap publicCustomMapObj; if (hasPublicMap[0]) { publicCustomMapObj = CustomMap.hasCustomMap(publicCustomMap) ? CustomMap.getCustomMap(publicCustomMap) : null; } else { publicCustomMapObj = null; } if (hasPublicMap[0] && publicCustomMapObj != null) { List<String> description = new ArrayList<>(); boolean isSelected = Text.comparablyEquals(publicCustomMap, customMap); if (isSelected) { description.add(GREEN + "SELECTED"); } description.add(GRAY + "The public custom map you have for this kit."); description.add(GRAY + "Right-Click to to preview."); add(51, isSelected ? ItemUtilities.enchanted(publicCustomMapObj.getRepresentative()) : new ItemStack(publicCustomMapObj.getRepresentative()), (player, b, b1) -> { if (b) { owner.selectPublicCustomMap(EditCustomKitGUI.this, publicCustomMapObj, true); } else { if (!isSelected) { EditCustomKitGUI.this.publicCustomMap = publicCustomMapObj.getId(); customMap = publicCustomMapObj.getId(); owner.playSuccessSound(); map = null; fill(); } } }, AQUA + publicCustomMapObj.getName(), description); } else { add(51, Material.POLISHED_BLACKSTONE_BUTTON, (player, b, b1) -> { enterCustomMapCode(); }, YELLOW + "Public Custom Map", GRAY + "Click to enter a custom map code."); } add(52, Material.EMERALD, (player, b, b1) -> owner.showCustomMapHistory(EditCustomKitGUI.this), GREEN + "History", GRAY + "View your recently played maps."); add(53, Material.CLOCK, (player, b, b1) -> owner.browsePublicMaps(EditCustomKitGUI.this, false), GOLD + "Public Maps", GRAY + "Browse public custom maps."); fillEmptySpots(); } }; mapSelector.open(this.owner.getPlayer()); this.owner.playClickSound(); } private void enterCustomMapCode() { getStringInput("Enter Code", null, s -> { if (!s.isEmpty()) { Main.async(() -> { CustomMap customMap1 = CustomMap.getCustomMap(s); if (customMap1 != null) { this.publicCustomMap = customMap1.getId(); this.owner.playSuccessSound(); } else { this.owner.playErrorSound(); this.owner.sendErrorMessage("No public map by the code %s%s%s found.", YELLOW, s, RED); } }); } selectMap(); }); } public void createCustomMap() { CustomMap customMap = new CustomMap(this.owner.getSmartPlayer()); this.owner.editCustomMap(customMap, true); this.customMap = customMap.getId(); this.map = null; } public void editSlot(int slot, boolean rightClick, boolean shiftClick) { if (slot < 0) { this.setItem(slot); return; } if (this.hasItemAtSlot(slot)) { if (rightClick) { if (shiftClick) { this.copyToClipboard(slot); } else { this.editItem(slot); } } else { if (shiftClick) { this.updateItem(slot, null); //this.owner.sendErrorMessage("You must copy an item before pasting it! Use Shift + Right Click to copy."); } else { this.setItem(slot); } } } else { if (rightClick) { if (shiftClick) { this.updateItem(slot, this.clipboard); //this.owner.sendErrorMessage("You must put an item in the slot before copying it!"); } else { //this.owner.sendErrorMessage("You must put an item in the slot before editing it!"); this.showPresetMenu(); } } else { if (shiftClick) { this.owner.sendSuccessMessage("Pasted clipboard."); this.updateItem(slot, this.clipboard); } else { this.setItem(slot); } } } } public void showPresetMenu() { List<Kit> duelsKits = Miscellaneous.getList(Kits.DUELS_CRYSTAL, Kits.DUELS_NETHERITE_POT, Kits.DUELS_DIAMOND_POT, Kits.DUELS_UHC, Kits.DUELS_AXE, Kits.DUELS_SWORD, Kits.SMP_KIT, Kits.DUELS_OP); SmartGUI presetSelect = new SmartGUI("Select Preset", 1, false); for (int i = 0; i < duelsKits.size(); i++) { Kit kit = duelsKits.get(i); presetSelect.add(i, kit.representative.itemStack, (player, b, b1) -> this.selectPreset(kit), GOLD + BOLD.toString() + kit.name.toUpperCase(), Miscellaneous.processList(s -> GRAY + s, kit.description.split(","))); } presetSelect.add(8, Material.BARRIER, (player, b, b1) -> this.back(), RED + "Back"); this.owner.openGui(presetSelect); this.owner.playClickSound(); } protected void selectPreset(Kit kit) { this.setFromKit(kit); if (kit == Kits.DUELS_AXE) { this.gameSettings.getSetting("rounds_to_win").setValueAndDefault(2); this.gameSettings.getSetting("block_drops").setValueAndDefault(false); } if (Miscellaneous.getList(Kits.DUELS_DIAMOND_POT, Kits.DUELS_NETHERITE_POT, Kits.DUELS_AXE, Kits.DUELS_SWORD).contains(kit)) { this.gameSettings.getSetting("break").setValueAndDefault(false); } if (kit == Kits.DUELS_SWORD) { this.gameSettings.getSetting("natural_regen").setValueAndDefault(false); } if (kit == Kits.DUELS_CRYSTAL) { this.gameSettings.getSetting("durability").setValueAndDefault(true); this.gameSettings.getSetting("rounds_to_win").setValueAndDefault(1); this.gameSettings.getSetting("time").setValueAndDefault(30); } this.back(); } public void copyToClipboard(int slot) { this.clipboard = this.getItemStackOfSlot(slot); this.owner.sendSuccessMessage("Copied item. Use Shift + Left Click to paste."); this.owner.playSuccessSound(); } public void setItem(int slot) { SlotType slotType = this.getTypeOfIndex(slot); switch (slotType) { case HELMET, CHESTPLATE, BOOTS, LEGGINGS -> { this.showItemSelect(slot, this.getMaterialsForType(slotType)); return; } } this.showCategorySelect(slot); } public List<Material> getMaterialsForType(SlotType slotType) { return switch (slotType) { case HELMET -> Miscellaneous.getList( Material.CARVED_PUMPKIN, Material.TURTLE_HELMET, Material.LEATHER_HELMET, Material.CHAINMAIL_HELMET, Material.GOLDEN_HELMET, Material.IRON_HELMET, Material.DIAMOND_HELMET, Material.NETHERITE_HELMET); case CHESTPLATE -> Miscellaneous.getList( Material.LEATHER_CHESTPLATE, Material.CHAINMAIL_CHESTPLATE, Material.GOLDEN_CHESTPLATE, Material.IRON_CHESTPLATE, Material.DIAMOND_CHESTPLATE, Material.NETHERITE_CHESTPLATE, Material.ELYTRA); case LEGGINGS -> Miscellaneous.getList( Material.LEATHER_LEGGINGS, Material.CHAINMAIL_LEGGINGS, Material.GOLDEN_LEGGINGS, Material.IRON_LEGGINGS, Material.DIAMOND_LEGGINGS, Material.NETHERITE_LEGGINGS); case BOOTS -> Miscellaneous.getList( Material.LEATHER_BOOTS, Material.CHAINMAIL_BOOTS, Material.GOLDEN_BOOTS, Material.IRON_BOOTS, Material.DIAMOND_BOOTS, Material.NETHERITE_BOOTS); default -> new ArrayList<>(); }; } public void editItem(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); if (itemStack == null) return; SmartGUI smartGUI = new SmartGUI("Edit", 5, false); boolean isPotion = itemStack.getItemMeta() instanceof PotionMeta; if (isPotion) { smartGUI.add(10, Material.GLOWSTONE_DUST, (player, b, b2) -> this.changeAmplifier(slot), YELLOW + "Change Amplifier"); smartGUI.add(12, Material.REDSTONE, (player, b, b2) -> this.changeDuration(slot), YELLOW + "Change Duration"); smartGUI.add(14, Material.ARROW, (player, b, b2) -> this.changeCount(slot), YELLOW + "Change Count"); smartGUI.add(16, Material.NAME_TAG, (player, b, b2) -> this.changeName(slot), YELLOW + "Change Name"); } else { Material material = itemStack.getType(); int maxCount = material.getMaxStackSize(); if (getApplicableEnchantments(slot).isEmpty()) { if (maxCount == 0 || maxCount == 1) { /*smartGUI.add(12, Material.ANVIL, (player, b, b2) -> */ this.changeDurability(slot)/*, YELLOW + "Change Durability")*/; } else { /*smartGUI.add(12, Material.ARROW, (player, b, b2) -> */ this.changeCount(slot)/*, YELLOW + "Change Count")*/; } //smartGUI.add(14, Material.NAME_TAG, (player, b, b2) -> this.changeName(slot), YELLOW + "Change Name"); return; } else { if (maxCount > 1) { smartGUI.add(12, Material.ARROW, (player, b, b2) -> this.changeCount(slot), YELLOW + "Change Count"); smartGUI.add(14, Material.ENCHANTING_TABLE, (player, b, b2) -> this.enchantMenu(slot), YELLOW + "Change Enchantments"); } else { this.enchantMenu(slot); return; } //smartGUI.add(15, Material.NAME_TAG, (player, b, b2) -> this.changeName(slot), YELLOW + "Change Name"); } } smartGUI.add(31, Material.BARRIER, (player, b, b2) -> this.back(), RED + "Cancel"); this.owner.openGui(smartGUI); this.owner.playClickSound(); } private void changeFireworkCharge(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); int max = this.getMaxAmplifier(); FireworkMeta fireWorkMeta = (FireworkMeta) itemStack.getItemMeta(); this.getStringInput("Charge (0 - " + max + ")", String.valueOf(fireWorkMeta.getEffectsSize()), s -> { try { int i = Integer.parseInt(s); i = Math.max(0, Math.min(max, i)); ItemStack changed = itemStack.clone(); int finalI1 = i; ItemUtilities.edit(changed, itemMeta -> { FireworkMeta fireworkMeta = (FireworkMeta) itemMeta; fireworkMeta.clearEffects(); for (int j = 0; j < finalI1; j++) { fireworkMeta.addEffect(FireworkEffect.builder().withColor(Color.RED).withFlicker().build()); } }); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.editItem(slot); }); } public void changeFireworkDuration(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); int max = this.getMaxAmplifier(); FireworkMeta fireWorkMeta = (FireworkMeta) itemStack.getItemMeta(); this.getStringInput("Duration (1 - " + max + ")", String.valueOf(fireWorkMeta.getPower()), s -> { try { int i = Integer.parseInt(s); i = Math.max(1, Math.min(max, i)); ItemStack changed = itemStack.clone(); int finalI1 = i; ItemUtilities.edit(changed, itemMeta -> { FireworkMeta fireworkMeta = (FireworkMeta) itemMeta; fireworkMeta.setPower(finalI1); }); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.editItem(slot); }); } public boolean isPotion(int slot) { return this.hasItemAtSlot(slot) && this.getItemStackOfSlot(slot).getItemMeta() instanceof PotionMeta; } public void changeCount(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); Material material = itemStack.getType(); int maxCount = material.getMaxStackSize(); if (maxCount == 0 || maxCount == 1) { this.owner.playErrorSound(); this.owner.sendErrorMessage("This item's size cannot be changed!"); return; } int currentCount = itemStack.getAmount(); boolean isFirework = itemStack.getItemMeta() instanceof FireworkMeta; SmartGUI countGUI = new SmartGUI("Count", isFirework ? 4 : 3, false); for (int i = 0; i < 6; i++) { int count; if (i == 0) { count = 1; } else if (i == 1) { count = maxCount / 8; } else { count = (int) (maxCount * ((i - 1) / 4.0)); } final int finalCount = count; countGUI.add(i + 11, new ItemStack(material, finalCount), (player, b, b1) -> { ItemStack changed = itemStack.asQuantity(finalCount); this.updateItem(slot, changed); this.back(); }); } if (isFirework) { countGUI.add(30, Material.CLOCK, (player, b, b1) -> this.changeFireworkCharge(slot), YELLOW + "Change Charge"); countGUI.add(32, Material.FIRE_CHARGE, (player, b, b1) -> this.changeFireworkDuration(slot), YELLOW + "Change Duration"); } countGUI.add(10, Material.WRITABLE_BOOK, (player, b, b1) -> this.getStringInput("Count (1 - " + maxCount + ")", String.valueOf(currentCount), s -> { try { int i = Integer.parseInt(s); i = Math.max(1, Math.min(maxCount, i)); ItemStack changed = itemStack.asQuantity(i); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.back(); }), GOLD + "Custom Count"); this.owner.openGui(countGUI); this.owner.playClickSound(); } public void changeAmplifier(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); int max = this.getMaxAmplifier(); PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta(); int duration; PotionEffectType type; if (potionMeta.hasCustomEffects()) { type = potionMeta.getCustomEffects().get(0).getType(); duration = potionMeta.getCustomEffects().get(0).getDuration(); } else { type = potionMeta.getBasePotionData().getType().getEffectType(); duration = 20 * (potionMeta.getBasePotionData().isUpgraded() ? 7 : 3); } this.getStringInput("Amplifier (0 - " + max + ")", null, s -> { try { int i = Integer.parseInt(s); i = Math.max(0, Math.min(max, i)); ItemStack changed = itemStack.clone(); int finalI = i; ItemUtilities.edit(changed, itemMeta -> { PotionMeta potionMeta1 = (PotionMeta) itemMeta; potionMeta1.setBasePotionData(new PotionData(PotionType.WATER, false, false)); potionMeta1.addCustomEffect(new PotionEffect(type, duration, finalI), true); String start = ""; switch (itemStack.getType()) { case POTION: start = "Potion"; break; case SPLASH_POTION: start = "Splash Potion"; break; case LINGERING_POTION: start = "Lingering Potion"; break; case TIPPED_ARROW: start = "Arrow"; break; } potionMeta1.displayName(Component.text(WHITE + start + " of " + KitItem.PotionKitItem.getPotionName(type))); }); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.editItem(slot); }); } public int getMaxAmplifier() { if (this.owner.isAdministrator()) { return 255; } if (this.owner.isStaff()) { return 32; } if (this.owner.isInGroupOrHigher(Group.YOUTUBE)) { return 16; } return switch (this.owner.getHighestGroup()) { case CHAMPION -> 10; case TIERIII -> 8; case TIERII -> 6; case TIERI -> 4; default -> 2; }; } public int getMaxDuration() { if (this.owner.isAdministrator()) { return 6000; } if (this.owner.isStaff()) { return 600; } if (this.owner.isInGroupOrHigher(Group.YOUTUBE)) { return 300; } switch (this.owner.getHighestGroup()) { case CHAMPION: return 180; case TIERIII: return 90; case TIERII: return 60; case TIERI: return 45; } return 30; } public void changeDurability(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); Material material = itemStack.getType(); if (!(itemStack.getItemMeta() instanceof Damageable) || material.getMaxDurability() == 0) { this.owner.playErrorSound(); this.owner.sendErrorMessage("This item's durability cannot be changed!"); return; } Damageable damageable = (Damageable) itemStack.getItemMeta(); int maxDurability = material.getMaxDurability(); int currentDurability = maxDurability - damageable.getDamage(); this.getStringInput("Durability (1 - " + maxDurability + ")", String.valueOf(currentDurability), s -> { try { int i = Integer.parseInt(s); ItemStack changed = itemStack.clone(); i = Math.max(1, Math.min(maxDurability, i)); int finalI = i; ItemUtilities.edit(changed, itemMeta -> ((Damageable) itemMeta).setDamage(maxDurability - finalI)); this.updateItem(slot, changed, false); } catch (Exception exception) { this.onInvalidInput(); } this.enchantMenu(slot); }); } public void changeDuration(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); int max = this.getMaxDuration(); PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta(); int amplifier; PotionEffectType type; if (potionMeta.hasCustomEffects()) { type = potionMeta.getCustomEffects().get(0).getType(); amplifier = potionMeta.getCustomEffects().get(0).getAmplifier(); } else { type = potionMeta.getBasePotionData().getType().getEffectType(); amplifier = 0; } this.getStringInput("Duration (1 - " + max + ")", null, s -> { try { int i = Integer.parseInt(s); i = Math.max(1, Math.min(max, i)); ItemStack changed = itemStack.clone(); int finalI = i; ItemUtilities.edit(changed, itemMeta -> { PotionMeta potionMeta1 = (PotionMeta) itemMeta; potionMeta1.setBasePotionData(new PotionData(PotionType.WATER, false, false)); potionMeta1.addCustomEffect(new PotionEffect(type, finalI * 20, amplifier), true); String start = ""; switch (itemStack.getType()) { case POTION: start = "Potion"; break; case SPLASH_POTION: start = "Splash Potion"; break; case LINGERING_POTION: start = "Lingering Potion"; break; case TIPPED_ARROW: start = "Arrow"; break; } potionMeta1.displayName(Component.text(WHITE + start + " of " + KitItem.PotionKitItem.getPotionName(type))); }); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.editItem(slot); }); } protected List<Enchantment> getApplicableEnchantments(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); List<Enchantment> applicableEnchantments = Miscellaneous.getList(Enchantment.values()); applicableEnchantments.removeIf(enchantment -> !enchantment.canEnchantItem(itemStack)); return Miscellaneous.without(applicableEnchantments, Enchantment.BINDING_CURSE, Enchantment.VANISHING_CURSE); } public void enchantMenu(int slot) { List<Enchantment> applicableEnchantments = getApplicableEnchantments(slot); //Miscellaneous.addIfAbsent(applicableEnchantments, Enchantment.DAMAGE_ALL); //Miscellaneous.addIfAbsent(applicableEnchantments, Enchantment.KNOCKBACK); if (applicableEnchantments.isEmpty()) { this.owner.playErrorSound(); this.owner.sendErrorMessage("This item cannot be enchanted."); } else { this.selectEnchantment(slot, applicableEnchantments); } } public void selectEnchantment(int slot, List<Enchantment> options) { SmartGUI smartGUI = new SmartGUI("Enchantments", 5, false); int itemIndex = 0; Map<Enchantment, Integer> kitToIndex = new HashMap<>(); for (int row = 1; row < 4 && itemIndex < options.size(); row++) { for (int i = 1; i < 8 && itemIndex < options.size(); i++) { Enchantment enchantment = options.get(itemIndex++); final int currentIndex = row * 9 + i; kitToIndex.put(enchantment, currentIndex); } } ItemStack itemStack = this.getItemStackOfSlot(slot); for (Enchantment enchantment : kitToIndex.keySet()) { int index = kitToIndex.get(enchantment); ItemStack representative; if (itemStack.containsEnchantment(enchantment)) { if (enchantment.getMaxLevel() == 1) { representative = ItemUtilities.enchanted(ItemUtilities.getItemStack(Material.BOOK, AQUA + Text.prettify(enchantment.getKey().getKey()))); } else { representative = ItemUtilities.enchanted(ItemUtilities.getItemStack(Material.BOOK, AQUA + Text.prettify(enchantment.getKey().getKey()), DARK_GRAY + "Level: " + GRAY + itemStack.getEnchantmentLevel(enchantment))); } } else { representative = ItemUtilities.getItemStack(Material.BOOK, AQUA + Text.prettify(enchantment.getKey().getKey())); } smartGUI.add( index, representative, (player, b, b2) -> { if (b) { this.removeEnchantment(slot, enchantment); } else { this.enchant(slot, enchantment); } }); } smartGUI.addImmutable(36, itemStack); smartGUI.add( 0, Material.ARROW, (player, b, b2) -> this.back(), RED + "Back"); smartGUI.add(38, Material.NAME_TAG, (player, b, b1) -> this.changeName(slot), GOLD + "Change Name"); smartGUI.add(39, Material.ANVIL, (player, b, b1) -> this.changeDurability(slot), YELLOW + "Change Durability"); smartGUI.add(40, Material.BEDROCK, (player, b, b1) -> this.toggleUnbreakable(slot), DARK_AQUA + "Toggle Unbreakable", itemStack.getItemMeta() != null && itemStack.getItemMeta().isUnbreakable() ? (GREEN + "ON") : (RED + "OFF")); smartGUI.add( 41, Material.PINK_DYE, (player, b, b2) -> this.maxEnchants(slot), LIGHT_PURPLE + "Max Enchants"); smartGUI.add( 42, Material.NETHERITE_SCRAP, (player, b, b2) -> this.removeEnchants(slot), YELLOW + "Clear Enchants"); this.owner.openGui(smartGUI); this.owner.playClickSound(); } private void removeEnchantment(int slot, Enchantment enchantment) { ItemStack itemStack = this.getItemStackOfSlot(slot); if (itemStack.containsEnchantment(enchantment)) { itemStack.removeEnchantment(enchantment); this.updateItem(slot, itemStack, false); this.enchantMenu(slot); } } private void toggleUnbreakable(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); if (itemStack.hasItemMeta() && itemStack.getItemMeta().isUnbreakable()) { this.updateItem(slot, ItemUtilities.edit(itemStack, itemMeta -> itemMeta.setUnbreakable(false)), false); } else { this.updateItem(slot, ItemUtilities.unbreakable(itemStack), false); } this.owner.playSuccessSound(); this.enchantMenu(slot); } protected void maxEnchants(int slot) { List<Enchantment> applicableEnchantments = getApplicableEnchantments(slot); ItemStack itemStack = this.getItemStackOfSlot(slot); for (Enchantment enchantment : Miscellaneous.getList(Enchantment.PROTECTION_ENVIRONMENTAL, Enchantment.PIERCING, Enchantment.LOYALTY, Enchantment.DAMAGE_ALL, Enchantment.DEPTH_STRIDER)) { if (applicableEnchantments.contains(enchantment)) { itemStack.addEnchantment(enchantment, enchantment.getMaxLevel()); } } for (Enchantment applicableEnchantment : applicableEnchantments) { boolean canEnchant = true; for (Enchantment enchantment : itemStack.getEnchantments().keySet()) { if (enchantment != applicableEnchantment && enchantment.conflictsWith(applicableEnchantment)) { canEnchant = false; break; } } if (canEnchant && applicableEnchantment.canEnchantItem(itemStack)) { itemStack.addEnchantment(applicableEnchantment, applicableEnchantment.getMaxLevel()); } } this.updateItem(slot, itemStack, false); this.owner.playSuccessSound(); this.enchantMenu(slot); } public void enchant(int slot, Enchantment enchantment) { ItemStack itemStack = this.getItemStackOfSlot(slot); SmartGUI smartGUI = new SmartGUI("Enchant", 1, false); int i = enchantment.getMaxLevel(); if (i == 1) { ItemStack changed = itemStack.clone(); ItemUtilities.edit(changed, itemMeta -> itemMeta.addEnchant(enchantment, 1, true)); this.updateItem(slot, changed, false); this.enchantMenu(slot); return; } for (int j = 0; j < i; j++) { int finalJ = j; smartGUI.add( j, ItemUtilities.edit(Material.ENCHANTED_BOOK, itemMeta -> itemMeta.addEnchant(enchantment, finalJ + 1, true)), (player, b, b2) -> { ItemStack changed = itemStack.clone(); ItemUtilities.edit(changed, itemMeta -> itemMeta.addEnchant(enchantment, finalJ + 1, true)); this.updateItem(slot, changed, false); this.enchantMenu(slot); }, ""); } /* int max = this.getMaxEnchantLevel(enchantment); this.getStringInput("Enchantment (1 - " + max + ")", "0", s -> { try { int i = Integer.parseInt(s); i = Math.max(1, Math.min(max, i)); ItemStack changed = itemStack.clone(); int finalI = i; ItemUtilities.edit(changed, itemMeta -> itemMeta.addEnchant(enchantment, finalI, true)); this.updateItem(slot, changed); } catch (Exception exception) { this.onInvalidInput(); } this.back(); });*/ smartGUI.add(8, Material.BARRIER, (player, b, b1) -> this.enchantMenu(slot), RED + "Back"); smartGUI.fillEmptySpots(); this.owner.openGui(smartGUI); this.owner.playClickSound(); } public int getMaxEnchantLevel(Enchantment enchantment) { if (this.owner.isAdministrator()) { return 32767; } if (this.owner.isStaff()) { return 31; } if (this.owner.isInGroupOrHigher(Group.YOUTUBE)) { return 10; } return enchantment.getMaxLevel(); } public void removeEnchants(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); ItemStack changed = ItemUtilities.edit(itemStack, itemMeta -> { for (Enchantment enchantment : itemMeta.getEnchants().keySet()) { itemMeta.removeEnchant(enchantment); } }); this.updateItem(slot, changed, false); this.enchantMenu(slot); return; /* SmartGUI smartGUI = new SmartGUI("Clear Enchants?", 5, false); if (itemStack.getItemMeta().getEnchants().isEmpty()) { this.owner.playErrorSound(); this.owner.sendErrorMessage("No enchantments to clear."); return; } smartGUI.add(13, itemStack, null); smartGUI.add(30, Material.EMERALD_BLOCK, (player, b, b2) -> { ItemStack changed = ItemUtilities.edit(itemStack, itemMeta -> { for (Enchantment enchantment : itemMeta.getEnchants().keySet()) { itemMeta.removeEnchant(enchantment); } }); this.updateItem(slot, changed, false); this.enchantMenu(slot); }, RED + "Confirm", YELLOW + "Remove all enchantments on item."); smartGUI.add(32, Material.BARRIER, (player, b, b2) -> this.enchantMenu(slot), YELLOW + "Cancel"); this.owner.openGui(smartGUI); this.owner.playClickSound(); */ } public void changeName(int slot) { ItemStack itemStack = this.getItemStackOfSlot(slot); this.getStringInput("Change Name", null, s -> { try { if (!s.isEmpty()) { if (this.owner.isInGroupOrHigher(Group.CHAMPION)) { s = ChatColor.translateAlternateColorCodes('&', s); s = SwearUtils.processMessageSwears(s, 4); } String finalS = s; ItemStack changed = ItemUtilities.edit(itemStack.clone(), itemMeta -> itemMeta.displayName(Component.text(WHITE + finalS))); this.updateItem(slot, changed, false); } } catch (Exception exception) { this.onInvalidInput(); } this.back(); }); } public void showItemSelect(int slot, List<Material> options) { int rowsize = 9; int totalRows = (int) (Math.ceil(options.size() / (double) rowsize)) + 1; SmartGUI smartGUI = new SmartGUI("Select", totalRows, false); //smartGUI.add((totalRows - 1) * 9 + 3, Material.BLUE_STAINED_GLASS_PANE, (player, b, b2) -> this.updateItem(slot, null), GRAY + "None"); smartGUI.add((totalRows - 1) * 9 + 4, Material.BARRIER, (player, b, b2) -> this.back(), RED + "Cancel"); for (int i = 0; i < options.size(); i++) { Material material = options.get(i); if (material != null) { smartGUI.add(i, material, ((player, b, b1) -> this.updateItem(slot, new ItemStack(material)))); } } /*if (options.size() % 2 == 0) { int startingIndex = 13 - options.size() / 2 + 1; for (int i = 0; i < options.size() - 1; i++) { Material material = options.get(i); smartGUI.add(startingIndex + i, material, (player, b, b2) -> this.updateItem(slot, new ItemStack(material))); } int i = options.size() - 1; Material material = options.get(i); smartGUI.add(22, material, (player, b, b2) -> this.updateItem(slot, new ItemStack(material))); } else { int startingIndex = 13 - options.size() / 2; for (int i = 0; i < options.size(); i++) { Material material = options.get(i); smartGUI.add(startingIndex + i, material, (player, b, b2) -> this.updateItem(slot, new ItemStack(material))); } }*/ this.owner.openGui(smartGUI); this.owner.playClickSound(); } public void showItemSelect(int slot, List<KitItem> options, ItemCategory itemCategory) { SmartGUI smartGUI = new SmartGUI("Select", 6, false); //smartGUI.add(47, Material.BLUE_STAINED_GLASS_PANE, (player, b, b2) -> this.updateItem(slot, null), GRAY + "None"); smartGUI.add(49, Material.BARRIER, (player, b, b2) -> this.showCategorySelect(slot), RED + "Cancel"); /* int rowLength = switch (itemCategory) { case RANGED, ARMOR, WEAPONS, OTHER -> 6; case BLOCKS -> 7; case POTION -> 3; case FOOD -> 8; }; for (int i = 0; i < options.size(); i++) { int index = this.calculatePosition(rowLength, i, options.size()); KitItem kitItem = options.get(i); if (index >= 0 && index < 54) { smartGUI.add(index, kitItem.itemStack, (player, b, b2) -> this.updateItem(slot, kitItem.itemStack)); } else { Main.warn("Invalid index! (i = %d, index = %d)!", i, index); } } */ for (int index = 0; index < options.size(); index++) { KitItem kitItem = options.get(index); Material material = kitItem.itemStack.getType(); if (kitItem.itemStack.getType() != Material.AIR) { if (index < 54) { boolean maxStackSize = material != Material.COMPASS && slot != REPRESENTATIVE; smartGUI.add(index, kitItem.itemStack, (player, b, b2) -> this.updateItem(slot, kitItem.itemStack.asQuantity(maxStackSize ? material.getMaxStackSize() : 1))); } else { Main.warn("Invalid index! (i = %d, index = %d)!", index, index); } } } this.owner.openGui(smartGUI); this.owner.playClickSound(); } public int calculatePosition(int rowLength, int index, int totalSize) { int rowNumber = index / rowLength; int positionInRow = index % rowLength; int rows = (int) Math.ceil((double) totalSize / (double) rowLength); int halfOfRowLength = rowLength / 2; int middleStart = 22 - (9 * (rows / 2)) + (9 * rowNumber); if (rowLength % 2 == 0) { int startPos = middleStart - halfOfRowLength; if ((positionInRow + 1) > halfOfRowLength && rowLength < 9) { return startPos + positionInRow + 1; } return startPos + positionInRow; } int startPos = middleStart - halfOfRowLength; return startPos + positionInRow; } public void updateItem(int slot, ItemStack itemStack) { this.updateItem(slot, itemStack, true); } public void updateItem(int slot, ItemStack itemStack, boolean back) { if (slot == REPRESENTATIVE) { if (itemStack == null) { itemStack = new ItemStack(Material.RED_BANNER); } itemStack.setAmount(1); this.representative = itemStack; if (back) { this.back(); } else { this.fill(); } this.owner.playSuccessSound(); return; } if (slot < 18) { switch (this.getTypeOfIndex(slot)) { case HELMET: this.helmet = itemStack; break; case CHESTPLATE: this.chestplate = itemStack; break; case LEGGINGS: this.leggings = itemStack; break; case BOOTS: this.boots = itemStack; break; case OFF_HAND: this.offHand = itemStack; break; default: this.representative = itemStack; break; } } else { if (slot < 45) { int index; if (slot < 27) { index = slot % 9 + 18; } else if (slot < 36) { index = slot % 9 + 9; } else { index = slot % 9; } this.inventory[index] = itemStack; } else { this.hotbar[slot % 9] = itemStack; } } if (back) { this.back(); } else { this.fill(); this.owner.playSuccessSound(); } } public void showCategorySelect(int slot) { SmartGUI smartGUI = new SmartGUI("Categories", 5, false); List<ItemCategory> itemCategories = Miscellaneous.getList(ItemCategory.values()); //smartGUI.add(30, Material.BLUE_STAINED_GLASS_PANE, (player, b, b2) -> this.updateItem(slot, null), GRAY + "None"); smartGUI.add(31, Material.BARRIER, (player, b, b2) -> this.back(), RED + "Cancel"); if (itemCategories.size() % 2 == 0) { int startingIndex = 13 - itemCategories.size() / 2 + 1; for (int i = 0; i < itemCategories.size() - 1; i++) { ItemCategory itemCategory = itemCategories.get(i); smartGUI.add(startingIndex + i, itemCategory.representative, (player, b, b2) -> this.showItemCategorySelect(itemCategory, slot), AQUA + itemCategory.name); } int i = itemCategories.size() - 1; ItemCategory itemCategory = itemCategories.get(i); smartGUI.add(22, itemCategory.representative, (player, b, b2) -> this.showItemCategorySelect(itemCategory, slot), AQUA + itemCategory.name); } else { int startingIndex = 13 - itemCategories.size() / 2; for (int i = 0; i < itemCategories.size(); i++) { ItemCategory itemCategory = itemCategories.get(i); smartGUI.add(startingIndex + i, itemCategory.representative, (player, b, b2) -> this.showItemCategorySelect(itemCategory, slot), AQUA + itemCategory.name); } } this.owner.openGui(smartGUI); this.owner.playClickSound(); } public void showItemCategorySelect(ItemCategory itemCategory, int slot) { if (itemCategory == ItemCategory.POTION) { this.showPotionSelect(slot); } else { List<KitItem> options = this.getKitItemsForCategory(itemCategory); this.showItemSelect(slot, options, itemCategory); } } public static List<KitItem> getKitItemsForCategory(ItemCategory itemCategory) { switch (itemCategory) { case WEAPONS: return turnIntoKitItems(Material.WOODEN_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLDEN_SWORD, Material.DIAMOND_SWORD, Material.NETHERITE_SWORD, Material.TRIDENT, Material.TOTEM_OF_UNDYING, Material.ENDER_PEARL, Material.WOODEN_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLDEN_AXE, Material.DIAMOND_AXE, Material.NETHERITE_AXE, Material.OBSIDIAN, Material.END_CRYSTAL, Material.WATER_BUCKET, Material.WOODEN_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLDEN_PICKAXE, Material.DIAMOND_PICKAXE, Material.NETHERITE_PICKAXE, Material.RESPAWN_ANCHOR, Material.GLOWSTONE, Material.LAVA_BUCKET, Material.WOODEN_SHOVEL, Material.STONE_SHOVEL, Material.IRON_SHOVEL, Material.GOLDEN_SHOVEL, Material.DIAMOND_SHOVEL, Material.NETHERITE_SHOVEL, Material.RAIL, Material.TNT_MINECART, Material.FLINT_AND_STEEL, Material.WOODEN_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLDEN_HOE, Material.DIAMOND_HOE, Material.NETHERITE_HOE, Material.BOW, Material.CROSSBOW, Material.FISHING_ROD); case ARMOR: return turnIntoKitItems(Material.LEATHER_HELMET, Material.CHAINMAIL_HELMET, Material.GOLDEN_HELMET, Material.IRON_HELMET, Material.DIAMOND_HELMET, Material.NETHERITE_HELMET, Material.TURTLE_HELMET, Material.TOTEM_OF_UNDYING, Material.AIR, Material.LEATHER_CHESTPLATE, Material.CHAINMAIL_CHESTPLATE, Material.GOLDEN_CHESTPLATE, Material.IRON_CHESTPLATE, Material.DIAMOND_CHESTPLATE, Material.NETHERITE_CHESTPLATE, Material.ELYTRA, Material.AIR, Material.AIR, Material.LEATHER_LEGGINGS, Material.CHAINMAIL_LEGGINGS, Material.GOLDEN_LEGGINGS, Material.IRON_LEGGINGS, Material.DIAMOND_LEGGINGS, Material.NETHERITE_LEGGINGS, Material.SHIELD, Material.AIR, Material.AIR, Material.LEATHER_BOOTS, Material.CHAINMAIL_BOOTS, Material.GOLDEN_BOOTS, Material.IRON_BOOTS, Material.DIAMOND_BOOTS, Material.NETHERITE_BOOTS, Material.CARVED_PUMPKIN); case RANGED: List<KitItem> items = Miscellaneous.getList(turnIntoKitItems(Material.BOW, Material.CROSSBOW, Material.ARROW)); for (PotionType value : Miscellaneous.without(Miscellaneous.getList(PotionType.values()), PotionType.UNCRAFTABLE, PotionType.WATER, PotionType.MUNDANE, PotionType.THICK, PotionType.AWKWARD, PotionType.NIGHT_VISION, PotionType.JUMP, PotionType.INSTANT_HEAL, PotionType.LUCK)) { KitItem.ArrowKitItem arrowKitItem = new KitItem.ArrowKitItem(value, false, false, 1, -1); items.add(arrowKitItem); if (value.isUpgradeable()) { KitItem.ArrowKitItem upgraded = new KitItem.ArrowKitItem(value, false, true, 1, -1); items.add(upgraded); } if (value.isExtendable()) { KitItem.ArrowKitItem extended = new KitItem.ArrowKitItem(value, true, false, 1, -1); items.add(extended); } } items.add(new KitItem(Material.SPECTRAL_ARROW)); items.add(new KitItem(Material.FIREWORK_ROCKET)); return items; case BLOCKS: return turnIntoKitItems(Material.OBSIDIAN, Material.OAK_LOG, Material.OAK_PLANKS, Material.DIRT, Material.COBBLESTONE, Material.DEEPSLATE, Material.END_STONE, Material.NETHERRACK, Material.GRAVEL, Material.SAND, Material.HAY_BLOCK, Material.MAGMA_BLOCK, Material.ICE, Material.SOUL_SAND, Material.SOUL_SOIL, Material.GRASS_BLOCK, Material.STONE, Material.WHITE_WOOL, Material.GLASS, Material.SCAFFOLDING, Material.TNT, Material.SLIME_BLOCK, Material.PUMPKIN, Material.MELON, Material.BONE_BLOCK, Material.SPONGE, Material.WET_SPONGE, Material.OAK_DOOR, Material.IRON_DOOR, Material.OAK_TRAPDOOR, Material.IRON_TRAPDOOR, Material.POINTED_DRIPSTONE, Material.HONEY_BLOCK, Material.HONEYCOMB_BLOCK, Material.NOTE_BLOCK, Material.JUKEBOX, Material.COAL_BLOCK, Material.IRON_BLOCK, Material.GOLD_BLOCK, Material.REDSTONE_BLOCK, Material.EMERALD_BLOCK, Material.LAPIS_BLOCK, Material.DIAMOND_BLOCK, Material.NETHERITE_BLOCK, Material.CRYING_OBSIDIAN); case FOOD: return turnIntoKitItems(Material.APPLE, Material.GOLDEN_APPLE, Material.ENCHANTED_GOLDEN_APPLE, Material.MELON, Material.SWEET_BERRIES, Material.GLOW_BERRIES, Material.CHORUS_FRUIT, Material.CARROT, Material.GOLDEN_CARROT, Material.POTATO, Material.BAKED_POTATO, Material.POISONOUS_POTATO, Material.BEETROOT, Material.DRIED_KELP, Material.BEEF, Material.COOKED_BEEF, Material.PORKCHOP, Material.COOKED_PORKCHOP, Material.MUTTON, Material.COOKED_MUTTON, Material.CHICKEN, Material.COOKED_CHICKEN, Material.RABBIT, Material.COOKED_RABBIT, Material.COD, Material.COOKED_COD, Material.SALMON, Material.COOKED_SALMON, Material.TROPICAL_FISH, Material.PUFFERFISH_BUCKET, Material.BREAD, Material.COOKIE, Material.CAKE, Material.PUMPKIN_PIE, Material.ROTTEN_FLESH, Material.SPIDER_EYE, Material.MUSHROOM_STEW, Material.BOWL, Material.RABBIT_STEW, Material.SUSPICIOUS_STEW, Material.HONEY_BOTTLE); case OTHER: items = new ArrayList<>(); items.add(new KitItem(ItemUtilities.getItemStack(Material.COMPASS, RED + "Tracker"))); items.addAll(turnIntoKitItems(Material.SHEARS, Material.EXPERIENCE_BOTTLE, Material.SNOWBALL, Material.RED_BED, Material.OAK_BOAT, Material.LEAD, Material.TOTEM_OF_UNDYING, Material.END_CRYSTAL, Material.BUCKET, Material.WATER_BUCKET, Material.LAVA_BUCKET, Material.MILK_BUCKET, Material.PUFFERFISH_BUCKET, Material.AXOLOTL_BUCKET, Material.POWDER_SNOW_BUCKET, Material.EGG, Material.FIREWORK_ROCKET, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.MINECART, Material.TNT_MINECART, Material.TNT, Material.COMPARATOR, Material.REPEATER, Material.REDSTONE, Material.REDSTONE_TORCH, Material.STONE_BUTTON, Material.LEVER, Material.STONE_PRESSURE_PLATE, Material.DROPPER, Material.DISPENSER, Material.TRIPWIRE_HOOK, Material.STRING, Material.HORSE_SPAWN_EGG, Material.MULE_SPAWN_EGG, Material.DONKEY_SPAWN_EGG, Material.PIG_SPAWN_EGG, Material.LEATHER_HORSE_ARMOR, Material.IRON_HORSE_ARMOR, Material.GOLDEN_HORSE_ARMOR, Material.DIAMOND_HORSE_ARMOR, Material.CARROT_ON_A_STICK)); return items; } return new ArrayList<>(); } public void showPotionSelect(int slot) { List<KitItem.PotionKitItem> options = new ArrayList<>(); for (PotionEffectType value : PotionEffectType.values()) { if (PotionType.getByEffect(value) != null) { options.add(new KitItem.PotionKitItem(value, Material.POTION, false, false, -1)); } } SmartGUI smartGUI = new SmartGUI("Select", 6, false); smartGUI.add(40, Material.BARRIER, (player, b, b2) -> this.showCategorySelect(slot), RED + "Cancel"); int rowLength = 7; for (int i = 0; i < options.size(); i++) { // i = 7 int row = i / rowLength; // 1 int positionInRow = i % rowLength; // 0 int remainingAfterLength = options.size() % rowLength; // 1 int reduce = (i + 1) < (9 * options.size() / rowLength) ? rowLength / 2 : ((remainingAfterLength == 0 ? rowLength : remainingAfterLength) / 2); // 15 - 7 > 7 + 1 ? 7 / 2 : ((1 == 1 ? 7 : remainingAfterLength) / 2) int startingPositionInRow = 13 + (9 * row) - reduce; int index = startingPositionInRow + positionInRow; KitItem.PotionKitItem potionKitItem = options.get(i); if (index < 54) { PotionMeta potionMeta = (PotionMeta) potionKitItem.itemStack.getItemMeta(); if (potionMeta.getCustomEffects().isEmpty()) { smartGUI.add(index, potionKitItem.itemStack, (player, b, b2) -> this.showPotionSelect(slot, ((PotionMeta) potionKitItem.itemStack.getItemMeta()).getBasePotionData().getType().getEffectType())); } else { smartGUI.add(index, potionKitItem.itemStack, (player, b, b2) -> this.showPotionSelect(slot, ((PotionMeta) potionKitItem.itemStack.getItemMeta()).getCustomEffects().get(0).getType())); } } else { Main.warn("Invalid index! (i = %d; index = %d)", i, index); } } this.owner.openGui(smartGUI); this.owner.playClickSound(); } public void showPotionSelect(int slot, PotionEffectType type) { List<KitItem> options = new ArrayList<>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { boolean extended = j == 1; boolean upgraded = k == 1; Material material = switch (i) { case 0 -> Material.POTION; case 1 -> Material.SPLASH_POTION; default -> Material.LINGERING_POTION; }; PotionType potionType = PotionType.getByEffect(type); if (potionType != null) { if (!((!potionType.isExtendable() && extended) || (!potionType.isUpgradeable() && upgraded) || (upgraded && extended))) { options.add(new KitItem.PotionKitItem(type, material, extended, upgraded, -1)); } } else { Main.error("Potion Type is null for %s", type); } } } } this.showItemSelect(slot, options, ItemCategory.POTION); } public static List<KitItem> turnIntoKitItems(Material... materials) { return Miscellaneous.processList(Miscellaneous.getList(materials), KitItem::new); } public boolean hasItemAtSlot(int index) { ItemStack itemStack = this.getItemStackOfSlot(index); return itemStack != null && !Text.toComparable(itemStack.getType()).contains("pane"); } public ItemStack getItemStackOfSlot(int index) { return this.gui.getItem(index); } public void back() { this.fill(); this.owner.openGui(this); this.owner.playClickSound(); } public SlotType getTypeOfIndex(int index) { switch (index) { case HELMET: return SlotType.HELMET; case CHESTPLATE: return SlotType.CHESTPLATE; case LEGGINGS: return SlotType.LEGGINGS; case BOOTS: return SlotType.BOOTS; case OFF_HAND: return SlotType.OFF_HAND; case REPRESENTATIVE: return SlotType.ANY; } return SlotType.ANY; } public void showLabelMenu() { SmartGUI smartGUI = new SmartGUI("Label", 1, false); smartGUI.add(2, Material.NAME_TAG, (player, b, b2) -> this.editName(), AQUA + "Change Name", GRAY + this.name); smartGUI.add(4, Material.BARRIER, (player, b, b1) -> this.back(), RED + "Back"); smartGUI.add(6, this.representative.clone(), (player, b, b2) -> this.editSlot(REPRESENTATIVE, b, b2), RED + "Kit Icon"); smartGUI.fillEmptySpots(); this.owner.openGui(smartGUI); this.owner.playClickSound(); } public void editName() { this.getStringInput("Kit Name", this.name, s -> { boolean isAcceptable = !s.isEmpty() && SwearUtils.canSendMessageAtLevel(s, ChatFilter.HIGH); if (this.owner.isInGroupOrHigher(Group.CHAMPION)) { s = ChatColor.translateAlternateColorCodes('&', s); } if (isAcceptable) { this.name = s; this.owner.playSuccessSound(); } else { this.onInvalidInput(); } this.back(); }); } public void onInvalidInput() { this.owner.playErrorSound(); this.owner.sendErrorMessage("Invalid input!"); } public void save() { if (this.deleted || this.shared) { return; } if (this.name.equals(DEFAULT_NAME)) { this.editName(); return; } if (this.hotbar[0] != null && (this.representative == null || this.representative.getType() == Material.RED_BANNER)) { this.representative = this.hotbar[0].clone(); this.representative.setAmount(1); } CustomDuelsKit kit = this.getAsKit(); this.owner.saveCustomKit(kit, originalId); } public CustomDuelsKit getAsKit() { List<KitItem> items = new ArrayList<>(); for (int i = 0; i < this.hotbar.length; i++) { ItemStack itemStack = this.hotbar[i]; if (itemStack != null) { items.add(new KitItem(itemStack, i)); } } for (int i = 0; i < this.inventory.length; i++) { ItemStack itemStack = this.inventory[i]; if (itemStack != null) { items.add(new KitItem(itemStack, i + 9)); } } if (this.offHand != null) { items.add(new KitItem(this.offHand, 40)); } KitItem helmet = this.helmet == null ? null : new KitItem(this.helmet); KitItem chestplate = this.chestplate == null ? null : new KitItem(this.chestplate); KitItem leggings = this.leggings == null ? null : new KitItem(this.leggings); KitItem boots = this.boots == null ? null : new KitItem(this.boots); if (this.representative == null) { this.representative = new ItemStack(Material.RED_BANNER); } return new CustomDuelsKit( this.id, this.owner.getUUID(), new Kit(this.name, "Custom Kit.", false, new KitItem(this.representative), helmet, chestplate, leggings, boots, items, false), this.gameSettings.toJson(), this.getMaps(), this.publicCustomMap, shared, 0, this.creators, 0); } protected List<String> getMaps() { if (this.map == null) { if (this.customMap != null) { return Miscellaneous.getList(customMap); } return Miscellaneous.getList(DuelMap.ARENA.getCodeName()); } return Miscellaneous.getList(this.map.getCodeName()); } public void reset() { this.setFromOriginal(); this.back(); } public void cancel() { this.owner.openDuelsCustomKitsListGui(1); } public void delete() { SmartGUI smartGUI = new SmartGUI("Delete?", 3, false); smartGUI.add(12, Material.EMERALD_BLOCK, (player, b, b2) -> { this.owner.deleteKit(this.originalId, this.id); this.deleted = true; }, RED + "Confirm", YELLOW + "Permanently delete this custom kit."); smartGUI.add(14, Material.BARRIER, (player, b, b2) -> this.back(), YELLOW + "Cancel"); this.owner.openGui(smartGUI); this.owner.playClickSound(); } public boolean hasOriginal() { return this.originalKit != null; } public void getStringInput(String title, String originalText, Consumer<String> process) { new TextGUI(this.owner.getPlayer(), title, originalText) { @Override public void process(ItemStack itemStack) { process.accept(itemStack.getItemMeta().getDisplayName()); } @Override public void onClose() { EditCustomKitGUI.this.back(); } }.openInventory(); } @Override public void onClose() { this.save(); } enum SlotType { HELMET, CHESTPLATE, LEGGINGS, BOOTS, OFF_HAND, ANY } enum ItemCategory { WEAPONS("Weapons & Tools", Material.IRON_SWORD), ARMOR("Armor", Material.DIAMOND_CHESTPLATE), RANGED("Ranged", Material.CROSSBOW), BLOCKS("Blocks", Material.OAK_PLANKS), FOOD("Foodstuffs", Material.GOLDEN_CARROT), POTION("Potions", Material.GLASS_BOTTLE), OTHER("Other", Material.DIAMOND_HORSE_ARMOR), ; final String name; final Material representative; ItemCategory(String name, Material representative) { this.name = name; this.representative = representative; } } }