diff --git a/pom.xml b/pom.xml index ec31959..dc745a8 100644 --- a/pom.xml +++ b/pom.xml @@ -45,14 +45,14 @@ 2.0.2 - 1.13.2-R0.1-SNAPSHOT + 1.14.4-R0.1-SNAPSHOT 1.6.0 ${build.version}-SNAPSHOT -LOCAL - 1.6.1 + 1.7.0 diff --git a/src/main/java/bentobox/addon/limits/commands/LimitPanel.java b/src/main/java/bentobox/addon/limits/commands/LimitPanel.java index 51a4baa..dff1647 100644 --- a/src/main/java/bentobox/addon/limits/commands/LimitPanel.java +++ b/src/main/java/bentobox/addon/limits/commands/LimitPanel.java @@ -29,6 +29,8 @@ public class LimitPanel { // This maps the entity types to the icon that should be shown in the panel // If the icon is null, then the entity type is not covered by the addon public final static Map E2M = new HashMap<>(); + // This is a map of blocks to Material + public final static Map B2M = new HashMap<>(); static { E2M.put(EntityType.PIG_ZOMBIE, Material.ZOMBIE_PIGMAN_SPAWN_EGG); E2M.put(EntityType.MUSHROOM_COW, Material.MOOSHROOM_SPAWN_EGG); @@ -73,7 +75,13 @@ public class LimitPanel { E2M.put(EntityType.ENDER_CRYSTAL, null); E2M.put(EntityType.ENDER_PEARL, null); E2M.put(EntityType.ENDER_DRAGON, null); - + // Block to Material icons + B2M.put(Material.SWEET_BERRY_BUSH, Material.SWEET_BERRIES); + B2M.put(Material.POTATOES, Material.POTATO); + B2M.put(Material.CARROTS, Material.CARROT); + B2M.put(Material.BEETROOTS, Material.BEETROOT); + B2M.put(Material.BAMBOO_SAPLING, Material.BAMBOO); + B2M.put(Material.REDSTONE_WIRE, Material.REDSTONE); } /** @@ -104,12 +112,9 @@ public class LimitPanel { for (Entry en : matLimits.entrySet()) { PanelItemBuilder pib = new PanelItemBuilder(); pib.name(Util.prettifyText(en.getKey().toString())); - if (en.getKey() == Material.REDSTONE_WIRE) { - pib.icon(Material.REDSTONE); - } - else { - pib.icon(en.getKey()); - } + // Adjust icon + pib.icon(B2M.getOrDefault(en.getKey(), en.getKey())); + int count = ibc == null ? 0 : ibc.getBlockCount().getOrDefault(en.getKey(), 0); String color = count >= en.getValue() ? user.getTranslation("island.limits.max-color") : user.getTranslation("island.limits.regular-color"); pib.description(color @@ -128,6 +133,7 @@ public class LimitPanel { } else if (k.isAlive()) { m = Material.valueOf(k.toString() + "_SPAWN_EGG"); } else { + // Regular material m = Material.valueOf(k.toString()); } } catch (Exception e) { diff --git a/src/main/java/bentobox/addon/limits/commands/PlayerCommand.java b/src/main/java/bentobox/addon/limits/commands/PlayerCommand.java index f705f80..35fe526 100644 --- a/src/main/java/bentobox/addon/limits/commands/PlayerCommand.java +++ b/src/main/java/bentobox/addon/limits/commands/PlayerCommand.java @@ -22,6 +22,7 @@ public class PlayerCommand extends CompositeCommand { public PlayerCommand(Limits addon, CompositeCommand parent) { super(parent, "limits"); this.addon = addon; + new RecountCommand(addon, this); } /* (non-Javadoc) diff --git a/src/main/java/bentobox/addon/limits/commands/RecountCommand.java b/src/main/java/bentobox/addon/limits/commands/RecountCommand.java new file mode 100644 index 0000000..13748a2 --- /dev/null +++ b/src/main/java/bentobox/addon/limits/commands/RecountCommand.java @@ -0,0 +1,61 @@ +package bentobox.addon.limits.commands; + +import java.util.List; + +import bentobox.addon.limits.Limits; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.user.User; + +/** + * + * @author tastybento + */ +public class RecountCommand extends CompositeCommand { + + private final Limits addon; + + /** + * Player command to do a recount. Has a cooldown + * + * @param addon - addon + */ + public RecountCommand(Limits addon, CompositeCommand parent) { + super(parent, "recount"); + this.addon = addon; + } + + /* (non-Javadoc) + * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#setup() + */ + @Override + public void setup() { + this.setPermission("limits.player.recount"); + this.setOnlyPlayer(true); + this.setParametersHelp("island.limits.recount.parameters"); + this.setDescription("island.limits.recount.description"); + } + + /* (non-Javadoc) + * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List) + */ + @Override + public boolean canExecute(User user, String label, List args) { + if (!args.isEmpty()) { + showHelp(this, user); + return false; + } + if (addon.getIslands().getIsland(getWorld(), user) == null) { + user.sendMessage("general.errors.no-island"); + return false; + } + return !checkCooldown(user); + } + @Override + public boolean execute(User user, String label, List args) { + // Set cooldown + setCooldown(user.getUniqueId(), addon.getConfig().getInt("cooldown", 120)); + new LimitsCalc(getWorld(), getPlugin(), user.getUniqueId(), addon, user); + return true; + } + +} diff --git a/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java b/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java index e42799d..0f24af9 100644 --- a/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java +++ b/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java @@ -23,7 +23,6 @@ import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFromToEvent; -import org.bukkit.event.block.BlockGrowEvent; import org.bukkit.event.block.BlockMultiPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockSpreadEvent; @@ -50,7 +49,7 @@ public class BlockLimitsListener implements Listener { * Blocks that are not counted */ private static final List DO_NOT_COUNT = Arrays.asList(Material.LAVA, Material.WATER, Material.AIR, Material.FIRE, Material.END_PORTAL, Material.NETHER_PORTAL); - + private static final List STACKABLE = Arrays.asList(Material.SUGAR_CANE, Material.BAMBOO); /** * Save every 10 blocks of change */ @@ -147,7 +146,23 @@ public class BlockLimitsListener implements Listener { } void handleBreak(Cancellable e, Player player, Block b) { - notify(e, User.getInstance(player), process(b, false), b.getType()); + Material mat = b.getType(); + // Special handling for crops that can break in different ways + if (mat.equals(Material.WHEAT_SEEDS)) { + mat = Material.WHEAT; + } else if (mat.equals(Material.BEETROOT_SEEDS)) { + mat = Material.BEETROOT; + } + // Check for stackable plants + if (STACKABLE.contains(b.getType())) { + // Check for blocks above + Block block = b; + while(block.getRelative(BlockFace.UP).getType().equals(mat) && block.getY() < b.getWorld().getMaxHeight()) { + block = block.getRelative(BlockFace.UP); + process(block, false, mat); + } + } + notify(e, User.getInstance(player), process(b, false, mat), mat); // Player breaks a block and there was a redstone dust/repeater/... above if (b.getRelative(BlockFace.UP).getType() == Material.REDSTONE_WIRE || b.getRelative(BlockFace.UP).getType() == Material.REPEATER || b.getRelative(BlockFace.UP).getType() == Material.COMPARATOR || b.getRelative(BlockFace.UP).getType() == Material.REDSTONE_TORCH) { process(b.getRelative(BlockFace.UP), false); @@ -201,18 +216,22 @@ public class BlockLimitsListener implements Listener { process(e.getBlock(), true); } + /* @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlock(BlockGrowEvent e) { + Bukkit.getLogger().info(e.getEventName()); process(e.getBlock(), true); } - + */ @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlock(BlockSpreadEvent e) { + Bukkit.getLogger().info(e.getEventName()); process(e.getBlock(), true); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlock(EntityBlockFormEvent e) { + Bukkit.getLogger().info(e.getEventName()); process(e.getBlock(), true); } @@ -244,11 +263,24 @@ public class BlockLimitsListener implements Listener { return process(b, add, b.getType()); } - // It wouldn't make sense to count REDSTONE_WALL_TORCH and REDSTONE_TORCH as separed limits. + // Return equivalents. public Material fixMaterial(Material b) { - if (b == Material.REDSTONE_WALL_TORCH) { + switch (b) { + case REDSTONE_WALL_TORCH: return Material.REDSTONE_TORCH; - } else { + case WALL_TORCH: + return Material.TORCH; + case ZOMBIE_WALL_HEAD: + return Material.ZOMBIE_HEAD; + case CREEPER_WALL_HEAD: + return Material.CREEPER_HEAD; + case PLAYER_WALL_HEAD: + return Material.PLAYER_HEAD; + case DRAGON_WALL_HEAD: + return Material.DRAGON_HEAD; + case BAMBOO_SAPLING: + return Material.BAMBOO; + default: return b; } } @@ -286,13 +318,14 @@ public class BlockLimitsListener implements Listener { } else { if (islandCountMap.containsKey(id)) { // Check for changes - if (!fixMaterial(changeTo).equals(fixMaterial(b.getType())) && fixMaterial(changeTo).isBlock() && !DO_NOT_COUNT.contains(fixMaterial(changeTo))) { + Material fixed = fixMaterial(changeTo); + if (!fixed.equals(fixMaterial(b.getType())) && fixed.isBlock() && !DO_NOT_COUNT.contains(fixed)) { // Check limit - int limit = checkLimit(b.getWorld(), fixMaterial(changeTo), id); + int limit = checkLimit(b.getWorld(), fixed, id); if (limit > -1) { return limit; } - islandCountMap.get(id).add(fixMaterial(changeTo)); + islandCountMap.get(id).add(fixed); } islandCountMap.get(id).remove(fixMaterial(b.getType())); saveMap.merge(id, 1, Integer::sum); diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index ea03560..9e70751 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -4,24 +4,33 @@ version: ${version}${build.number} authors: tastybento -softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid +softdepend: AcidIsland, BSkyBlock, CaveBlock permissions: acidisland.limits.player.limits: description: Player can use limits command default: true + acidisland.limits.player.recount: + description: Player can use recount command + default: true acidisland.limits.admin.limits: description: Player can use admin limits command default: op bskyblock.limits.player.limits: description: Player can use limits command default: true + bskyblock.limits.player.recount: + description: Player can use recount command + default: true bskyblock.limits.admin.limits: description: Player can use admin limits command default: op caveblock.limits.player.limits: description: Player can use limits command default: true + caveblock.limits.player.recount: + description: Player can use recount command + default: true caveblock.limits.admin.limits: description: Player can use admin limits command default: op diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9c2eb74..b7d8d72 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -10,6 +10,9 @@ gamemodes: # example: bskyblock.island.limit.hopper.10 # permission activates when player logs in. # +# Cooldown for player recount command in seconds +cooldown: 120 + # General block limiting # Use this section to limit how many blocks can be added to an island. # 0 means the item will be blocked from placement completely. diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 1d35556..d8eaf98 100755 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -22,11 +22,12 @@ admin: finished: "&aIsland recalc finished sucessfully!" island: - limits: - parameters: "" + limits: description: "show your island limits" max-color: "&c" regular-color: "&a" block-limit-syntax: "[number]/[limit]" no-limits: "&cNo limits set in this world" + recount: + description: "recounts limits for your island"