diff --git a/locales/en-US.yml b/locales/en-US.yml index b39d19772..e699f66e8 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -127,9 +127,10 @@ commands: parameters: "" description: "manipulate schems" copy-first: "&cCopy a schem first!" + file-exists: "&cFile already exists, overwrite?" no-such-file: "&cNo such file!" could-not-load: "&cCould not load that file!" - could-not-save: "&Hmm, something went wrong saving that file: [message]" + could-not-save: "&cHmm, something went wrong saving that file: [message]" set-pos1: "&aPosition 1 set at [vector]" set-pos2: "&aPosition 2 set at [vector]" set-different-pos: "&cSet a different location - this pos is already set!" diff --git a/plugin.yml b/plugin.yml index 322e7155a..0e471f4ae 100755 --- a/plugin.yml +++ b/plugin.yml @@ -41,13 +41,13 @@ permissions: default: true bskyblock.island.lock: description: Allows island locking - default: false + default: true bskyblock.island.expel: description: Allows expelling of visitors default: true bskyblock.island.ban: description: Allows banning of visitors - default: false + default: true bskyblock.island.settings: description: Player can see server settings default: true diff --git a/schems/island.schem b/schems/island.schem index 714541612..55a0e2f58 100644 Binary files a/schems/island.schem and b/schems/island.schem differ diff --git a/schems/nether-island.schem b/schems/nether-island.schem index 968824f5c..5cd7841c3 100644 Binary files a/schems/nether-island.schem and b/schems/nether-island.schem differ diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index 7cac0f642..a78a7ff60 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -25,6 +25,7 @@ import us.tastybento.bskyblock.managers.IslandsManager; import us.tastybento.bskyblock.managers.LocalesManager; import us.tastybento.bskyblock.managers.PlayersManager; import us.tastybento.bskyblock.managers.RanksManager; +import us.tastybento.bskyblock.managers.SchemsManager; import us.tastybento.bskyblock.util.HeadGetter; /** @@ -50,6 +51,7 @@ public class BSkyBlock extends JavaPlugin { private FlagsManager flagsManager; private IslandWorldManager islandWorldManager; private RanksManager ranksManager; + private SchemsManager schemsManager; // Settings private Settings settings; @@ -61,6 +63,9 @@ public class BSkyBlock extends JavaPlugin { @Override public void onEnable(){ + // Store the current millis time so we can tell how many ms it took for BSB to fully load. + final long startMillis = System.currentTimeMillis(); + // Save the default config from config.yml saveDefaultConfig(); setInstance(this); @@ -78,7 +83,7 @@ public class BSkyBlock extends JavaPlugin { // Start head getter headGetter = new HeadGetter(this); - + // Load metrics metrics = new Metrics(instance); registerCustomCharts(); @@ -95,21 +100,25 @@ public class BSkyBlock extends JavaPlugin { getServer().getScheduler().runTask(this, () -> { // Create the world if it does not exist islandWorldManager = new IslandWorldManager(instance); - + // Load schems manager + schemsManager = new SchemsManager(instance); + // Load the default island schems + schemsManager.loadIslands(getIWM().getIslandWorld()); + // Set up commands new IslandCommand(); new AdminCommand(); - + // Locales manager must be loaded before addons localesManager = new LocalesManager(instance); PlaceholderHandler.register(instance); - + // Load addons. Addons may load worlds, so they must go before islands are loaded. addonsManager = new AddonsManager(instance); addonsManager.loadAddons(); // Enable addons addonsManager.enableAddons(); - + getServer().getScheduler().runTask(instance, () -> { // Load Flags flagsManager = new FlagsManager(instance); @@ -119,9 +128,8 @@ public class BSkyBlock extends JavaPlugin { // Load islands from database - need to wait until all the worlds are loaded islandsManager.load(); - + // Save islands & players data asynchronously every X minutes - instance.getServer().getScheduler().runTaskTimer(instance, () -> { playersManager.save(true); islandsManager.save(true); @@ -129,6 +137,7 @@ public class BSkyBlock extends JavaPlugin { instance.log("#############################################"); instance.log(instance.getDescription().getFullName() + " has been fully enabled."); + instance.log("It took: " + (System.currentTimeMillis() - startMillis + "ms")); instance.log("Thanks for using our plugin !"); instance.log("- Tastybento and Poslovitch, 2017-2018"); instance.log("#############################################"); @@ -295,15 +304,15 @@ public class BSkyBlock extends JavaPlugin { public HeadGetter getHeadGetter() { return headGetter; } - + public void log(String string) { getLogger().info(() -> string); } - + public void logError(String error) { getLogger().severe(() -> error); } - + public void logWarning(String warning) { getLogger().warning(warning); } @@ -317,4 +326,14 @@ public class BSkyBlock extends JavaPlugin { islandWorldManager.addWorld(world, worldSettings); } + + + /** + * @return the schemsManager + */ + public SchemsManager getSchemsManager() { + return schemsManager; + } + + } diff --git a/src/main/java/us/tastybento/bskyblock/Settings.java b/src/main/java/us/tastybento/bskyblock/Settings.java index ba9d51773..fcc9649dc 100644 --- a/src/main/java/us/tastybento/bskyblock/Settings.java +++ b/src/main/java/us/tastybento/bskyblock/Settings.java @@ -6,12 +6,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.bukkit.GameMode; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.configuration.ConfigComment; import us.tastybento.bskyblock.api.configuration.ConfigEntry; import us.tastybento.bskyblock.api.configuration.StoreAt; @@ -165,7 +167,7 @@ public class Settings implements DataObject, WorldSettings { private int islandZOffset; @ConfigComment("Island height - Lowest is 5.") - @ConfigComment("It is the y coordinate of the bedrock block in the schematic") + @ConfigComment("It is the y coordinate of the bedrock block in the schem") @ConfigEntry(path = "world.island-height") private int islandHeight = 100; @@ -428,6 +430,7 @@ public class Settings implements DataObject, WorldSettings { @ConfigEntry(path = "panel.close-on-click-outside") private boolean closePanelOnClickOutside = true; + //---------------------------------------------------------------------------------------/ private String uniqueId = "config"; // Getters and setters @@ -1562,5 +1565,11 @@ public class Settings implements DataObject, WorldSettings { this.onLeaveResetEnderChest = onLeaveResetEnderChest; } + @Override + public Optional getAddon() { + // This is a plugin, not an addon + return Optional.empty(); + } + } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java index dddb3ed06..9a88e2cdf 100644 --- a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java +++ b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java @@ -282,4 +282,16 @@ public abstract class Addon implements AddonInterface { public Optional getAddonByName(String name) { return getBSkyBlock().getAddonsManager().getAddonByName(name); } + + public void log(String string) { + getBSkyBlock().log(string); + } + + public void logWarning(String string) { + getBSkyBlock().logWarning(string); + } + + public void logError(String string) { + getBSkyBlock().logError(string); + } } diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java b/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java index b2a3bf7fc..fa7c8142d 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/WorldSettings.java @@ -2,11 +2,14 @@ package us.tastybento.bskyblock.api.configuration; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.bukkit.GameMode; import org.bukkit.entity.EntityType; +import us.tastybento.bskyblock.api.addons.Addon; + /** * Contains world-specific settings. Only getters are required, but you may need setters for your own class. * @author tastybento @@ -156,30 +159,35 @@ public interface WorldSettings { * @return the onJoinResetMoney */ public boolean isOnJoinResetMoney(); - + /** * @return the onJoinResetInventory */ public boolean isOnJoinResetInventory(); - + /** * @return the onJoinResetEnderChest */ public boolean isOnJoinResetEnderChest(); - + /** * @return the onLeaveResetMoney */ public boolean isOnLeaveResetMoney(); - + /** * @return the onLeaveResetInventory */ public boolean isOnLeaveResetInventory(); - + /** * @return the onLeaveResetEnderChest */ public boolean isOnLeaveResetEnderChest(); + /** + * @return the Addon that registered this world + */ + public Optional getAddon(); + } diff --git a/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java b/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java index b92ea9c3b..d0b1a4f36 100644 --- a/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java +++ b/src/main/java/us/tastybento/bskyblock/api/localization/TextVariables.java @@ -5,7 +5,7 @@ package us.tastybento.bskyblock.api.localization; * @author Poslovitch */ public class TextVariables { - + private TextVariables() {} public static final String NAME = "[name]"; @@ -14,4 +14,5 @@ public class TextVariables { public static final String RANK = "[rank]"; public static final String LABEL = "[label]"; public static final String PERMISSION = "[permission]"; + public static final String SPAWN_HERE = "[spawn_here]"; } diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java index 9ab77ab03..e2137ea96 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminSchemCommand.java @@ -1,5 +1,6 @@ package us.tastybento.bskyblock.commands.admin; +import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -21,6 +22,7 @@ public class AdminSchemCommand extends CompositeCommand { super(parent, "schem"); } + @Override public void setup() { setPermission("admin.schem"); setParameters("commands.admin.schem.parameters"); @@ -29,13 +31,15 @@ public class AdminSchemCommand extends CompositeCommand { clipboards = new HashMap<>(); } + @Override @SuppressWarnings("deprecation") public boolean execute(User user, List args) { if (args.isEmpty()) { showHelp(this, user); return false; } - Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin())); + File schemFolder = new File(getIWM().getDataFolder(getWorld()), "schems"); + Clipboard cb = clipboards.getOrDefault(user.getUniqueId(), new Clipboard(getPlugin(), schemFolder)); if (args.get(0).equalsIgnoreCase("paste")) { if (cb.isFull()) { @@ -71,7 +75,7 @@ public class AdminSchemCommand extends CompositeCommand { if (b != null) { cb.setOrigin(b.getLocation()); user.getPlayer().sendBlockChange(b.getLocation(), Material.STAINED_GLASS,(byte)14); - Bukkit.getScheduler().runTaskLater(getPlugin(), + Bukkit.getScheduler().runTaskLater(getPlugin(), () -> user.getPlayer().sendBlockChange(b.getLocation(), b.getType(), b.getData()), 20L); user.sendMessage("general.success"); @@ -90,7 +94,15 @@ public class AdminSchemCommand extends CompositeCommand { if (args.get(0).equalsIgnoreCase("save")) { if (cb.isFull()) { if (args.size() == 2) { - return cb.save(user, args.get(1)); + // Check if file exists + File newFile = new File(schemFolder, args.get(1) + ".schem"); + if (newFile.exists()) { + user.sendMessage("commands.admin.schem.file-exists"); + this.askConfirmation(user, () -> cb.save(user, args.get(1))); + return false; + } else { + return cb.save(user, args.get(1)); + } } else { showHelp(this, user); return false; diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index 37c36667a..ab52bbebb 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -11,6 +11,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.World.Environment; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.util.Vector; @@ -101,7 +102,7 @@ public class Island implements DataObject { @Expose private int levelHandicap; @Expose - private Location spawnPoint; + private Map spawnPoint = new HashMap<>(); public Island() {} public Island(Location location, UUID owner, int protectionRange) { @@ -169,7 +170,7 @@ public class Island implements DataObject { return createdDate; } /** - * Gets the Island Guard flag's setting. If this is a protection flag, the this will be the + * 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 - flag @@ -288,10 +289,6 @@ public class Island implements DataObject { return members.getOrDefault(user.getUniqueId(), RanksManager.VISITOR_RANK); } - public Location getSpawnPoint() { - return spawnPoint; - } - /** * @param material - Material * @return count of how many tile entities of type mat are on the island at last count. Counts are done when a player places @@ -620,9 +617,21 @@ public class Island implements DataObject { //TODO default flags } - public void setSpawnPoint(Location location) { - spawnPoint = location; + /** + * Get the default spawn location for this island. Note that this may only be valid + * after the initial pasting because the player can change the island after that point + * @return the spawnPoint + */ + public Map getSpawnPoint() { + return spawnPoint; + } + /** + * Set when island is pasted + * @param spawnPoint the spawnPoint to set + */ + public void setSpawnPoint(Map spawnPoint) { + this.spawnPoint = spawnPoint; } @Override @@ -699,10 +708,10 @@ public class Island implements DataObject { members.forEach((u, i) -> { if (owner.equals(u)) { user.sendMessage("commands.admin.info.team-owner-format", "[name]", plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); } else if (i > RanksManager.VISITOR_RANK){ user.sendMessage("commands.admin.info.team-member-format", "[name]", plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); } }); } @@ -731,5 +740,23 @@ public class Island implements DataObject { } } + /** + * Set the spawn location for this island type + * @param islandType - island type + * @param l - location + */ + public void setSpawnPoint(Environment islandType, Location l) { + spawnPoint.put(islandType, l); + } + + /** + * Get the spawn point for this island type + * @param islandType - island type + * @return - location or null if one does not exist + */ + public Location getSpawnPoint(Environment islandType) { + return spawnPoint.get(islandType); + } + } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java index 740a970f9..d201a4b60 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/Clipboard.java @@ -9,14 +9,20 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Nameable; +import org.bukkit.World; import org.bukkit.block.Banner; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -28,7 +34,14 @@ import org.bukkit.block.banner.PatternType; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.ChestedHorse; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Tameable; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @@ -41,10 +54,13 @@ import org.bukkit.material.MaterialData; import org.bukkit.material.Openable; import org.bukkit.material.Redstone; import org.bukkit.material.Stairs; +import org.bukkit.util.Vector; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.localization.TextVariables; import us.tastybento.bskyblock.api.user.User; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.util.Util; public class Clipboard { @@ -76,14 +92,15 @@ public class Clipboard { private File schemFolder; - public Clipboard(BSkyBlock plugin) { + public Clipboard(BSkyBlock plugin, File schemFolder) { super(); this.plugin = plugin; - schemFolder = new File(plugin.getDataFolder(), "schems"); if (!schemFolder.exists()) { schemFolder.mkdirs(); } + this.schemFolder = schemFolder; } + /** * @return the pos1 */ @@ -133,8 +150,11 @@ public class Clipboard { user.sendMessage("commands.admin.schem.need-pos1-pos2"); return false; } + // World + World world = pos1.getWorld(); // Clear the clipboard blockConfig = new YamlConfiguration(); + int count = 0; int minX = Math.max(pos1.getBlockX(),pos2.getBlockX()); int maxX = Math.min(pos1.getBlockX(), pos2.getBlockX()); @@ -142,11 +162,15 @@ public class Clipboard { int maxY = Math.min(pos1.getBlockY(), pos2.getBlockY()); int minZ = Math.max(pos1.getBlockZ(),pos2.getBlockZ()); int maxZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); + for (int x = Math.min(pos1.getBlockX(), pos2.getBlockX()); x <= Math.max(pos1.getBlockX(),pos2.getBlockX()); x++) { for (int y = Math.min(pos1.getBlockY(), pos2.getBlockY()); y <= Math.max(pos1.getBlockY(),pos2.getBlockY()); y++) { for (int z = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); z <= Math.max(pos1.getBlockZ(),pos2.getBlockZ()); z++) { - Block block = pos1.getWorld().getBlockAt(x, y, z); - if (copyBlock(block, origin == null ? user.getLocation() : origin, copyAir)) { + Block block = world.getBlockAt(x, y, z); + if (copyBlock(block, origin == null ? user.getLocation() : origin, copyAir, world.getLivingEntities().stream() + .filter(Objects::nonNull) + .filter(e -> !(e instanceof Player) && e.getLocation().getBlock().equals(block)) + .collect(Collectors.toList()))) { minX = Math.min(minX, x); maxX = Math.max(maxX, x); minY = Math.min(minY, y); @@ -167,137 +191,227 @@ public class Clipboard { } /** - * Pastes the clipboard to location - * @param location - location to paste + * Pastes the clipboard to island location + * @param world - world in which to paste + * @param island - location to paste + * @param task - task to run after pasting */ - public void paste(Location location) { - blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location, blockConfig.getConfigurationSection(BLOCK + "." + b))); + public void paste(World world, Island island, Runnable task) { + // Offset due to bedrock + Vector off = new Vector(0,0,0); + if (blockConfig.contains("bedrock")) { + String[] offset = blockConfig.getString("bedrock").split(","); + off = new Vector(Integer.valueOf(offset[0]), Integer.valueOf(offset[1]), Integer.valueOf(offset[2])); + } + // Calculate location for pasting + Location loc = island.getCenter().toVector().subtract(off).toLocation(world); + // Paste + blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(world, island, loc, blockConfig.getConfigurationSection(BLOCK + "." + b))); + // Run follow on task if it exists + if (task != null) { + Bukkit.getScheduler().runTaskLater(plugin, task, 2L); + } } - private void pasteBlock(Location location, ConfigurationSection s) { - String[] pos = s.getName().split(","); + /** + * Paste clipboard at this location + * @param location + */ + public void paste(Location location) { + blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location.getWorld(), null, location, blockConfig.getConfigurationSection(BLOCK + "." + b))); + + } + + private void writeSign(Island island, Block block, List lines) { + Sign sign = (Sign) block.getState(); + org.bukkit.material.Sign s = (org.bukkit.material.Sign) sign.getData(); + // Handle spawn sign + if (island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { + block.setType(Material.AIR); + // Orient to face same direction as sign + Location spawnPoint = new Location(block.getWorld(), block.getX() + 0.5D, block.getY(), + block.getZ() + 0.5D, Util.blockFaceToFloat(s.getFacing().getOppositeFace()), 30F); + island.setSpawnPoint(block.getWorld().getEnvironment(), spawnPoint); + return; + } + String name = TextVariables.NAME; + if (island != null) { + name = plugin.getPlayers().getName(island.getOwner()); + } + // Sub in player's name + for (int i = 0 ; i < lines.size(); i++) { + sign.setLine(i, lines.get(i).replace(TextVariables.NAME, name)); + } + sign.update(); + } + + + private void pasteBlock(World world, Island island, Location location, ConfigurationSection config) { + String[] pos = config.getName().split(","); int x = location.getBlockX() + Integer.valueOf(pos[0]); int y = location.getBlockY() + Integer.valueOf(pos[1]); int z = location.getBlockZ() + Integer.valueOf(pos[2]); - Material m = Material.getMaterial(s.getString("type")); - Block block = location.getWorld().getBlockAt(x, y, z); - if (s.getBoolean(ATTACHED)) { - plugin.log("Setting 1 tick later for " + m.toString()); - plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(block, s, m)); + // Default type is air + Material material = Material.getMaterial(config.getString("type", "AIR")); + Block block = world.getBlockAt(x, y, z); + if (config.getBoolean(ATTACHED)) { + plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(island, block, config, material)); } else { - setBlock(block, s, m); + setBlock(island, block, config, material); } } @SuppressWarnings("deprecation") - private void setBlock(Block block, ConfigurationSection s, Material m) { + private void setBlock(Island island, Block block, ConfigurationSection config, Material material) { // Block state - if (s.getBoolean(ATTACHED) && m.toString().contains("TORCH")) { - TorchDir d = TorchDir.valueOf(s.getString(FACING)); - + if (config.getBoolean(ATTACHED) && material.toString().contains("TORCH")) { + TorchDir d = TorchDir.valueOf(config.getString(FACING)); + // The block below has to be set to something solid for this to work Block rel = block.getRelative(BlockFace.DOWN); Material rm = rel.getType(); Byte data = rel.getData(); - if (rel.isEmpty() || rel.isLiquid()) { rel.setType(Material.STONE); - block.setType(m); + block.setType(material); block.setData((byte)d.ordinal()); // Set the block back to what it was rel.setType(rm); rel.setData(data); } else { - block.setType(m); + block.setType(material); block.setData((byte)d.ordinal()); } return; } - - block.setType(m, false); - - BlockState bs = block.getState(); - - byte data = (byte)s.getInt("data"); + // Set the block type + block.setType(material, false); + // Set the block data + byte data = (byte)config.getInt("data"); block.setData(data); - + // Get the block state + BlockState bs = block.getState(); // Material Data MaterialData md = bs.getData(); if (md instanceof Openable) { Openable open = (Openable)md; - open.setOpen(s.getBoolean("open")); + open.setOpen(config.getBoolean("open")); } if (md instanceof Directional) { Directional facing = (Directional)md; if (md instanceof Stairs) { - facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + Stairs stairs = (Stairs)md; + stairs.setInverted(config.getBoolean("inverted")); + stairs.setFacingDirection(BlockFace.valueOf(config.getString(FACING, "NORTH"))); } else { - facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING))); + facing.setFacingDirection(BlockFace.valueOf(config.getString(FACING, "NORTH"))); } } if (md instanceof Lever) { Lever r = (Lever)md; - r.setPowered(s.getBoolean(POWERED)); + r.setPowered(config.getBoolean(POWERED)); } if (md instanceof Button) { Button r = (Button)md; - r.setPowered(s.getBoolean(POWERED)); + r.setPowered(config.getBoolean(POWERED)); } // Block data + // Signs if (bs instanceof Sign) { - Sign sign = (Sign)bs; - List lines = s.getStringList("lines"); - for (int i =0 ; i < lines.size(); i++) { - sign.setLine(i, lines.get(i)); - } - sign.update(); + List lines = config.getStringList("lines"); + writeSign(island, block, lines); } + // Banners if (bs instanceof Banner) { Banner banner = (Banner)bs; - DyeColor baseColor = DyeColor.valueOf(s.getString("baseColor")); + DyeColor baseColor = DyeColor.valueOf(config.getString("baseColor", "RED")); banner.setBaseColor(baseColor); int i = 0; - ConfigurationSection pat = s.getConfigurationSection("pattern"); + ConfigurationSection pat = config.getConfigurationSection("pattern"); if (pat != null) { for (String pattern : pat.getKeys(false)) { - banner.setPattern(i, new Pattern(DyeColor.valueOf(pat.getString(pattern)) + banner.setPattern(i, new Pattern(DyeColor.valueOf(pat.getString(pattern, "GREEN")) , PatternType.valueOf(pattern))); i++; } } + bs.update(true, false); } + // Mob spawners if (bs instanceof CreatureSpawner) { CreatureSpawner spawner = ((CreatureSpawner) bs); - spawner.setSpawnedType(EntityType.valueOf(s.getString("spawnedType", "PIG"))); - spawner.setMaxNearbyEntities(s.getInt("maxNearbyEntities", 16)); - spawner.setMaxSpawnDelay(s.getInt("maxSpawnDelay", 2*60*20)); - spawner.setMinSpawnDelay(s.getInt("minSpawnDelay", 5*20)); - - spawner.setDelay(s.getInt("delay", -1)); - spawner.setRequiredPlayerRange(s.getInt("requiredPlayerRange", 16)); - spawner.setSpawnRange(s.getInt("spawnRange", 4)); + spawner.setSpawnedType(EntityType.valueOf(config.getString("spawnedType", "PIG"))); + spawner.setMaxNearbyEntities(config.getInt("maxNearbyEntities", 16)); + spawner.setMaxSpawnDelay(config.getInt("maxSpawnDelay", 2*60*20)); + spawner.setMinSpawnDelay(config.getInt("minSpawnDelay", 5*20)); + spawner.setDelay(config.getInt("delay", -1)); + spawner.setRequiredPlayerRange(config.getInt("requiredPlayerRange", 16)); + spawner.setSpawnRange(config.getInt("spawnRange", 4)); + bs.update(true, false); } - - - bs.update(true, false); - + // Chests, in general if (bs instanceof InventoryHolder) { + bs.update(true, false); Inventory ih = ((InventoryHolder)bs).getInventory(); - ConfigurationSection inv = s.getConfigurationSection("inventory"); - inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + if (config.isConfigurationSection("inventory")) { + ConfigurationSection inv = config.getConfigurationSection("inventory"); + inv.getKeys(false).forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + } } + // Entities + if (config.isConfigurationSection("entity")) { + ConfigurationSection en = config.getConfigurationSection("entity"); + en.getKeys(false).forEach(k -> { + ConfigurationSection ent = en.getConfigurationSection(k); + Location center = block.getLocation().add(new Vector(0.5, 0.0, 0.5)); + LivingEntity e = (LivingEntity)block.getWorld().spawnEntity(center, EntityType.valueOf(ent.getString("type", "PIG"))); + if (e instanceof Nameable) { + e.setCustomName(ent.getString("name")); + } + if (e instanceof Colorable) { + if (ent.contains("color")) { + ((Colorable) e).setColor(DyeColor.valueOf(ent.getString("color"))); + } + } + if (e instanceof Tameable) { + ((Tameable)e).setTamed(ent.getBoolean("tamed")); + } + if (e instanceof ChestedHorse) { + ((ChestedHorse)e).setCarryingChest(ent.getBoolean("chest")); + } + if (e instanceof Ageable) { + if (ent.getBoolean("adult")) { + ((Ageable)e).setAdult(); + } else { + ((Ageable)e).setBaby(); + } + } + if (e instanceof AbstractHorse) { + AbstractHorse horse = (AbstractHorse)e; + horse.setDomestication(ent.getInt("domestication")); + ConfigurationSection inv = ent.getConfigurationSection("inventory"); + inv.getKeys(false).forEach(i -> horse.getInventory().setItem(Integer.valueOf(i), (ItemStack)inv.get(i))); + } + + if (e instanceof AbstractHorse) { + Horse horse = (Horse)e; + horse.setStyle(Horse.Style.valueOf(ent.getString("style", "NONE"))); + } + }); + } } @SuppressWarnings("deprecation") - private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir) { - if (!copyAir && block.getType().equals(Material.AIR)) { + private boolean copyBlock(Block block, Location copyOrigin, boolean copyAir, Collection entities) { + if (!copyAir && block.getType().equals(Material.AIR) && entities.isEmpty()) { return false; } // Create position @@ -308,11 +422,57 @@ public class Clipboard { // Position defines the section ConfigurationSection s = blockConfig.createSection(BLOCK + "." + pos); + + // Set entities + for (LivingEntity e: entities) { + ConfigurationSection en = s.createSection("entity." + e.getUniqueId()); + en.set("type", e.getType().name()); + if (e instanceof Nameable) { + en.set("name", e.getCustomName()); + } + if (e instanceof Colorable) { + Colorable c = (Colorable)e; + en.set("color", c.getColor().name()); + } + if (e instanceof Tameable && ((Tameable)e).isTamed()) { + en.set("tamed", true); + } + if (e instanceof ChestedHorse && ((ChestedHorse)e).isCarryingChest()) { + en.set("chest", true); + } + if (e instanceof Ageable) { + en.set("adult", ((Ageable)e).isAdult()); + } + if (e instanceof AbstractHorse) { + AbstractHorse horse = (AbstractHorse)e; + en.set("domestication", horse.getDomestication()); + for (int index = 0; index < horse.getInventory().getSize(); index++) { + ItemStack i = horse.getInventory().getItem(index); + if (i != null) { + en.set("inventory." + index, i); + } + } + } + + if (e instanceof Horse) { + Horse horse = (Horse)e; + en.set("style", horse.getStyle().name()); + } + } + + // Return if this is just air block + if (!copyAir && block.getType().equals(Material.AIR) && !entities.isEmpty()) { + return true; + } + // Set the block type s.set("type", block.getType().toString()); if (block.getData() != 0) { s.set("data", block.getData()); } + if (block.getType().equals(Material.BEDROCK)) { + blockConfig.set("bedrock", x + "," + y + "," + z); + } // Block state BlockState bs = block.getState(); @@ -324,8 +484,15 @@ public class Clipboard { s.set("open", open.isOpen()); } if (md instanceof Directional) { - Directional facing = (Directional)md; - s.set(FACING, facing.getFacing().name()); + if (md instanceof Stairs) { + //facing.setFacingDirection(BlockFace.valueOf(s.getString(FACING)).getOppositeFace()); + Stairs stairs = (Stairs)md; + s.set("inverted", stairs.isInverted()); + s.set(FACING, stairs.getAscendingDirection().name()); + } else { + Directional facing = (Directional)md; + s.set(FACING, facing.getFacing().name()); + } } if (md instanceof Attachable) { Attachable facing = (Attachable)md; @@ -493,11 +660,11 @@ public class Clipboard { /** * Save the clipboard to a file * @param user - user who is copying - * @param string - filename + * @param newFile - filename * @return - true if successful, false if error */ - public boolean save(User user, String string) { - File file = new File(schemFolder, string); + public boolean save(User user, String newFile) { + File file = new File(schemFolder, newFile); try { getBlockConfig().save(file); } catch (IOException e) { @@ -515,4 +682,6 @@ public class Clipboard { user.sendMessage("general.success"); return true; } + + } diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java deleted file mode 100644 index 548d727e1..000000000 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java +++ /dev/null @@ -1,487 +0,0 @@ -package us.tastybento.bskyblock.island.builders; - -import java.util.List; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.TreeType; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Chest; - -import us.tastybento.bskyblock.Constants; -import us.tastybento.bskyblock.Constants.GameType; -import us.tastybento.bskyblock.api.localization.TextVariables; -import us.tastybento.bskyblock.api.user.User; -import us.tastybento.bskyblock.database.objects.Island; - -/** - * Fired when a team event happens. - * - * @author tastybento - * @since 1.0 - */ -public class IslandBuilder { - - public enum IslandType { - ISLAND, - NETHER, - END - } - - private Island island; - private World world; - private IslandType type = IslandType.ISLAND; - private List chestItems; - private UUID playerUUID; - private String playerName; - - //TODO support companions? - - public IslandBuilder(Island island) { - this.island = island; - world = island.getWorld(); - } - - /** - * @param type the type to set - */ - public IslandBuilder setType(IslandType type) { - this.type = type; - return this; - } - - /** - * @param player - the player the player to set - */ - public IslandBuilder setPlayer(Player player) { - playerUUID = player.getUniqueId(); - playerName = player.getName(); - return this; - } - - /** - * @param list the default chestItems to set - */ - public IslandBuilder setChestItems(List list) { - chestItems = list; - return this; - } - - public void build() { - // Switch on island type - switch (type) { - case ISLAND: - world = island.getWorld(); - if (Constants.GAMETYPE == GameType.ACIDISLAND) { - generateAcidIslandBlocks(); - } else { - generateIslandBlocks(); - } - break; - case NETHER: - world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); - if (world == null) { - return; - } - generateNetherBlocks(); - break; - case END: - world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); - if (world == null) { - return; - } - generateEndBlocks(); - break; - } - // Do other stuff - } - - /** - * Creates the AcidIsland default island block by block - */ - private void generateAcidIslandBlocks() { - // AcidIsland - // Build island layer by layer - // Start from the base - // half sandstone; half sand - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y = 0; - for (int x_space = x - 4; x_space <= x + 4; x_space++) { - for (int z_space = z - 4; z_space <= z + 4; z_space++) { - Block b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.BEDROCK); - } - } - for (y = 1; y < islandHeight + 5; y++) { - for (int x_space = x - 4; x_space <= x + 4; x_space++) { - for (int z_space = z - 4; z_space <= z + 4; z_space++) { - Block b = world.getBlockAt(x_space, y, z_space); - if (y < (islandHeight / 2)) { - b.setType(Material.SANDSTONE); - } else { - b.setType(Material.SAND); - } - } - } - } - // Then cut off the corners to make it round-ish - for (y = 0; y < islandHeight + 5; y++) { - for (int x_space = x - 4; x_space <= x + 4; x_space += 8) { - for (int z_space = z - 4; z_space <= z + 4; z_space += 8) { - Block b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.STATIONARY_WATER); - } - } - } - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - Block blockToChange = world.getBlockAt(x_space, y, z_space); - blockToChange.setType(Material.GRASS); - } - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.DIRT); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.DIRT); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.DIRT); - - // Add island items - y = islandHeight; - // Add tree (natural) - Location treeLoc = new Location(world, x, y + 5D, z); - world.generateTree(treeLoc, TreeType.ACACIA); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we - // know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateIslandBlocks() { - // Skyblock - // Build island layer by layer - // Start from the base - // half sandstone; half sand - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - World world = island.getCenter().getWorld(); - int y; - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.GRASS); - } - } - } - - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.DIRT); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.DIRT); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.DIRT); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.DIRT); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.DIRT); - - // Add island items - y = islandHeight; - // Add tree (natural) - Location treeLoc = new Location(world, x, y + 5D, z); - world.generateTree(treeLoc, TreeType.TREE); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we - // know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateNetherBlocks() { - // Nether block - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y; - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.NETHER_BRICK); - } - } - } - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.NETHERRACK); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.SOUL_SAND); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.SOUL_SAND); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.GRAVEL); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.QUARTZ_ORE); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.QUARTZ_ORE); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.MAGMA); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.MAGMA); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.MAGMA); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.MAGMA); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void generateEndBlocks() { - // Nether block - int x = island.getCenter().getBlockX(); - int z = island.getCenter().getBlockZ(); - int islandHeight = island.getCenter().getBlockY(); - - int y; - // Add some grass - for (y = islandHeight + 4; y < islandHeight + 5; y++) { - for (int x_space = x - 3; x_space <= x + 3; x_space++) { - for (int z_space = z - 3; z_space <= z + 3; z_space++) { - world.getBlockAt(x_space, y, z_space).setType(Material.END_BRICKS); - } - } - } - // Then cut off the corners to make it round-ish - for (int x_space = x - 3; x_space <= x + 3; x_space += 6) { - for (int z_space = z - 3; z_space <= z + 3; z_space += 6) { - world.getBlockAt(x_space, y-1, z_space).setType(Material.AIR); - } - } - // Place bedrock - MUST be there (ensures island are not - // overwritten - Block b = world.getBlockAt(x, islandHeight, z); - b.setType(Material.BEDROCK); - // Then add some more dirt in the classic shape - y = islandHeight + 3; - for (int x_space = x - 2; x_space <= x + 2; x_space++) { - for (int z_space = z - 2; z_space <= z + 2; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.ENDER_STONE); - } - } - b = world.getBlockAt(x - 3, y, z); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x + 3, y, z); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x, y, z - 3); - b.setType(Material.OBSIDIAN); - b = world.getBlockAt(x, y, z + 3); - b.setType(Material.OBSIDIAN); - y = islandHeight + 2; - for (int x_space = x - 1; x_space <= x + 1; x_space++) { - for (int z_space = z - 1; z_space <= z + 1; z_space++) { - b = world.getBlockAt(x_space, y, z_space); - b.setType(Material.ENDER_STONE); - } - } - b = world.getBlockAt(x - 2, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x + 2, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z - 2); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z + 2); - b.setType(Material.ENDER_STONE); - y = islandHeight + 1; - b = world.getBlockAt(x - 1, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x + 1, y, z); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z - 1); - b.setType(Material.ENDER_STONE); - b = world.getBlockAt(x, y, z + 1); - b.setType(Material.ENDER_STONE); - - // Add island items - y = islandHeight; - // Spawn an ender crystal - world.spawnEntity(new Location(world, x, y + 5D, z), EntityType.ENDER_CRYSTAL); - - // Place a helpful sign in front of player - placeSign(x, islandHeight + 5, z + 3); - // Place the chest - no need to use the safe spawn function - // because we know what this island looks like - placeChest(x, islandHeight + 5, z + 1); - } - - private void placeSign(int x, int y, int z) { - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.SIGN_POST); - if (playerUUID != null) { - Sign sign = (Sign) blockToChange.getState(); - User user = User.getInstance(playerUUID); - - // Sets the lines of the sign - sign.setLine(0, user.getTranslation("new-island.sign.line0", TextVariables.NAME, playerName)); - sign.setLine(1, user.getTranslation("new-island.sign.line1", TextVariables.NAME, playerName)); - sign.setLine(2, user.getTranslation("new-island.sign.line2", TextVariables.NAME, playerName)); - sign.setLine(3, user.getTranslation("new-island.sign.line3", TextVariables.NAME, playerName)); - - ((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH); - sign.update(); - } - } - - private void placeChest(int x, int y, int z) { - // Fill the chest and orient it correctly - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.CHEST); - BlockState state = blockToChange.getState(); - Chest chest = new Chest(BlockFace.SOUTH); - state.setData(chest); - state.update(); - if (!chestItems.isEmpty()) { - InventoryHolder chestBlock = (InventoryHolder) state; - for (ItemStack item: chestItems) { - chestBlock.getInventory().addItem(item); - } - } - } -} - - diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java deleted file mode 100644 index 626a32ad2..000000000 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilderNew.java +++ /dev/null @@ -1,196 +0,0 @@ -package us.tastybento.bskyblock.island.builders; - -import java.io.File; -import java.io.IOException; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.entity.Player; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Chest; - -import us.tastybento.bskyblock.BSkyBlock; -import us.tastybento.bskyblock.api.localization.TextVariables; -import us.tastybento.bskyblock.api.user.User; -import us.tastybento.bskyblock.database.objects.Island; - -/** - * Generates islands - * - * @author tastybento - * @since 1.0 - */ -public class IslandBuilderNew { - - public enum IslandType { - ISLAND, - NETHER, - END - } - - private Island island; - private World world; - private IslandType type = IslandType.ISLAND; - private List chestItems; - private UUID playerUUID; - private String playerName; - private BSkyBlock plugin; - private Map islandSchems = new EnumMap<>(IslandType.class); - - //TODO support companions? - - public IslandBuilderNew(BSkyBlock plugin, Island island) { - this.plugin = plugin; - this.island = island; - world = island.getWorld(); - loadIslands(); - } - - private void loadIslands() { - File schems = new File(plugin.getDataFolder(), "schems"); - if (!schems.exists()) { - if (!schems.mkdirs()) { - plugin.logError("Could not make schems folder!"); - } else { - copySchems(schems); - } - } - - try { - Clipboard cb = new Clipboard(plugin); - cb.load("island"); - islandSchems.put(IslandType.ISLAND, cb); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default island"); - } - if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands()) { - try { - Clipboard cbn = new Clipboard(plugin); - cbn.load("nether-island"); - islandSchems.put(IslandType.NETHER, cbn); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default nether island"); - } - } - if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands()) { - try { - Clipboard cbe = new Clipboard(plugin); - cbe.load("end-island"); - islandSchems.put(IslandType.END, cbe); - } catch (IOException | InvalidConfigurationException e) { - plugin.logError("Could not load default end island"); - } - } - plugin.log("Loaded " + islandSchems.size() + " islands"); - } - - /** - * Copies schems from the jar file - * @param schems2 - file containing schem - */ - private void copySchems(File schems2) { - plugin.saveResource("schems/island.schem", false); - plugin.saveResource("schems/nether-island.schem", false); - plugin.saveResource("schems/end-island.schem", false); - } - - /** - * @param type the type to set - */ - public IslandBuilderNew setType(IslandType type) { - this.type = type; - return this; - } - - /** - * @param player - the player the player to set - */ - public IslandBuilderNew setPlayer(Player player) { - playerUUID = player.getUniqueId(); - playerName = player.getName(); - return this; - } - - /** - * @param list the default chestItems to set - */ - public IslandBuilderNew setChestItems(List list) { - chestItems = list; - return this; - } - - public void build() { - plugin.log("Pasting island to " + type); - Location loc = island.getCenter(); - // Switch on island type - switch (type) { - case NETHER: - world = Bukkit.getWorld(island.getWorld().getName() + "_nether"); - if (world == null) { - return; - } - loc = island.getCenter().toVector().toLocation(world); - break; - case END: - world = Bukkit.getWorld(island.getWorld().getName() + "_the_end"); - if (world == null) { - return; - } - loc = island.getCenter().toVector().toLocation(world); - break; - default: - break; - } - plugin.log("Pasting island to " + loc); - islandSchems.get(type).paste(loc); - // Do other stuff - } - - private void placeSign(int x, int y, int z) { - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.SIGN_POST); - if (playerUUID != null) { - Sign sign = (Sign) blockToChange.getState(); - User user = User.getInstance(playerUUID); - - // Sets the lines of the sign - sign.setLine(0, user.getTranslation("new-island.sign.line0", TextVariables.NAME, playerName)); - sign.setLine(1, user.getTranslation("new-island.sign.line1", TextVariables.NAME, playerName)); - sign.setLine(2, user.getTranslation("new-island.sign.line2", TextVariables.NAME, playerName)); - sign.setLine(3, user.getTranslation("new-island.sign.line3", TextVariables.NAME, playerName)); - - ((org.bukkit.material.Sign) sign.getData()).setFacingDirection(BlockFace.NORTH); - sign.update(); - } - } - - private void placeChest(int x, int y, int z) { - // Fill the chest and orient it correctly - Block blockToChange = world.getBlockAt(x, y, z); - blockToChange.setType(Material.CHEST); - BlockState state = blockToChange.getState(); - Chest chest = new Chest(BlockFace.SOUTH); - state.setData(chest); - state.update(); - if (!chestItems.isEmpty()) { - InventoryHolder chestBlock = (InventoryHolder) state; - for (ItemStack item: chestItems) { - chestBlock.getInventory().addItem(item); - } - } - } -} - - diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java index 04a73ecbf..938c1a82d 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandWorldManager.java @@ -1,8 +1,10 @@ package us.tastybento.bskyblock.managers; +import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -16,6 +18,7 @@ import org.bukkit.WorldType; import org.bukkit.entity.EntityType; import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.configuration.WorldSettings; import us.tastybento.bskyblock.api.flags.Flag; import us.tastybento.bskyblock.api.user.User; @@ -495,42 +498,42 @@ public class IslandWorldManager { public Set getRemoveMobsWhitelist(World world) { return worldSettings.get(Util.getWorld(world)).getRemoveMobsWhitelist(); } - + /** * @return the onJoinResetMoney */ public boolean isOnJoinResetMoney(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetMoney(); } - + /** * @return the onJoinResetInventory */ public boolean isOnJoinResetInventory(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetInventory(); } - + /** * @return the onJoinResetEnderChest */ public boolean isOnJoinResetEnderChest(World world) { return worldSettings.get(Util.getWorld(world)).isOnJoinResetEnderChest(); } - + /** * @return the onLeaveResetMoney */ public boolean isOnLeaveResetMoney(World world) { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetMoney(); } - + /** * @return the onLeaveResetInventory */ public boolean isOnLeaveResetInventory(World world) { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetInventory(); } - + /** * @return the onLeaveResetEnderChest */ @@ -538,4 +541,21 @@ public class IslandWorldManager { return worldSettings.get(Util.getWorld(world)).isOnLeaveResetEnderChest(); } + /** + * The data folder for the addon that registered this world, or the plugin's data folder if none found + * @return + */ + public File getDataFolder(World world) { + return worldSettings.get(Util.getWorld(world)).getAddon().map(Addon::getDataFolder).orElse(plugin.getDataFolder()); + } + + /** + * Get the addon associated with this world set + * @param world - world + * @return Addon, or empty + */ + public Optional getAddon(World world) { + return worldSettings.get(Util.getWorld(world)).getAddon(); + } + } diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java index 626de2ba6..b8996b3ec 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java @@ -348,6 +348,7 @@ public class IslandsManager { public Location getSafeHomeLocation(World world, User user, int number) { // Try the numbered home location first Location l = plugin.getPlayers().getHomeLocation(world, user, number); + if (l == null) { // Get the default home, which may be null too, but that's okay number = 1; @@ -433,7 +434,7 @@ public class IslandsManager { * @return the spawnPoint or null if spawn does not exist */ public Location getSpawnPoint(World world) { - return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint() : null; + return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint(world.getEnvironment()) : null; } /** @@ -480,7 +481,7 @@ public class IslandsManager { /** * Teleport player to a home location. If one cannot be found a search is done to * find a safe place. - * + * * @param world - world to check * @param player - the player * @param number - a number - home location to do to @@ -504,7 +505,7 @@ public class IslandsManager { /** * Teleport player to a home location. If one cannot be found a search is done to * find a safe place. - * + * * @param world - world to check * @param player - the player * @param number - a number - home location to do to @@ -548,7 +549,7 @@ public class IslandsManager { // If this is a new island, then run commands and do resets if (newIsland) { // TODO add command running - + // Remove money inventory etc. if (plugin.getIWM().isOnJoinResetEnderChest(world)) { user.getPlayer().getEnderChest().clear(); @@ -723,7 +724,7 @@ public class IslandsManager { // Move player to spawn if (spawn.containsKey(island.getWorld())) { // go to island spawn - player.teleport(spawn.get(island.getWorld()).getSpawnPoint()); + player.teleport(spawn.get(island.getWorld()).getSpawnPoint(island.getWorld().getEnvironment())); } else { if (!player.performCommand(Constants.SPAWNCOMMAND)) { plugin.logWarning("During island deletion player " + player.getName() + " could not be sent to spawn so was dropped, sorry."); diff --git a/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java new file mode 100644 index 000000000..feb32bf92 --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/managers/SchemsManager.java @@ -0,0 +1,114 @@ +package us.tastybento.bskyblock.managers; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.bukkit.World; +import org.bukkit.configuration.InvalidConfigurationException; + +import us.tastybento.bskyblock.BSkyBlock; +import us.tastybento.bskyblock.api.addons.Addon; +import us.tastybento.bskyblock.database.objects.Island; +import us.tastybento.bskyblock.island.builders.Clipboard; + +public class SchemsManager { + + private BSkyBlock plugin; + private Map islandSchems; + + /** + * @param plugin + */ + public SchemsManager(BSkyBlock plugin) { + this.plugin = plugin; + islandSchems = new HashMap<>(); + } + + private void copySchems(File schems, World world, String name) { + if (!schems.exists() && !schems.mkdirs()) { + plugin.logError("Could not make schems folder!"); + return; + } + + Optional addon = plugin.getIWM().getAddon(world); + if (addon.isPresent()) { + addon.get().saveResource("schems/" + name + ".schem", false); + } else { + plugin.saveResource("schems/" + name + ".schem", false); + } + } + + public Clipboard get(World world) { + return islandSchems.get(world); + } + + /** + * Load schems for world. Will try and load nether and end schems too if settings are set. + * @param world - world + */ + public void loadIslands(World world) { + if (plugin.getSchemsManager().loadSchem(world, "island")) { + plugin.log("Loaded island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load island for " + plugin.getIWM().getFriendlyName(world)); + } + if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world)) { + + if (plugin.getSchemsManager().loadSchem(plugin.getIWM().getNetherWorld(world), "nether-island")) { + plugin.log("Loaded nether island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load nether island for " + plugin.getIWM().getFriendlyName(world)); + } + } + if (plugin.getIWM().isEndGenerate(world) && plugin.getIWM().isEndIslands(world)) { + if (plugin.getSchemsManager().loadSchem(plugin.getIWM().getEndWorld(world), "end-island")) { + plugin.log("Loaded end island for " + plugin.getIWM().getFriendlyName(world)); + } else { + plugin.logError("Could not load end island for " + plugin.getIWM().getFriendlyName(world)); + } + } + + + } + + private boolean loadSchem(World world, String name) { + File schems = new File(plugin.getIWM().getDataFolder(world), "schems"); + copySchems(schems, world, name); + try { + Clipboard cb = new Clipboard(plugin, schems); + cb.load(name); + islandSchems.put(world, cb); + } catch (IOException | InvalidConfigurationException e) { + plugin.logError("Could not load " + name + " schem"); + e.printStackTrace(); + return false; + } + return true; + } + + /** + * Paste the schem for world to the island center location and run task afterwards + * @param world - world to paste to + * @param island - the island who owns this schem + * @param task - task to run after pasting is completed + */ + public void paste(World world, Island island, Runnable task) { + if (islandSchems.containsKey(world)) { + islandSchems.get(world).paste(world, island, task); + } + } + + /** + * Paste the schem to world for island + * @param world + * @param island + */ + public void paste(World world, Island island) { + paste(world, island, null); + + } + +} diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java index 2f1953b5d..8a396f177 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/NewIsland.java @@ -4,6 +4,7 @@ import java.io.IOException; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.World.Environment; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.events.IslandBaseEvent; @@ -11,7 +12,6 @@ import us.tastybento.bskyblock.api.events.island.IslandEvent; import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; -import us.tastybento.bskyblock.island.builders.IslandBuilderNew; /** * Create and paste a new island @@ -117,40 +117,48 @@ public class NewIsland { .island(island) .location(island.getCenter()) .build(); - if (!event.isCancelled()) { - // Create island - IslandBuilderNew ib = new IslandBuilderNew(plugin, island) - .setPlayer(user.getPlayer()) - .setChestItems(plugin.getSettings().getChestItems()) - .setType(IslandBuilderNew.IslandType.ISLAND); - ib.build(); - if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { - ib.setType(IslandBuilderNew.IslandType.NETHER).build(); - } - if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { - ib.setType(IslandBuilderNew.IslandType.END).build(); - } - // Teleport player to their island - plugin.getIslands().homeTeleport(world, user.getPlayer(), true); - // Fire exit event - Reason reasonDone = Reason.CREATED; - switch (reason) { - case CREATE: - reasonDone = Reason.CREATED; - break; - case RESET: - reasonDone = Reason.RESETTED; - break; - default: - break; - } - IslandEvent.builder() - .involvedPlayer(user.getUniqueId()) - .reason(reasonDone) - .island(island) - .location(island.getCenter()) - .build(); + if (event.isCancelled()) { + return; } + // Create island + plugin.getSchemsManager().paste(world, island, () -> { + // Set initial spawn point if one exists + if (island.getSpawnPoint(Environment.NORMAL) != null) { + plugin.getPlayers().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL), 1); + } + // Teleport player after this island is built + plugin.getIslands().homeTeleport(world, user.getPlayer(), true); + }); + + // Make nether island + if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIWM().getNetherWorld() != null) { + plugin.getSchemsManager().paste(plugin.getIWM().getNetherWorld(world), island); + } + + // Make end island + if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIWM().getEndWorld() != null) { + plugin.getSchemsManager().paste(plugin.getIWM().getEndWorld(world), island); + } + + // Fire exit event + Reason reasonDone = Reason.CREATED; + switch (reason) { + case CREATE: + reasonDone = Reason.CREATED; + break; + case RESET: + reasonDone = Reason.RESETTED; + break; + default: + break; + } + IslandEvent.builder() + .involvedPlayer(user.getUniqueId()) + .reason(reasonDone) + .island(island) + .location(island.getCenter()) + .build(); + } /** diff --git a/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java b/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java index 1cc2a9c0e..e725fa695 100644 --- a/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java +++ b/src/main/java/us/tastybento/bskyblock/panels/LanguagePanel.java @@ -2,6 +2,8 @@ package us.tastybento.bskyblock.panels; import java.util.Locale; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder; @@ -23,8 +25,16 @@ public class LanguagePanel { .name(user.getTranslation("language.panel-title")); for (Locale locale : BSkyBlock.getInstance().getLocalesManager().getAvailableLocales(true)) { - PanelItemBuilder localeIcon = new PanelItemBuilder().icon(BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner()) - .name(fancyLocaleDisplayName(user, locale)) + PanelItemBuilder localeIcon = new PanelItemBuilder(); + + ItemStack localeBanner = BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner(); + if (localeBanner != null) { + localeIcon.icon(localeBanner); + } else { + localeIcon.icon(new ItemStack(Material.BANNER, 1)); // Set to a blank banner. + } + + localeIcon.name(fancyLocaleDisplayName(user, locale)) .clickHandler((panel, u, click, slot) -> { BSkyBlock.getInstance().getPlayers().setLocale(u.getUniqueId(), locale.toLanguageTag()); u.sendMessage("language.edited", "[lang]", fancyLocaleDisplayName(u, locale)); diff --git a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java index 0d823927f..443715eff 100644 --- a/src/main/java/us/tastybento/bskyblock/util/ItemParser.java +++ b/src/main/java/us/tastybento/bskyblock/util/ItemParser.java @@ -132,11 +132,11 @@ public class ItemParser { if (part.length == 2) { return new ItemStack(Material.BANNER, Integer.parseInt(part[1])); } - if (part.length > 3) { + if (part.length >= 3) { int reqAmount = Integer.parseInt(part[1]); @SuppressWarnings("deprecation") - ItemStack result = new ItemStack(Material.BANNER, reqAmount, (short) DyeColor.valueOf(part[2]).getDyeData()); + ItemStack result = new ItemStack(Material.BANNER, reqAmount, DyeColor.valueOf(part[2]).getDyeData()); BannerMeta meta = (BannerMeta) result.getItemMeta(); for (int i = 3; i < part.length; i += 2) { @@ -147,10 +147,10 @@ public class ItemParser { return result; } else { - return new ItemStack(Material.BANNER, 1); // Return a blank banner + return null; } } catch (Exception e) { - return new ItemStack(Material.BANNER, 1); // Return a blank banner + return null; } } } diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index 00d79c5b4..9e12b9b43 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -13,6 +13,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.World.Environment; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.util.Vector; @@ -243,5 +244,49 @@ public class Util { return world.getEnvironment().equals(Environment.NORMAL) ? world : Bukkit.getWorld(world.getName().replaceAll(NETHER, "").replaceAll(THE_END, "")); } - + /** + * Converts block face direction to radial degrees. Returns 0 if block face + * is not radial. + * + * @param face + * @return degrees + */ + public static float blockFaceToFloat(BlockFace face) { + switch (face) { + case EAST: + return 90F; + case EAST_NORTH_EAST: + return 67.5F; + case EAST_SOUTH_EAST: + return 0F; + case NORTH: + return 0F; + case NORTH_EAST: + return 45F; + case NORTH_NORTH_EAST: + return 22.5F; + case NORTH_NORTH_WEST: + return 337.5F; + case NORTH_WEST: + return 315F; + case SOUTH: + return 180F; + case SOUTH_EAST: + return 135F; + case SOUTH_SOUTH_EAST: + return 157.5F; + case SOUTH_SOUTH_WEST: + return 202.5F; + case SOUTH_WEST: + return 225F; + case WEST: + return 270F; + case WEST_NORTH_WEST: + return 292.5F; + case WEST_SOUTH_WEST: + return 247.5F; + default: + return 0F; + } + } } diff --git a/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java b/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java index 8eda4b1cf..9b1d8552a 100644 --- a/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java +++ b/src/test/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandlerTest.java @@ -16,6 +16,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.World; +import org.bukkit.World.Environment; import org.bukkit.inventory.ItemFactory; import org.bukkit.plugin.PluginManager; import org.junit.BeforeClass; @@ -39,7 +40,7 @@ import us.tastybento.bskyblock.util.Util; @RunWith(PowerMockRunner.class) @PrepareForTest( { BSkyBlock.class, Util.class }) public class MySQLDatabaseHandlerTest { - + private static MySQLDatabaseHandler handler; private static Island instance; private static String UNIQUE_ID = "xyz"; @@ -66,14 +67,14 @@ public class MySQLDatabaseHandlerTest { Bukkit.setServer(server); when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); - + Whitebox.setInternalState(BSkyBlock.class, "instance", plugin); - + Settings settings = mock(Settings.class); - + when(plugin.getSettings()).thenReturn(settings); when(settings.getDeathsMax()).thenReturn(10); - + when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); dbConn = mock(MySQLDatabaseConnecter.class); Connection connection = mock(Connection.class); @@ -88,7 +89,7 @@ public class MySQLDatabaseHandlerTest { instance = new Island(); instance.setUniqueId(UNIQUE_ID); handler = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn); - + PowerMockito.mockStatic(Util.class); when(Util.sameWorld(Mockito.any(), Mockito.any())).thenReturn(true); @@ -120,11 +121,11 @@ public class MySQLDatabaseHandlerTest { players.setPlayerName("name"); players.setPlayerUUID(UUID.randomUUID()); players.setResetsLeft(3); - + MySQLDatabaseHandler h = new MySQLDatabaseHandler<>(plugin, Players.class, dbConn); h.saveObject(players); - + Island island = new Island(); island.setUniqueId(UNIQUE_ID); island.setCenter(location); @@ -149,12 +150,12 @@ public class MySQLDatabaseHandlerTest { island.setPurgeProtected(true); island.setRange(100); island.setSpawn(true); - island.setSpawnPoint(location); + island.setSpawnPoint(Environment.NORMAL, location); island.setWorld(world); - + MySQLDatabaseHandler ih = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn); ih.saveObject(island); - + } } diff --git a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java index 9944d464f..57dd5e939 100644 --- a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java +++ b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java @@ -600,7 +600,7 @@ public class IslandsManagerTest { Island island = mock(Island.class); when(island.getWorld()).thenReturn(world); // Make a spawn position on the island - when(island.getSpawnPoint()).thenReturn(location); + when(island.getSpawnPoint(Mockito.any())).thenReturn(location); // Set the spawn island im.setSpawn(island); assertEquals(location,im.getSpawnPoint(world)); diff --git a/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java b/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java index 4de239cdb..22d4de255 100644 --- a/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java +++ b/src/test/java/us/tastybento/bskyblock/util/ItemParserTest.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemFactory; @@ -16,6 +17,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BannerMeta; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.inventory.meta.SpawnEggMeta; +import org.bukkit.material.MaterialData; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; import org.junit.Before; @@ -183,7 +185,7 @@ public class ItemParserTest { assertEquals(3, result.getAmount()); } } - } + } } } @@ -193,22 +195,24 @@ public class ItemParserTest { assertEquals(Material.TIPPED_ARROW, result.getType()); } - + @Test public void testParseBannerSimple() { ItemStack result = ItemParser.parse("BANNER:2"); assertEquals(Material.BANNER, result.getType()); assertEquals(2, result.getAmount()); } - + + @SuppressWarnings("deprecation") @Test public void testParseBannerThreeArgs() { // Germany ItemStack result = ItemParser.parse("BANNER:1:RED"); assertEquals(Material.BANNER, result.getType()); assertEquals(1, result.getAmount()); + assertEquals(new MaterialData(Material.BANNER, DyeColor.RED.getDyeData()), result.getData()); } - + @Test public void testParseBanner() { // Germany - two patterns @@ -216,6 +220,14 @@ public class ItemParserTest { Mockito.verify(bannerMeta, Mockito.times(2)).addPattern(Mockito.any()); } + @Test + public void testParseBannerTooManyColons() { + ItemStack result = ItemParser.parse("BANNER:1::::::::::::::"); + Mockito.verify(bannerMeta, Mockito.never()).addPattern(Mockito.any()); + assertEquals(Material.BANNER, result.getType()); + assertEquals(1, result.getAmount()); + } + @Test public void testParseTwoItem() { ItemStack result = ItemParser.parse("STONE:5");