Added specific WORLD_SETTING flag.

This flag is separate from island SETTING flags. The settings are done
in a different way and rather than try and work out which type is which,
it is better to specify them at the start.

Also added a SUB_MENU settings type.
This commit is contained in:
tastybento 2018-06-08 08:20:16 -07:00
parent 8a339f755a
commit 9a666e29ca
24 changed files with 271 additions and 77 deletions

View File

@ -334,6 +334,9 @@ protection:
ITEM_PICKUP: "ITEM_PICKUP" ITEM_PICKUP: "ITEM_PICKUP"
INVINCIBLE_VISITORS: INVINCIBLE_VISITORS:
name: "Invincible Visitors" name: "Invincible Visitors"
description: |
Configure invincible visitor
settings.
LEASH: "LEASH" LEASH: "LEASH"
LOCK: LOCK:
name: "Lock island" name: "Lock island"
@ -353,9 +356,21 @@ protection:
PLACE_BLOCKS: "PLACE_BLOCKS" PLACE_BLOCKS: "PLACE_BLOCKS"
PORTAL: "PORTAL" PORTAL: "PORTAL"
PRESSURE_PLATE: "PRESSURE_PLATE" PRESSURE_PLATE: "PRESSURE_PLATE"
PVP_OVERWORLD: "PVP_OVERWORLD" PVP_OVERWORLD:
PVP_NETHER: "PVP_NETHER" name: "Overworld PVP"
PVP_END: "PVP_END" description: |
Enable/Disable PVP
on island.
PVP_NETHER:
name: "Nether PVP"
description: |
Enable/Disable PVP
in nether.
PVP_END:
name: "End PVP"
description: |
Enable/Disable PVP
in the End.
REDSTONE: "REDSTONE" REDSTONE: "REDSTONE"
SPAWN_EGGS: "SPAWN_EGGS" SPAWN_EGGS: "SPAWN_EGGS"
SHEARING: "SHEARING" SHEARING: "SHEARING"

View File

@ -1494,8 +1494,10 @@ public class Settings implements DataObject, WorldSettings {
} }
/** /**
* Invincible visitor settings
* @return the ivSettings * @return the ivSettings
*/ */
@Override
public List<String> getIvSettings() { public List<String> getIvSettings() {
return ivSettings; return ivSettings;
} }

View File

@ -1,5 +1,6 @@
package us.tastybento.bskyblock.api.configuration; package us.tastybento.bskyblock.api.configuration;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -125,5 +126,10 @@ public interface WorldSettings {
* @return the permission prefix * @return the permission prefix
*/ */
String getPermissionPrefix(); String getPermissionPrefix();
/**
* @return Invincible Visitor setting list
*/
List<String> getIvSettings();
} }

View File

@ -22,7 +22,9 @@ public class Flag implements Comparable<Flag> {
public enum Type { public enum Type {
PROTECTION, PROTECTION,
SETTING SETTING,
SUB_MENU,
WORLD_SETTING
} }
private final String id; private final String id;
@ -61,10 +63,10 @@ public class Flag implements Comparable<Flag> {
* @param world - world * @param world - world
* @return world setting, or default system setting if a specific world setting is not set * @return world setting, or default system setting if a specific world setting is not set
*/ */
public boolean isSet(World world) { public boolean isSetForWorld(World world) {
return worldSettings.getOrDefault(Util.getWorld(world), setting); return worldSettings.getOrDefault(Util.getWorld(world), setting);
} }
/** /**
* Set the default or global setting for this world * Set the default or global setting for this world
* @param world - world * @param world - world
@ -146,32 +148,40 @@ public class Flag implements Comparable<Flag> {
.icon(new ItemStack(icon)) .icon(new ItemStack(icon))
.name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation("protection.flags." + id + ".name"))) .name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation("protection.flags." + id + ".name")))
.clickHandler(clickHandler); .clickHandler(clickHandler);
// Check if this is a setting or world setting
// Check if this is a setting if (this.getType().equals(Type.WORLD_SETTING)) {
if (this.getType().equals(Type.SETTING)) { String setting = this.isSetForWorld(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
String setting = this.isSet(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
: user.getTranslation("protection.panel.flag-item.setting-disabled"); : user.getTranslation("protection.panel.flag-item.setting-disabled");
pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", "[description]", user.getTranslation("protection.flags." + id + ".description") pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", "[description]", user.getTranslation("protection.flags." + id + ".description")
, "[setting]", setting)); , "[setting]", setting));
return pib.build(); return pib.build();
} }
// Protection flag
pib.description(user.getTranslation("protection.panel.flag-item.description-layout", "[description]", user.getTranslation("protection.flags." + id + ".description")));
// Get the island this user is on or their own // Get the island this user is on or their own
Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId())); Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()));
if (island != null) { if (island != null) {
if (this.getType().equals(Type.SETTING)) {
String setting = island.isAllowed(this) ? user.getTranslation("protection.panel.flag-item.setting-active")
: user.getTranslation("protection.panel.flag-item.setting-disabled");
pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", "[description]", user.getTranslation("protection.flags." + id + ".description")
, "[setting]", setting));
return pib.build();
}
// TODO: Get the world settings - the player has no island and is not in an island location // TODO: Get the world settings - the player has no island and is not in an island location
// Dynamic rank list // Dynamic rank list
plugin.getRanksManager().getRanks().forEach((reference, score) -> { if (this.getType().equals(Type.PROTECTION)) {
if (score > RanksManager.BANNED_RANK && score < island.getFlag(this)) { // Protection flag
pib.description(user.getTranslation("protection.panel.flag-item.blocked_rank") + user.getTranslation(reference)); pib.description(user.getTranslation("protection.panel.flag-item.description-layout", "[description]", user.getTranslation("protection.flags." + id + ".description")));
} else if (score <= RanksManager.OWNER_RANK && score > island.getFlag(this)) { plugin.getRanksManager().getRanks().forEach((reference, score) -> {
pib.description(user.getTranslation("protection.panel.flag-item.allowed_rank") + user.getTranslation(reference)); if (score > RanksManager.BANNED_RANK && score < island.getFlag(this)) {
} else if (score == island.getFlag(this)) { pib.description(user.getTranslation("protection.panel.flag-item.blocked_rank") + user.getTranslation(reference));
pib.description(user.getTranslation("protection.panel.flag-item.minimal_rank") + user.getTranslation(reference)); } else if (score <= RanksManager.OWNER_RANK && score > island.getFlag(this)) {
} pib.description(user.getTranslation("protection.panel.flag-item.allowed_rank") + user.getTranslation(reference));
}); } else if (score == island.getFlag(this)) {
pib.description(user.getTranslation("protection.panel.flag-item.minimal_rank") + user.getTranslation(reference));
}
});
}
} }
return pib.build(); return pib.build();
} }

View File

@ -5,7 +5,7 @@ import org.bukkit.event.Listener;
import us.tastybento.bskyblock.api.flags.Flag.Type; import us.tastybento.bskyblock.api.flags.Flag.Type;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.listeners.flags.CycleClick; import us.tastybento.bskyblock.listeners.flags.clicklisteners.CycleClick;
import us.tastybento.bskyblock.managers.RanksManager; import us.tastybento.bskyblock.managers.RanksManager;
public class FlagBuilder { public class FlagBuilder {
@ -88,7 +88,7 @@ public class FlagBuilder {
/** /**
* Adds a listener for clicks on this flag when it is a panel item. Default is * Adds a listener for clicks on this flag when it is a panel item. Default is
* {@link us.tastybento.bskyblock.listeners.flags.CycleClick} * {@link us.tastybento.bskyblock.listeners.flags.clicklisteners.CycleClick}
* @param onClickListener - the listener for clicks. Must use the ClickOn interface * @param onClickListener - the listener for clicks. Must use the ClickOn interface
* @return FlagBuilder * @return FlagBuilder
*/ */

View File

@ -167,17 +167,15 @@ public class Island implements DataObject {
return createdDate; return createdDate;
} }
/** /**
* Gets the rank needed to bypass this Island Guard flag * Gets the Island Guard flag's setting. If this is a protection flag, the this will be the
* rank needed to bypass this flag. If it is a Settings flag, any non-zero value means the
* setting is allowed.
* @param flag * @param flag
* @return the rank needed to bypass this flag. Players must have at least this rank to bypass this flag. * @return flag value
*/ */
public int getFlag(Flag flag){ public int getFlag(Flag flag) {
if(flags.containsKey(flag)) { flags.putIfAbsent(flag, flag.getDefaultRank());
return flags.get(flag); return flags.get(flag);
} else {
flags.put(flag, flag.getDefaultRank());
return flag.getDefaultRank();
}
} }
/** /**
@ -396,11 +394,12 @@ public class Island implements DataObject {
/** /**
* Check if the flag is allowed or not * Check if the flag is allowed or not
* For flags that are for the island in general and not related to rank * For flags that are for the island in general and not related to rank.
* @param flag * @param flag
* @return true if allowed, false if not * @return true if allowed, false if not
*/ */
public boolean isAllowed(Flag flag) { public boolean isAllowed(Flag flag) {
// A negative value means not allowed
return getFlag(flag) >= 0; return getFlag(flag) >= 0;
} }
@ -701,4 +700,27 @@ public class Island implements DataObject {
} }
/**
* Toggles a settings flag
* @param flag
*/
public void toggleFlag(Flag flag) {
if (flag.getType().equals(Flag.Type.SETTING) || flag.getType().equals(Flag.Type.WORLD_SETTING)) {
setSettingsFlag(flag, !isAllowed(flag));
}
}
/**
* Sets the state of a settings flag
* @param flag
* @param state
*/
public void setSettingsFlag(Flag flag, boolean state) {
if (flag.getType().equals(Flag.Type.SETTING) || flag.getType().equals(Flag.Type.WORLD_SETTING)) {
flags.put(flag, state ? 1 : -1);
}
}
} }

View File

@ -130,7 +130,7 @@ public abstract class AbstractFlagListener implements Listener {
// Handle Settings Flag // Handle Settings Flag
if (flag.getType().equals(Type.SETTING)) { if (flag.getType().equals(Type.SETTING)) {
// If the island exists, return the setting, otherwise return the default setting for this flag // If the island exists, return the setting, otherwise return the default setting for this flag
return island.map(x -> x.isAllowed(flag)).orElse(flag.isSet(loc.getWorld())); return island.map(x -> x.isAllowed(flag)).orElse(flag.isSetForWorld(loc.getWorld()));
} }
// Protection flag // Protection flag
@ -158,7 +158,7 @@ public abstract class AbstractFlagListener implements Listener {
} }
} }
// The player is in the world, but not on an island, so general world settings apply // The player is in the world, but not on an island, so general world settings apply
if (!flag.isSet(loc.getWorld())) { if (!flag.isSetForWorld(loc.getWorld())) {
noGo(e, silent); noGo(e, silent);
user = null; user = null;
return false; return false;

View File

@ -104,7 +104,7 @@ public class BreakBlocksListener extends AbstractFlagListener {
}); });
// The player is in the world, but not on an island, so general world settings apply // The player is in the world, but not on an island, so general world settings apply
if (!Flags.BREAK_BLOCKS.isSet(e.getVehicle().getWorld())) { if (!Flags.BREAK_BLOCKS.isSetForWorld(e.getVehicle().getWorld())) {
e.setCancelled(true); e.setCancelled(true);
user.sendMessage("protection.protected"); user.sendMessage("protection.protected");
} }

View File

@ -26,7 +26,7 @@ public class EnterExitListener extends AbstractFlagListener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onMove(PlayerMoveEvent e) { public void onMove(PlayerMoveEvent e) {
// Only process if Enter Exit flags are active, we are in the right world and there is a change in X or Z coords // Only process if Enter Exit flags are active, we are in the right world and there is a change in X or Z coords
if (!Flags.ENTER_EXIT_MESSAGES.isSet(e.getFrom().getWorld()) if (!Flags.ENTER_EXIT_MESSAGES.isSetForWorld(e.getFrom().getWorld())
|| e.getFrom().toVector().multiply(XZ).equals(e.getTo().toVector().multiply(XZ)) || e.getFrom().toVector().multiply(XZ).equals(e.getTo().toVector().multiply(XZ))
|| !getIslandWorldManager().inWorld(e.getFrom())) { || !getIslandWorldManager().inWorld(e.getFrom())) {
return; return;
@ -47,9 +47,13 @@ public class EnterExitListener extends AbstractFlagListener {
return; return;
} }
User user = User.getInstance(e.getPlayer()); User user = User.getInstance(e.getPlayer());
from.ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-leaving", "[name]", !i.getName().isEmpty() ? i.getName() : // Send message if island is owned by someone
from.filter(i -> i.getOwner() != null).ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-leaving", "[name]", !i.getName().isEmpty() ? i.getName() :
user.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", "[name]", getPlugin().getPlayers().getName(i.getOwner())))); user.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", "[name]", getPlugin().getPlayers().getName(i.getOwner()))));
to.ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-entering", "[name]", !i.getName().isEmpty() ? i.getName() : to.filter(i -> i.getOwner() != null).ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-entering", "[name]", !i.getName().isEmpty() ? i.getName() :
user.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", "[name]", getPlugin().getPlayers().getName(i.getOwner())))); user.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", "[name]", getPlugin().getPlayers().getName(i.getOwner()))));
// Send message if island is unowned, but has a name
from.filter(i -> i.getOwner() == null && !i.getName().isEmpty()).ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-leaving", "[name]", i.getName()));
to.filter(i -> i.getOwner() == null && !i.getName().isEmpty()).ifPresent(i -> user.sendMessage("protection.flags.ENTER_EXIT_MESSAGES.now-entering", "[name]", i.getName()));
} }
} }

View File

@ -40,7 +40,7 @@ public class FireListener extends AbstractFlagListener {
return false; return false;
} }
// Check if the island exists and if fire is allowed // Check if the island exists and if fire is allowed
boolean cancel = getIslands().getIslandAt(l).map(i -> !i.isAllowed(flag)).orElse(!flag.isSet(l.getWorld())); boolean cancel = getIslands().getIslandAt(l).map(i -> !i.isAllowed(flag)).orElse(!flag.isSetForWorld(l.getWorld()));
e.setCancelled(cancel); e.setCancelled(cancel);
return cancel; return cancel;
} }

View File

@ -5,7 +5,12 @@ package us.tastybento.bskyblock.listeners.flags;
import java.util.Arrays; import java.util.Arrays;
import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
@ -16,6 +21,7 @@ import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.Util;
import us.tastybento.bskyblock.util.teleport.SafeTeleportBuilder;
/** /**
* @author tastybento * @author tastybento
@ -62,7 +68,34 @@ public class InvincibleVisitorsListener extends AbstractFlagListener implements
pb.item(pib.build()); pb.item(pib.build());
}); });
pb.build(); pb.build();
}
/**
* Prevents visitors from getting damage if a particular damage type is listed in the config
* @param e - event
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onVisitorGetDamage(EntityDamageEvent e) {
World world = e.getEntity().getWorld();
if (!getPlugin().getIWM().getIvSettings(world).contains(e.getCause().name())
|| !(e.getEntity() instanceof Player)
|| e.getCause().equals(DamageCause.ENTITY_ATTACK)
|| !getPlugin().getIWM().inWorld(e.getEntity().getLocation())
|| getIslands().userIsOnIsland(world, User.getInstance(e.getEntity()))) {
return;
}
// Player is a visitor and should be protected from damage
e.setCancelled(true);
Player p = (Player) e.getEntity();
// Handle the void - teleport player back to island in a safe spot
if(e.getCause().equals(DamageCause.VOID)) {
// Will be set back after the teleport
p.setGameMode(GameMode.SPECTATOR);
getIslands().getIslandAt(p.getLocation()).ifPresent(i -> {
new SafeTeleportBuilder(getPlugin()).entity(p).island(i).build();
});
}
} }

View File

@ -43,11 +43,11 @@ public class MobSpawnListener extends AbstractFlagListener {
Optional<Island> island = getIslands().getIslandAt(e.getLocation()); Optional<Island> island = getIslands().getIslandAt(e.getLocation());
// Cancel the event if these are true // Cancel the event if these are true
if ((e.getEntity() instanceof Monster || e.getEntity() instanceof Slime)) { if ((e.getEntity() instanceof Monster || e.getEntity() instanceof Slime)) {
boolean cancel = island.map(i -> !i.isAllowed(Flags.MONSTER_SPAWN)).orElse(!Flags.MONSTER_SPAWN.isSet(e.getEntity().getWorld())); boolean cancel = island.map(i -> !i.isAllowed(Flags.MONSTER_SPAWN)).orElse(!Flags.MONSTER_SPAWN.isSetForWorld(e.getEntity().getWorld()));
e.setCancelled(cancel); e.setCancelled(cancel);
return cancel; return cancel;
} else if (e.getEntity() instanceof Animals) { } else if (e.getEntity() instanceof Animals) {
boolean cancel = island.map(i -> !i.isAllowed(Flags.ANIMAL_SPAWN)).orElse(!Flags.ANIMAL_SPAWN.isSet(e.getEntity().getWorld())); boolean cancel = island.map(i -> !i.isAllowed(Flags.ANIMAL_SPAWN)).orElse(!Flags.ANIMAL_SPAWN.isSetForWorld(e.getEntity().getWorld()));
e.setCancelled(cancel); e.setCancelled(cancel);
return cancel; return cancel;
} }

View File

@ -39,26 +39,40 @@ public class PVPListener extends AbstractFlagListener {
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(final EntityDamageByEntityEvent e) { public void onEntityDamage(final EntityDamageByEntityEvent e) {
// Check PVP
if (e.getEntity() instanceof Player) { if (e.getEntity() instanceof Player) {
// Protect visitors
if (e.getCause().equals(DamageCause.ENTITY_ATTACK)
&& getPlugin().getIWM().getIvSettings(e.getEntity().getWorld()).contains(DamageCause.ENTITY_ATTACK.name())
&& !getIslands().userIsOnIsland(e.getEntity().getWorld(), User.getInstance(e.getEntity()))) {
e.setCancelled(true);
return;
}
Flag flag = Flags.PVP_OVERWORLD; Flag flag = Flags.PVP_OVERWORLD;
if (e.getEntity().getWorld().equals(getPlugin().getIWM().getNetherWorld())) { if (e.getEntity().getWorld().equals(getPlugin().getIWM().getNetherWorld(e.getEntity().getWorld()))) {
flag = Flags.PVP_NETHER; flag = Flags.PVP_NETHER;
} else if (e.getEntity().getWorld().equals(getPlugin().getIWM().getEndWorld())) { } else if (e.getEntity().getWorld().equals(getPlugin().getIWM().getEndWorld(e.getEntity().getWorld()))) {
flag = Flags.PVP_END; flag = Flags.PVP_END;
} }
respond(e, e.getDamager(), flag); respond(e, e.getDamager(), flag);
} }
} }
private void respond(Event event, Entity damager, Flag flag) { /**
* Checks how to respond to an attack
* @param e
* @param damager
* @param flag
*/
private void respond(Event e, Entity damager, Flag flag) {
// Get the attacker // Get the attacker
if (damager instanceof Player) { if (damager instanceof Player) {
setUser(User.getInstance(damager)).checkIsland(event, damager.getLocation(), flag); setUser(User.getInstance(damager)).checkIsland(e, damager.getLocation(), flag);
} else if (damager instanceof Projectile) { } else if (damager instanceof Projectile) {
// Find out who fired the arrow // Find out who fired the arrow
Projectile p = (Projectile) damager; Projectile p = (Projectile) damager;
if (p.getShooter() instanceof Player) { if (p.getShooter() instanceof Player) {
if (!setUser(User.getInstance((Player)p.getShooter())).checkIsland(event, damager.getLocation(), flag)) { if (!setUser(User.getInstance((Player)p.getShooter())).checkIsland(e, damager.getLocation(), flag)) {
damager.setFireTicks(0); damager.setFireTicks(0);
damager.remove(); damager.remove();
} }
@ -70,6 +84,12 @@ public class PVPListener extends AbstractFlagListener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFishing(PlayerFishEvent e) { public void onFishing(PlayerFishEvent e) {
if (e.getCaught() instanceof Player) { if (e.getCaught() instanceof Player) {
// Protect visitors
if (getPlugin().getIWM().getIvSettings(e.getPlayer().getWorld()).contains(DamageCause.ENTITY_ATTACK.name())
&& !getIslands().userIsOnIsland(e.getPlayer().getWorld(), User.getInstance(e.getCaught()))) {
e.setCancelled(true);
return;
}
Flag flag = Flags.PVP_OVERWORLD; Flag flag = Flags.PVP_OVERWORLD;
if (e.getCaught().getWorld().equals(getPlugin().getIWM().getNetherWorld())) { if (e.getCaught().getWorld().equals(getPlugin().getIWM().getNetherWorld())) {
flag = Flags.PVP_NETHER; flag = Flags.PVP_NETHER;
@ -108,6 +128,12 @@ public class PVPListener extends AbstractFlagListener {
} }
// PVP? // PVP?
if (entity instanceof Player) { if (entity instanceof Player) {
// Protect visitors
if (getPlugin().getIWM().getIvSettings(entity.getWorld()).contains(DamageCause.ENTITY_ATTACK.name())
&& !getIslands().userIsOnIsland(entity.getWorld(), User.getInstance(entity))) {
e.setCancelled(true);
return;
}
if (!setUser(User.getInstance(attacker)).checkIsland(e, entity.getLocation(), flag)) { if (!setUser(User.getInstance(attacker)).checkIsland(e, entity.getLocation(), flag)) {
for (PotionEffect effect : e.getPotion().getEffects()) { for (PotionEffect effect : e.getPotion().getEffects()) {
entity.removePotionEffect(effect.getType()); entity.removePotionEffect(effect.getType());
@ -153,6 +179,12 @@ public class PVPListener extends AbstractFlagListener {
Entity entity = e.getEntity(); Entity entity = e.getEntity();
// PVP? // PVP?
if (entity instanceof Player) { if (entity instanceof Player) {
// Protect visitors
if (getPlugin().getIWM().getIvSettings(entity.getWorld()).contains(DamageCause.ENTITY_ATTACK.name())
&& !getIslands().userIsOnIsland(entity.getWorld(), User.getInstance(entity))) {
e.setCancelled(true);
return;
}
checkIsland(e, entity.getLocation(), flag); checkIsland(e, entity.getLocation(), flag);
} }
} }

View File

@ -19,7 +19,7 @@ public class PistonPushListener extends AbstractFlagListener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPistonExtend(BlockPistonExtendEvent e) { public void onPistonExtend(BlockPistonExtendEvent e) {
// Only process if flag is active // Only process if flag is active
if (Flags.PISTON_PUSH.isSet(e.getBlock().getWorld())) { if (Flags.PISTON_PUSH.isSetForWorld(e.getBlock().getWorld())) {
getIslands().getProtectedIslandAt(e.getBlock().getLocation()).ifPresent(i -> getIslands().getProtectedIslandAt(e.getBlock().getLocation()).ifPresent(i ->
e.setCancelled( e.setCancelled(
// Run through the location of all the relative blocks and see if they are outside the island // Run through the location of all the relative blocks and see if they are outside the island

View File

@ -1,4 +1,4 @@
package us.tastybento.bskyblock.listeners.flags; package us.tastybento.bskyblock.listeners.flags.clicklisteners;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;

View File

@ -0,0 +1,52 @@
/**
*
*/
package us.tastybento.bskyblock.listeners.flags.clicklisteners;
import org.bukkit.Sound;
import org.bukkit.event.inventory.ClickType;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.flags.Flag;
import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island;
/**
* Toggles a island setting on/off
* @author tastybento
*
*/
public class IslandToggleClickListener implements ClickHandler {
private BSkyBlock plugin = BSkyBlock.getInstance();
private String id;
/**
* @param id
*/
public IslandToggleClickListener(String id) {
this.id = id;
}
/* (non-Javadoc)
* @see us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler#onClick(us.tastybento.bskyblock.api.panels.Panel, us.tastybento.bskyblock.api.user.User, org.bukkit.event.inventory.ClickType, int)
*/
@Override
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
// Get the user's island
Island island = plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId());
if (island != null && island.getOwner().equals(user.getUniqueId())) {
Flag flag = plugin.getFlagsManager().getFlagByID(id);
// Toggle flag
island.toggleFlag(flag);
user.getWorld().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F);
// Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem());
}
return true;
}
}

View File

@ -1,7 +1,7 @@
/** /**
* *
*/ */
package us.tastybento.bskyblock.listeners.flags; package us.tastybento.bskyblock.listeners.flags.clicklisteners;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
@ -14,10 +14,11 @@ import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.Util;
/** /**
* Toggles a worldwide setting on/off
* @author tastybento * @author tastybento
* *
*/ */
public class SettingsToggleClickListener implements ClickHandler { public class WorldToggleClickListener implements ClickHandler {
private BSkyBlock plugin = BSkyBlock.getInstance(); private BSkyBlock plugin = BSkyBlock.getInstance();
private String id; private String id;
@ -25,7 +26,7 @@ public class SettingsToggleClickListener implements ClickHandler {
/** /**
* @param id * @param id
*/ */
public SettingsToggleClickListener(String id) { public WorldToggleClickListener(String id) {
this.id = id; this.id = id;
} }
@ -49,7 +50,7 @@ public class SettingsToggleClickListener implements ClickHandler {
// Get flag // Get flag
Flag flag = plugin.getFlagsManager().getFlagByID(id); Flag flag = plugin.getFlagsManager().getFlagByID(id);
// Toggle flag // Toggle flag
flag.setSetting(user.getWorld(), !flag.isSet(user.getWorld())); flag.setSetting(user.getWorld(), !flag.isSetForWorld(user.getWorld()));
user.getWorld().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); user.getWorld().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F);
// Apply change to panel // Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem()); panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem());

View File

@ -29,9 +29,10 @@ import us.tastybento.bskyblock.listeners.flags.PhysicalInteractionListener;
import us.tastybento.bskyblock.listeners.flags.PistonPushListener; import us.tastybento.bskyblock.listeners.flags.PistonPushListener;
import us.tastybento.bskyblock.listeners.flags.PlaceBlocksListener; import us.tastybento.bskyblock.listeners.flags.PlaceBlocksListener;
import us.tastybento.bskyblock.listeners.flags.PortalListener; import us.tastybento.bskyblock.listeners.flags.PortalListener;
import us.tastybento.bskyblock.listeners.flags.SettingsToggleClickListener;
import us.tastybento.bskyblock.listeners.flags.ShearingListener; import us.tastybento.bskyblock.listeners.flags.ShearingListener;
import us.tastybento.bskyblock.listeners.flags.TeleportationListener; import us.tastybento.bskyblock.listeners.flags.TeleportationListener;
import us.tastybento.bskyblock.listeners.flags.clicklisteners.IslandToggleClickListener;
import us.tastybento.bskyblock.listeners.flags.clicklisteners.WorldToggleClickListener;
import us.tastybento.bskyblock.managers.RanksManager; import us.tastybento.bskyblock.managers.RanksManager;
public class Flags { public class Flags {
@ -132,24 +133,27 @@ public class Flags {
* Settings flags (not protection flags) * Settings flags (not protection flags)
*/ */
// PVP // PVP
public static final Flag PVP_OVERWORLD = new FlagBuilder().id("PVP_OVERWORLD").icon(Material.ARROW).type(Type.SETTING).listener(new PVPListener()).build(); public static final Flag PVP_OVERWORLD = new FlagBuilder().id("PVP_OVERWORLD").icon(Material.ARROW).type(Type.SETTING)
public static final Flag PVP_NETHER = new FlagBuilder().id("PVP_NETHER").icon(Material.IRON_AXE).type(Type.SETTING).build(); .listener(new PVPListener()).onClick(new IslandToggleClickListener("PVP_OVERWORLD")).build();
public static final Flag PVP_END = new FlagBuilder().id("PVP_END").icon(Material.END_CRYSTAL).type(Type.SETTING).build(); public static final Flag PVP_NETHER = new FlagBuilder().id("PVP_NETHER").icon(Material.IRON_AXE).type(Type.SETTING)
.onClick(new IslandToggleClickListener("PVP_NETHER")).build();
public static final Flag PVP_END = new FlagBuilder().id("PVP_END").icon(Material.END_CRYSTAL).type(Type.SETTING)
.onClick(new IslandToggleClickListener("PVP_END")).build();
// Others // Others
public static final Flag ANIMAL_SPAWN = new FlagBuilder().id("ANIMAL_SPAWN").icon(Material.APPLE).allowedByDefault(true).type(Type.SETTING).build(); public static final Flag ANIMAL_SPAWN = new FlagBuilder().id("ANIMAL_SPAWN").icon(Material.APPLE).allowedByDefault(true).type(Type.SETTING).build();
public static final Flag MONSTER_SPAWN = new FlagBuilder().id("MONSTER_SPAWN").icon(Material.MOB_SPAWNER).allowedByDefault(true).type(Type.SETTING).build(); public static final Flag MONSTER_SPAWN = new FlagBuilder().id("MONSTER_SPAWN").icon(Material.MOB_SPAWNER).allowedByDefault(true).type(Type.SETTING).build();
public static final Flag FIRE_SPREAD = new FlagBuilder().id("FIRE_SPREAD").icon(Material.FIREWORK_CHARGE).type(Type.SETTING).build(); public static final Flag FIRE_SPREAD = new FlagBuilder().id("FIRE_SPREAD").icon(Material.FIREWORK_CHARGE).type(Type.SETTING).build();
// Global flags (apply to every island) // Global flags (apply to every island)
public static final Flag ENTER_EXIT_MESSAGES = new FlagBuilder().id("ENTER_EXIT_MESSAGES").icon(Material.DIRT).allowedByDefault(true).type(Type.SETTING) public static final Flag ENTER_EXIT_MESSAGES = new FlagBuilder().id("ENTER_EXIT_MESSAGES").icon(Material.DIRT).allowedByDefault(true).type(Type.WORLD_SETTING)
.listener(new EnterExitListener()) .listener(new EnterExitListener())
.onClick(new SettingsToggleClickListener("ENTER_EXIT_MESSAGES")) .onClick(new WorldToggleClickListener("ENTER_EXIT_MESSAGES"))
.build(); .build();
public static final Flag PISTON_PUSH = new FlagBuilder().id("PISTON_PUSH").icon(Material.PISTON_BASE).allowedByDefault(true).type(Type.SETTING) public static final Flag PISTON_PUSH = new FlagBuilder().id("PISTON_PUSH").icon(Material.PISTON_BASE).allowedByDefault(true).type(Type.WORLD_SETTING)
.listener(new PistonPushListener()) .listener(new PistonPushListener())
.onClick(new SettingsToggleClickListener("PISTON_PUSH")) .onClick(new WorldToggleClickListener("PISTON_PUSH"))
.build(); .build();
static InvincibleVisitorsListener ilv = new InvincibleVisitorsListener(); static InvincibleVisitorsListener ilv = new InvincibleVisitorsListener();
public static final Flag INVINCIBLE_VISITORS = new FlagBuilder().id("INVINCIBLE_VISITORS").icon(Material.DIAMOND_CHESTPLATE).type(Type.SETTING) public static final Flag INVINCIBLE_VISITORS = new FlagBuilder().id("INVINCIBLE_VISITORS").icon(Material.DIAMOND_CHESTPLATE).type(Type.SUB_MENU)
.listener(ilv).onClick(ilv).build(); .listener(ilv).onClick(ilv).build();
/** /**

View File

@ -449,10 +449,20 @@ public class IslandWorldManager {
/** /**
* Get the permission prefix for this world * Get the permission prefix for this world
* @param world * @param world
* @return permission prefix for this world
*/ */
public String getPermissionPrefix(World world) { public String getPermissionPrefix(World world) {
return worldSettings.get(Util.getWorld(world)).getPermissionPrefix(); return worldSettings.get(Util.getWorld(world)).getPermissionPrefix();
} }
/**
* Get the invincible visitor settings for this world
* @param world
* @return invisible visitor settings
*/
public List<String> getIvSettings(World world) {
return worldSettings.get(world).getIvSettings();
}
} }

View File

@ -633,10 +633,11 @@ public class IslandsManager {
/** /**
* Checks if an online player is in the protected area of their island, a team island or a * Checks if an online player is in the protected area of their island, a team island or a
* coop island * coop island in the specific world in the arguments. Note that the user
* *
* @param user - the User * @param world - the world to check
* @return true if on valid island, false if not * @param user - the user
* @return true if on their island in world, false if not
*/ */
public boolean userIsOnIsland(World world, User user) { public boolean userIsOnIsland(World world, User user) {
if (user == null) { if (user == null) {

View File

@ -275,11 +275,11 @@ public class PlayersManager {
* Player must have logged into the game before * Player must have logged into the game before
* *
* @param playerUUID - the player's UUID * @param playerUUID - the player's UUID
* @return String - playerName * @return String - playerName, empty string if UUID is null
*/ */
public String getName(UUID playerUUID) { public String getName(UUID playerUUID) {
if (playerUUID == null) { if (playerUUID == null) {
return null; return "";
} }
addPlayer(playerUUID); addPlayer(playerUUID);
return playerCache.get(playerUUID).getPlayerName(); return playerCache.get(playerUUID).getPlayerName();

View File

@ -85,19 +85,19 @@ public class FlagTest {
@Test @Test
public void testIsDefaultSetting() { public void testIsDefaultSetting() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null); Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertFalse(id.isSet(mock(World.class))); assertFalse(id.isSetForWorld(mock(World.class)));
id = new Flag("id", Material.ACACIA_DOOR, null, true, null, 0, null); id = new Flag("id", Material.ACACIA_DOOR, null, true, null, 0, null);
assertTrue(id.isSet(mock(World.class))); assertTrue(id.isSetForWorld(mock(World.class)));
} }
@Test @Test
public void testSetDefaultSetting() { public void testSetDefaultSetting() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null); Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertFalse(id.isSet(mock(World.class))); assertFalse(id.isSetForWorld(mock(World.class)));
id.setDefaultSetting(true); id.setDefaultSetting(true);
assertTrue(id.isSet(mock(World.class))); assertTrue(id.isSetForWorld(mock(World.class)));
id.setDefaultSetting(false); id.setDefaultSetting(false);
assertFalse(id.isSet(mock(World.class))); assertFalse(id.isSetForWorld(mock(World.class)));
} }

View File

@ -36,6 +36,7 @@ import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.user.Notifier; import us.tastybento.bskyblock.api.user.Notifier;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.listeners.flags.clicklisteners.CycleClick;
import us.tastybento.bskyblock.managers.FlagsManager; import us.tastybento.bskyblock.managers.FlagsManager;
import us.tastybento.bskyblock.managers.IslandsManager; import us.tastybento.bskyblock.managers.IslandsManager;
import us.tastybento.bskyblock.managers.LocalesManager; import us.tastybento.bskyblock.managers.LocalesManager;

View File

@ -22,6 +22,7 @@ import us.tastybento.bskyblock.api.flags.Flag;
import us.tastybento.bskyblock.api.panels.Panel; import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.listeners.flags.clicklisteners.WorldToggleClickListener;
import us.tastybento.bskyblock.managers.FlagsManager; import us.tastybento.bskyblock.managers.FlagsManager;
import us.tastybento.bskyblock.managers.IslandWorldManager; import us.tastybento.bskyblock.managers.IslandWorldManager;
import us.tastybento.bskyblock.util.Util; import us.tastybento.bskyblock.util.Util;
@ -31,7 +32,7 @@ import us.tastybento.bskyblock.util.Util;
public class SettingsToggleClickListenerTest { public class SettingsToggleClickListenerTest {
private IslandWorldManager iwm; private IslandWorldManager iwm;
private SettingsToggleClickListener listener; private WorldToggleClickListener listener;
private Panel panel; private Panel panel;
private User user; private User user;
private Flag flag; private Flag flag;
@ -52,7 +53,7 @@ public class SettingsToggleClickListenerTest {
when(plugin.getIWM()).thenReturn(iwm); when(plugin.getIWM()).thenReturn(iwm);
listener = new SettingsToggleClickListener("test"); listener = new WorldToggleClickListener("test");
panel = mock(Panel.class); panel = mock(Panel.class);
when(panel.getInventory()).thenReturn(mock(Inventory.class)); when(panel.getInventory()).thenReturn(mock(Inventory.class));
@ -65,7 +66,7 @@ public class SettingsToggleClickListenerTest {
FlagsManager fm = mock(FlagsManager.class); FlagsManager fm = mock(FlagsManager.class);
flag = mock(Flag.class); flag = mock(Flag.class);
when(flag.isSet(Mockito.any())).thenReturn(false); when(flag.isSetForWorld(Mockito.any())).thenReturn(false);
PanelItem item = mock(PanelItem.class); PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class)); when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(Mockito.any(), Mockito.eq(user))).thenReturn(item); when(flag.toPanelItem(Mockito.any(), Mockito.eq(user))).thenReturn(item);