From 58253eb7d79fb76c1e9f4f076a3bfa289694eb25 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 12 Feb 2019 22:58:33 -0800 Subject: [PATCH] Implements gamemode-specific flags API (#541) * Implements gamemode flags API https://github.com/BentoBoxWorld/BentoBox/issues/406 * New and improved --- .../bentobox/bentobox/api/flags/Flag.java | 99 ++++++++++++++++++- .../bentobox/panels/SettingsPanel.java | 3 +- .../bentobox/bentobox/api/flags/FlagTest.java | 44 ++++----- 3 files changed, 121 insertions(+), 25 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java index 66f794b6b..7b7f2b0ea 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -1,16 +1,19 @@ package world.bentobox.bentobox.api.flags; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Optional; +import java.util.Set; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; - import org.eclipse.jdt.annotation.NonNull; + import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick; import world.bentobox.bentobox.api.flags.clicklisteners.IslandToggleClick; @@ -71,11 +74,12 @@ public class Flag implements Comparable { private final int defaultRank; private final PanelItem.ClickHandler clickHandler; private final boolean subPanel; + private Set gameModes = new HashSet<>(); /** * {@link Flag.Builder} should be used instead. This is only used for testing. */ - Flag(String id, Material icon, Listener listener, Type type, int defaultRank, PanelItem.ClickHandler clickListener, boolean subPanel) { + Flag(String id, Material icon, Listener listener, Type type, int defaultRank, PanelItem.ClickHandler clickListener, boolean subPanel, GameModeAddon gameModeAddon) { this.id = id; this.icon = icon; this.listener = listener; @@ -83,6 +87,9 @@ public class Flag implements Comparable { this.defaultRank = defaultRank; this.clickHandler = clickListener; this.subPanel = subPanel; + if (gameModeAddon != null) { + this.gameModes.add(gameModeAddon); + } } private Flag(Builder builder) { @@ -94,6 +101,9 @@ public class Flag implements Comparable { this.defaultRank = builder.defaultRank; this.clickHandler = builder.clickHandler; this.subPanel = builder.usePanel; + if (builder.gameModeAddon != null) { + this.gameModes.add(builder.gameModeAddon); + } } public String getID() { @@ -226,6 +236,37 @@ public class Flag implements Comparable { return PROTECTION_FLAGS + this.id + ".hint"; } + /** + * @return the gameModeAddon + */ + public Set getGameModes() { + return gameModes; + } + + /** + * @param gameModeAddon the gameModeAddon to set + */ + public void setGameModes(Set gameModeAddon) { + this.gameModes = gameModeAddon; + } + + /** + * Add a gameModeAddon to this flag + * @param gameModeAddon - game mode addon + */ + public void addGameModeAddon(GameModeAddon gameModeAddon) { + this.gameModes.add(gameModeAddon); + } + + /** + * Remove a gameModeAddon to this flag + * @param gameModeAddon - game mode addon + * @return true if this set contained the specified element + */ + public boolean removeGameModeAddon(GameModeAddon gameModeAddon) { + return this.gameModes.remove(gameModeAddon); + } + /** * Converts a flag to a panel item. The content of the flag will change depending on who the user is and where they are. * @param plugin - plugin @@ -298,6 +339,7 @@ public class Flag implements Comparable { } /** + * Builder for making flags * @author tastybento, Poslovitch */ public static class Builder { @@ -321,41 +363,94 @@ public class Flag implements Comparable { // Whether there is a sub-panel or not private boolean usePanel = false; + // GameModeAddon + private GameModeAddon gameModeAddon; + + /** + * Builder for making flags + * @param id - a unique id that MUST be the same as the enum of the flag + * @param icon - a material that will be used as the icon in the GUI + */ public Builder(String id, Material icon) { this.id = id; this.icon = icon; } + /** + * The listener that should be instantiated to handle events this flag cares about. + * If the listener class already exists, then do not create it again in another flag. + * @param listener - Bukkit Listener + * @return Builder + */ public Builder listener(Listener listener) { this.listener = listener; return this; } + /** + * The type of flag. + * @param type {@link Type#PROTECTION}, {@link Type#SETTING} or {@link Type#WORLD_SETTING} + * @return Builder + */ public Builder type(Type type) { this.type = type; return this; } + /** + * The click handler to use when this icon is clicked + * @param clickHandler - click handler + * @return Builder + */ public Builder clickHandler(PanelItem.ClickHandler clickHandler) { this.clickHandler = clickHandler; return this; } + /** + * Set the default setting for {@link Type#SETTING} or {@link Type#WORLD_SETTING} flags + * @param defaultSetting - true or false + * @return Builder + */ public Builder defaultSetting(boolean defaultSetting) { this.defaultSetting = defaultSetting; return this; } + /** + * Set the default rank for {@link Type#PROTECTION} flags + * @param defaultRank - default rank + * @return Builder + */ public Builder defaultRank(int defaultRank) { this.defaultRank = defaultRank; return this; } + /** + * Set that this flag icon will open up a sub-panel + * @param usePanel - true or false + * @return Builder + */ public Builder usePanel(boolean usePanel) { this.usePanel = usePanel; return this; } + /** + * Make this flag specific to this gameMode + * @param gameModeAddon + * @return + */ + public Builder setGameMode(GameModeAddon gameModeAddon) { + this.gameModeAddon = gameModeAddon; + return this; + } + + /** + * Build the flag + * @return Flag + */ public Flag build() { // If no clickHandler has been set, then apply default ones if (clickHandler == null) { diff --git a/src/main/java/world/bentobox/bentobox/panels/SettingsPanel.java b/src/main/java/world/bentobox/bentobox/panels/SettingsPanel.java index 504cc7d37..c03b658b6 100644 --- a/src/main/java/world/bentobox/bentobox/panels/SettingsPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/SettingsPanel.java @@ -44,7 +44,8 @@ public class SettingsPanel { List flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(flagType)) .sorted(Comparator.comparing(flag -> user.getTranslation(flag.getNameReference()))) .collect(Collectors.toList()); - + // Remove any that are not for this game mode + plugin.getIWM().getAddon(world).ifPresent(gm -> flags.removeIf(f -> !f.getGameModes().isEmpty() && !f.getGameModes().contains(gm))); // Use paging flags.stream().skip(page * 43L).limit(page * 43L + 43L).forEach((f -> panelBuilder.item(f.toPanelItem(plugin, user)))); // Add forward and backward icons diff --git a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java index 90fd4a1c6..2f8d90a6f 100644 --- a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java +++ b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java @@ -78,44 +78,44 @@ public class FlagTest { @Test public void testHashCode() { - Flag flag1 = new Flag(null, null, null, null, 0, null, false); - Flag flag2 = new Flag(null, null, null, null, 0, null, false); + Flag flag1 = new Flag(null, null, null, null, 0, null, false, null); + Flag flag2 = new Flag(null, null, null, null, 0, null, false, null); assertTrue(flag1.hashCode() == flag2.hashCode()); } @Test public void testFlag() { - assertNotNull(new Flag(null, null, null, null, 0, null, false)); + assertNotNull(new Flag(null, null, null, null, 0, null, false, null)); } @Test public void testGetID() { - Flag id = new Flag("id", null, null, null, 0, null, false); + Flag id = new Flag("id", null, null, null, 0, null, false, null); assertEquals("id", id.getID()); } @Test public void testGetIcon() { - Flag id = new Flag("id", Material.ACACIA_DOOR, null, null, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, null, 0, null, false, null); assertEquals(Material.ACACIA_DOOR, id.getIcon()); } @Test public void testGetListener() { Listener l = mock(Listener.class); - Flag id = new Flag("id", Material.ACACIA_DOOR, l, null, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, l, null, 0, null, false, null); Optional ol = Optional.ofNullable(l); assertEquals(ol, id.getListener()); - id = new Flag("id", Material.ACACIA_DOOR, null, null, 0, null, false); + id = new Flag("id", Material.ACACIA_DOOR, null, null, 0, null, false, null); assertEquals(Optional.empty(), id.getListener()); } @Test public void testIsDefaultSetting() { Type type = Type.SETTING; - Flag id = new Flag("id", Material.ACACIA_DOOR, null, type , 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, type , 0, null, false, null); assertFalse(id.isSetForWorld(mock(World.class))); - id = new Flag("id", Material.ACACIA_DOOR, null, type, 0, null, false); + id = new Flag("id", Material.ACACIA_DOOR, null, type, 0, null, false, null); id.setDefaultSetting(true); assertTrue(id.isSetForWorld(mock(World.class))); } @@ -123,7 +123,7 @@ public class FlagTest { @Test public void testSetDefaultSetting() { Type type = Type.SETTING; - Flag id = new Flag("id", Material.ACACIA_DOOR, null, type, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, type, 0, null, false, null); assertFalse(id.isSetForWorld(mock(World.class))); id.setDefaultSetting(true); assertTrue(id.isSetForWorld(mock(World.class))); @@ -135,25 +135,25 @@ public class FlagTest { @Test public void testIsDefaultSetting_World_Setting() { Type type = Type.WORLD_SETTING; - Flag id = new Flag("id", Material.ACACIA_DOOR, null, type , 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, type , 0, null, false, null); assertFalse(id.isSetForWorld(mock(World.class))); // Default can only be set once with world settings, so use a new id for flag - id = new Flag("id2", Material.ACACIA_DOOR, null, type, 0, null, false); + id = new Flag("id2", Material.ACACIA_DOOR, null, type, 0, null, false, null); id.setDefaultSetting(true); assertTrue(id.isSetForWorld(mock(World.class))); } @Test public void testGetType() { - Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); assertEquals(Flag.Type.PROTECTION,id.getType()); - id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.SETTING, 0, null, false); + id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.SETTING, 0, null, false, null); assertEquals(Flag.Type.SETTING,id.getType()); } @Test public void testGetDefaultRank() { - Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 100, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 100, null, false, null); assertEquals(100, id.getDefaultRank()); } @@ -161,18 +161,18 @@ public class FlagTest { @Test public void testEqualsObject() { Flag flag1 = null; - Flag flag2 = new Flag(null, null, null, null, 0, null, false); + Flag flag2 = new Flag(null, null, null, null, 0, null, false, null); assertFalse(flag2.equals(null)); int i = 45; assertFalse(flag2.equals(i)); - flag1 = new Flag(null, null, null, null, 0, null, false); + flag1 = new Flag(null, null, null, null, 0, null, false, null); flag2 = flag1; assertTrue(flag1.equals(flag2)); assertTrue(flag2.equals(flag1)); - flag2 = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); + flag2 = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); assertFalse(flag1.equals(flag2)); assertFalse(flag2.equals(flag1)); @@ -209,7 +209,7 @@ public class FlagTest { when(rm.getRank(Mockito.eq(RanksManager.VISITOR_RANK))).thenReturn("Visitor"); when(rm.getRank(Mockito.eq(RanksManager.OWNER_RANK))).thenReturn("Owner"); - Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); PanelItem pi = id.toPanelItem(plugin, user); @@ -222,14 +222,14 @@ public class FlagTest { @Test public void testToString() { - Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); + Flag id = new Flag("id", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); assertEquals("Flag [id=id, icon=ACACIA_DOOR, listener=null, type=PROTECTION, defaultSetting=false, defaultRank=0, clickHandler=null, subPanel=false]", id.toString()); } @Test public void testCompareTo() { - Flag aaa = new Flag("AAA", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); - Flag bbb = new Flag("BBB", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false); + Flag aaa = new Flag("AAA", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); + Flag bbb = new Flag("BBB", Material.ACACIA_DOOR, null, Flag.Type.PROTECTION, 0, null, false, null); assertTrue(aaa.compareTo(bbb) < bbb.compareTo(aaa)); assertTrue(aaa.compareTo(aaa) == 0); }