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;
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<Flag> {
private final int defaultRank;
private final PanelItem.ClickHandler clickHandler;
private final boolean subPanel;
private Set<GameModeAddon> 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<Flag> {
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<Flag> {
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<Flag> {
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.
* @param plugin - plugin
@ -298,6 +339,7 @@ public class Flag implements Comparable<Flag> {
}
/**
* Builder for making flags
* @author tastybento, Poslovitch
*/
public static class Builder {
@ -321,41 +363,94 @@ public class Flag implements Comparable<Flag> {
// 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) {

View File

@ -44,7 +44,8 @@ public class SettingsPanel {
List<Flag> 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

View File

@ -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<Listener> 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);
}