package world.bentobox.challenges.panel.util; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import java.util.*; import java.util.function.BiConsumer; import java.util.stream.Collectors; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; import world.bentobox.challenges.utils.Constants; import world.bentobox.challenges.utils.GuiUtils; import world.bentobox.challenges.utils.Utils; /** * This class contains all necessary things that allows to select single block from all ingame blocks. Selected * block will be returned via BiConsumer. */ public class SingleBlockSelector extends PagedSelector { private SingleBlockSelector(User user, Mode mode, Set excluded, BiConsumer consumer) { super(user); this.consumer = consumer; // Current GUI cannot display air blocks. It crashes with null-pointer excluded.add(Material.AIR); excluded.add(Material.CAVE_AIR); excluded.add(Material.VOID_AIR); // Piston head and moving piston is not necessary. useless. excluded.add(Material.PISTON_HEAD); excluded.add(Material.MOVING_PISTON); // Barrier cannot be accessible to user. excluded.add(Material.BARRIER); this.elements = Arrays.stream(Material.values()). filter(material -> !excluded.contains(material)). filter(material -> { switch (mode) { case BLOCKS -> { return material.isBlock(); } case ITEMS -> { return material.isItem(); } default -> { return true; } } }). collect(Collectors.toList()); } /** * This method opens GUI that allows to select challenge type. * * @param user User who opens GUI. * @param consumer Consumer that allows to get clicked type. */ public static void open(User user, Mode mode, Set excluded, BiConsumer consumer) { new SingleBlockSelector(user, mode, excluded, consumer).build(); } /** * This method opens GUI that allows to select challenge type. * * @param user User who opens GUI. * @param consumer Consumer that allows to get clicked type. */ public static void open(User user, BiConsumer consumer) { new SingleBlockSelector(user, Mode.ANY, new HashSet<>(), consumer).build(); } /** * This method opens GUI that allows to select challenge type. * * @param user User who opens GUI. * @param consumer Consumer that allows to get clicked type. */ public static void open(User user, Mode mode, BiConsumer consumer) { new SingleBlockSelector(user, mode, new HashSet<>(), consumer).build(); } // --------------------------------------------------------------------- // Section: Methods // --------------------------------------------------------------------- /** * This method builds all necessary elements in GUI panel. */ protected void build() { PanelBuilder panelBuilder = new PanelBuilder().user(this.user); panelBuilder.name(this.user.getTranslation(Constants.TITLE + "block-selector")); GuiUtils.fillBorder(panelBuilder, Material.BLUE_STAINED_GLASS_PANE); this.populateElements(panelBuilder, this.elements); panelBuilder.item(4, this.createButton()); panelBuilder.build(); } /** * This method creates PanelItem button of requested type. * @return new PanelItem with requested functionality. */ private PanelItem createButton() { final String reference = Constants.BUTTON + "cancel."; final String name = this.user.getTranslation(reference + "name"); final List description = new ArrayList<>(3); description.add(this.user.getTranslation(reference + "description")); ItemStack icon = new ItemStack(Material.IRON_DOOR); PanelItem.ClickHandler clickHandler = (panel, user1, clickType, slot) -> { this.consumer.accept(false, null); return true; }; description.add(""); description.add(this.user.getTranslation(Constants.TIPS + "click-to-cancel")); return new PanelItemBuilder(). icon(icon). name(name). description(description). clickHandler(clickHandler). build(); } /** * This method creates button for given material. * @param material material which button must be created. * @return new Button for material. */ @Override protected PanelItem createElementButton(Material material) { final String reference = Constants.BUTTON + "material."; List description = new ArrayList<>(); description.add(this.user.getTranslation(reference + "description", "[id]", material.name())); description.add(""); description.add(this.user.getTranslation(Constants.TIPS + "click-to-choose")); return new PanelItemBuilder(). name(this.user.getTranslation(reference + "name", "[material]", Utils.prettifyObject(material, this.user))). icon(GuiUtils.getMaterialItem(material)). description(description). clickHandler((panel, user1, clickType, slot) -> { this.consumer.accept(true, material); return true; }). build(); } // --------------------------------------------------------------------- // Section: Mode // --------------------------------------------------------------------- public enum Mode { BLOCKS, ITEMS, ANY } // --------------------------------------------------------------------- // Section: Variables // --------------------------------------------------------------------- /** * List with elements that will be displayed in current GUI. */ private final List elements; /** * This variable stores consumer. */ private final BiConsumer consumer; }