Implements gamemode-specific flags API (#541)

* Implements gamemode flags API

https://github.com/BentoBoxWorld/BentoBox/issues/406

* New and improved
This commit is contained in:
tastybento 2019-02-12 22:58:33 -08:00 committed by Florian CUNY
parent f89419f3d8
commit 58253eb7d7
3 changed files with 121 additions and 25 deletions

View File

@ -1,16 +1,19 @@
package world.bentobox.bentobox.api.flags; package world.bentobox.bentobox.api.flags;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick; import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
import world.bentobox.bentobox.api.flags.clicklisteners.IslandToggleClick; import world.bentobox.bentobox.api.flags.clicklisteners.IslandToggleClick;
@ -71,11 +74,12 @@ public class Flag implements Comparable<Flag> {
private final int defaultRank; private final int defaultRank;
private final PanelItem.ClickHandler clickHandler; private final PanelItem.ClickHandler clickHandler;
private final boolean subPanel; private final boolean subPanel;
private Set<GameModeAddon> gameModes = new HashSet<>();
/** /**
* {@link Flag.Builder} should be used instead. This is only used for testing. * {@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.id = id;
this.icon = icon; this.icon = icon;
this.listener = listener; this.listener = listener;
@ -83,6 +87,9 @@ public class Flag implements Comparable<Flag> {
this.defaultRank = defaultRank; this.defaultRank = defaultRank;
this.clickHandler = clickListener; this.clickHandler = clickListener;
this.subPanel = subPanel; this.subPanel = subPanel;
if (gameModeAddon != null) {
this.gameModes.add(gameModeAddon);
}
} }
private Flag(Builder builder) { private Flag(Builder builder) {
@ -94,6 +101,9 @@ public class Flag implements Comparable<Flag> {
this.defaultRank = builder.defaultRank; this.defaultRank = builder.defaultRank;
this.clickHandler = builder.clickHandler; this.clickHandler = builder.clickHandler;
this.subPanel = builder.usePanel; this.subPanel = builder.usePanel;
if (builder.gameModeAddon != null) {
this.gameModes.add(builder.gameModeAddon);
}
} }
public String getID() { public String getID() {
@ -226,6 +236,37 @@ public class Flag implements Comparable<Flag> {
return PROTECTION_FLAGS + this.id + ".hint"; return PROTECTION_FLAGS + this.id + ".hint";
} }
/**
* @return the gameModeAddon
*/
public Set<GameModeAddon> getGameModes() {
return gameModes;
}
/**
* @param gameModeAddon the gameModeAddon to set
*/
public void setGameModes(Set<GameModeAddon> 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 <tt>true</tt> 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. * 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 * @param plugin - plugin
@ -298,6 +339,7 @@ public class Flag implements Comparable<Flag> {
} }
/** /**
* Builder for making flags
* @author tastybento, Poslovitch * @author tastybento, Poslovitch
*/ */
public static class Builder { public static class Builder {
@ -321,41 +363,94 @@ public class Flag implements Comparable<Flag> {
// Whether there is a sub-panel or not // Whether there is a sub-panel or not
private boolean usePanel = false; 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) { public Builder(String id, Material icon) {
this.id = id; this.id = id;
this.icon = icon; 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) { public Builder listener(Listener listener) {
this.listener = listener; this.listener = listener;
return this; 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) { public Builder type(Type type) {
this.type = type; this.type = type;
return this; return this;
} }
/**
* The click handler to use when this icon is clicked
* @param clickHandler - click handler
* @return Builder
*/
public Builder clickHandler(PanelItem.ClickHandler clickHandler) { public Builder clickHandler(PanelItem.ClickHandler clickHandler) {
this.clickHandler = clickHandler; this.clickHandler = clickHandler;
return this; 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) { public Builder defaultSetting(boolean defaultSetting) {
this.defaultSetting = defaultSetting; this.defaultSetting = defaultSetting;
return this; return this;
} }
/**
* Set the default rank for {@link Type#PROTECTION} flags
* @param defaultRank - default rank
* @return Builder
*/
public Builder defaultRank(int defaultRank) { public Builder defaultRank(int defaultRank) {
this.defaultRank = defaultRank; this.defaultRank = defaultRank;
return this; 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) { public Builder usePanel(boolean usePanel) {
this.usePanel = usePanel; this.usePanel = usePanel;
return this; 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() { public Flag build() {
// If no clickHandler has been set, then apply default ones // If no clickHandler has been set, then apply default ones
if (clickHandler == null) { if (clickHandler == null) {

View File

@ -44,7 +44,8 @@ public class SettingsPanel {
List<Flag> flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(flagType)) List<Flag> flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(flagType))
.sorted(Comparator.comparing(flag -> user.getTranslation(flag.getNameReference()))) .sorted(Comparator.comparing(flag -> user.getTranslation(flag.getNameReference())))
.collect(Collectors.toList()); .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 // Use paging
flags.stream().skip(page * 43L).limit(page * 43L + 43L).forEach((f -> panelBuilder.item(f.toPanelItem(plugin, user)))); flags.stream().skip(page * 43L).limit(page * 43L + 43L).forEach((f -> panelBuilder.item(f.toPanelItem(plugin, user))));
// Add forward and backward icons // Add forward and backward icons

View File

@ -78,44 +78,44 @@ public class FlagTest {
@Test @Test
public void testHashCode() { public void testHashCode() {
Flag flag1 = 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); Flag flag2 = new Flag(null, null, null, null, 0, null, false, null);
assertTrue(flag1.hashCode() == flag2.hashCode()); assertTrue(flag1.hashCode() == flag2.hashCode());
} }
@Test @Test
public void testFlag() { 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 @Test
public void testGetID() { 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()); assertEquals("id", id.getID());
} }
@Test @Test
public void testGetIcon() { 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()); assertEquals(Material.ACACIA_DOOR, id.getIcon());
} }
@Test @Test
public void testGetListener() { public void testGetListener() {
Listener l = mock(Listener.class); 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<Listener> ol = Optional.ofNullable(l); Optional<Listener> ol = Optional.ofNullable(l);
assertEquals(ol, id.getListener()); 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()); assertEquals(Optional.empty(), id.getListener());
} }
@Test @Test
public void testIsDefaultSetting() { public void testIsDefaultSetting() {
Type type = Type.SETTING; 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))); 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); id.setDefaultSetting(true);
assertTrue(id.isSetForWorld(mock(World.class))); assertTrue(id.isSetForWorld(mock(World.class)));
} }
@ -123,7 +123,7 @@ public class FlagTest {
@Test @Test
public void testSetDefaultSetting() { public void testSetDefaultSetting() {
Type type = Type.SETTING; 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))); assertFalse(id.isSetForWorld(mock(World.class)));
id.setDefaultSetting(true); id.setDefaultSetting(true);
assertTrue(id.isSetForWorld(mock(World.class))); assertTrue(id.isSetForWorld(mock(World.class)));
@ -135,25 +135,25 @@ public class FlagTest {
@Test @Test
public void testIsDefaultSetting_World_Setting() { public void testIsDefaultSetting_World_Setting() {
Type type = Type.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))); assertFalse(id.isSetForWorld(mock(World.class)));
// Default can only be set once with world settings, so use a new id for flag // 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); id.setDefaultSetting(true);
assertTrue(id.isSetForWorld(mock(World.class))); assertTrue(id.isSetForWorld(mock(World.class)));
} }
@Test @Test
public void testGetType() { 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()); 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()); assertEquals(Flag.Type.SETTING,id.getType());
} }
@Test @Test
public void testGetDefaultRank() { 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()); assertEquals(100, id.getDefaultRank());
} }
@ -161,18 +161,18 @@ public class FlagTest {
@Test @Test
public void testEqualsObject() { public void testEqualsObject() {
Flag flag1 = null; 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)); assertFalse(flag2.equals(null));
int i = 45; int i = 45;
assertFalse(flag2.equals(i)); 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; flag2 = flag1;
assertTrue(flag1.equals(flag2)); assertTrue(flag1.equals(flag2));
assertTrue(flag2.equals(flag1)); 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(flag1.equals(flag2));
assertFalse(flag2.equals(flag1)); 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.VISITOR_RANK))).thenReturn("Visitor");
when(rm.getRank(Mockito.eq(RanksManager.OWNER_RANK))).thenReturn("Owner"); 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); PanelItem pi = id.toPanelItem(plugin, user);
@ -222,14 +222,14 @@ public class FlagTest {
@Test @Test
public void testToString() { 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()); assertEquals("Flag [id=id, icon=ACACIA_DOOR, listener=null, type=PROTECTION, defaultSetting=false, defaultRank=0, clickHandler=null, subPanel=false]", id.toString());
} }
@Test @Test
public void testCompareTo() { public void testCompareTo() {
Flag aaa = new Flag("AAA", 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); 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(bbb) < bbb.compareTo(aaa));
assertTrue(aaa.compareTo(aaa) == 0); assertTrue(aaa.compareTo(aaa) == 0);
} }