diff --git a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java index 84a076a..7213d4c 100644 --- a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java +++ b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java @@ -106,7 +106,7 @@ public class LegacyAdapter implements VersionAdapter { @Override public void applyToolDurability(Player player, int damage) { ItemStack tool = this.getItemInHand(player); - if (tool.getType().getMaxDurability() <= 1) + if (tool.getType().getMaxDurability() < 1) return; int unbreakingLevel = tool.getEnchantmentLevel(Enchantment.DURABILITY); diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/misc/OnlyToppleWhile.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/misc/OnlyToppleWhile.java new file mode 100644 index 0000000..bcdd7f3 --- /dev/null +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/misc/OnlyToppleWhile.java @@ -0,0 +1,20 @@ +package com.songoda.ultimatetimber.misc; + +public enum OnlyToppleWhile { + SNEAKING, + NOT_SNEAKING, + ALWAYS; + + /** + * Gets an OnlyToppleWhile from a given string + * + * @param string The string + * @return The TreeAnimationType, returns FANCY if the string is an invalid type + */ + public static OnlyToppleWhile fromString(String string) { + for (OnlyToppleWhile value : values()) + if (value.name().equalsIgnoreCase(string)) + return value; + return OnlyToppleWhile.ALWAYS; + } +} diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeDefinition.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeDefinition.java index 7b6771b..656c903 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeDefinition.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeDefinition.java @@ -14,13 +14,13 @@ public class TreeDefinition { private final int maxLeafDistanceFromLog; private final boolean detectLeavesDiagonally; private final boolean dropOriginalLog, dropOriginalLeaf; - private final Set logLoot, leafLoot; + private final Set logLoot, leafLoot, entireTreeLoot; private final Set requiredTools; public TreeDefinition(String key, Set logBlockData, Set leafBlockData, IBlockData saplingBlockData, Set plantableSoilBlockData, int maxLeafDistanceFromLog, boolean detectLeavesDiagonally, - boolean dropOriginalLog, boolean dropOriginalLeaf, Set logLoot, - Set leafLoot, Set requiredTools) { + boolean dropOriginalLog, boolean dropOriginalLeaf, Set logLoot, Set leafLoot, + Set entireTreeLoot, Set requiredTools) { this.key = key; this.logBlockData = logBlockData; this.leafBlockData = leafBlockData; @@ -32,6 +32,7 @@ public class TreeDefinition { this.dropOriginalLeaf = dropOriginalLeaf; this.logLoot = logLoot; this.leafLoot = leafLoot; + this.entireTreeLoot = entireTreeLoot; this.requiredTools = requiredTools; } @@ -134,6 +135,15 @@ public class TreeDefinition { return Collections.unmodifiableSet(this.leafLoot); } + /** + * Gets the loot for this TreeDefinition + * + * @return A Set of TreeLoot + */ + public Set getEntireTreeLoot() { + return Collections.unmodifiableSet(this.entireTreeLoot); + } + /** * Gets the tools that can be used to activate this tree topple * diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ChoppingManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ChoppingManager.java index 73b96de..952d34d 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ChoppingManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ChoppingManager.java @@ -1,29 +1,39 @@ package com.songoda.ultimatetimber.manager; import com.songoda.ultimatetimber.UltimateTimber; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.UUID; public class ChoppingManager extends Manager { private Set disabledPlayers; + private Map cooldownedPlayers; + private boolean useCooldown; + private int cooldownAmount; public ChoppingManager(UltimateTimber ultimateTimber) { super(ultimateTimber); this.disabledPlayers = new HashSet<>(); + this.cooldownedPlayers = new HashMap<>(); } @Override public void reload() { - + this.useCooldown = ConfigurationManager.Setting.PLAYER_TREE_TOPPLE_COOLDOWN.getBoolean(); + this.cooldownAmount = ConfigurationManager.Setting.PLAYER_TREE_TOPPLE_COOLDOWN_LENGTH.getInt(); } @Override public void disable() { this.disabledPlayers.clear(); + this.cooldownedPlayers.clear(); } /** @@ -52,4 +62,34 @@ public class ChoppingManager extends Manager { return !this.disabledPlayers.contains(player.getUniqueId()); } + /** + * Sets a player into cooldown + * + * @param player The player to cooldown + */ + public void cooldownPlayer(Player player) { + if (!this.useCooldown || player.hasPermission("ultimatetimber.bypasscooldown")) + return; + + this.cooldownedPlayers.put(player.getUniqueId(), false); + + Bukkit.getScheduler().scheduleSyncDelayedTask(UltimateTimber.getInstance(), () -> + this.cooldownedPlayers.remove(player.getUniqueId()), this.cooldownAmount * 20L); + } + + /** + * Checks if a player is in cooldown + * + * @param player The player to check + * @return True if the player can topple trees, otherwise false + */ + public boolean isInCooldown(Player player) { + boolean cooldowned = !this.useCooldown && this.cooldownedPlayers.containsKey(player.getUniqueId()); + if (this.cooldownedPlayers.containsKey(player.getUniqueId()) && !this.cooldownedPlayers.get(player.getUniqueId())) { + player.sendMessage(UltimateTimber.getInstance().getPrefix() + ChatColor.YELLOW + "You are on cooldown and cannot topple trees right now."); + this.cooldownedPlayers.replace(player.getUniqueId(), true); + } + return cooldowned; + } + } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ConfigurationManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ConfigurationManager.java index 1678b6a..d157af2 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ConfigurationManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/ConfigurationManager.java @@ -22,9 +22,11 @@ public class ConfigurationManager extends Manager { BREAK_ENTIRE_TREE_BASE(SettingType.BOOLEAN), DESTROY_INITIATED_BLOCK(SettingType.BOOLEAN), ONLY_DETECT_LOGS_UPWARDS(SettingType.BOOLEAN), - ONLY_TOPPLE_WHILE_SNEAKING(SettingType.BOOLEAN), + ONLY_TOPPLE_WHILE(SettingType.STRING), ALLOW_CREATIVE_MODE(SettingType.BOOLEAN), REQUIRE_CHOP_PERMISSION(SettingType.BOOLEAN), + PLAYER_TREE_TOPPLE_COOLDOWN(SettingType.BOOLEAN), + PLAYER_TREE_TOPPLE_COOLDOWN_LENGTH(SettingType.INT), IGNORE_REQUIRED_TOOLS(SettingType.BOOLEAN), REPLANT_SAPLINGS(SettingType.BOOLEAN), REPLANT_SAPLINGS_COOLDOWN(SettingType.INT), diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java index b7f5f6a..c57aff1 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java @@ -66,6 +66,7 @@ public class TreeDefinitionManager extends Manager { boolean dropOriginalLeaf; Set logLoot = new HashSet<>(); Set leafLoot = new HashSet<>(); + Set entireTreeLoot = new HashSet<>(); Set requiredTools = new HashSet<>(); for (String blockDataString : tree.getStringList("logs")) @@ -94,10 +95,16 @@ public class TreeDefinitionManager extends Manager { for (String lootKey : leafLootSection.getKeys(false)) leafLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, leafLootSection.getConfigurationSection(lootKey))); + ConfigurationSection entireTreeLootSection = tree.getConfigurationSection("entire-tree-loot"); + if (entireTreeLootSection != null) + for (String lootKey : entireTreeLootSection.getKeys(false)) + entireTreeLoot.add(this.getTreeLootEntry(versionAdapter, TreeBlockType.LEAF, entireTreeLootSection.getConfigurationSection(lootKey))); + for (String itemStackString : tree.getStringList("required-tools")) requiredTools.add(versionAdapter.parseItemStackFromString(itemStackString)); - this.treeDefinitions.add(new TreeDefinition(key, logBlockData, leafBlockData, saplingBlockData, plantableSoilBlockData, maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, requiredTools)); + this.treeDefinitions.add(new TreeDefinition(key, logBlockData, leafBlockData, saplingBlockData, plantableSoilBlockData, + maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, entireTreeLoot, requiredTools)); } // Load global plantable soil @@ -211,13 +218,14 @@ public class TreeDefinitionManager extends Manager { } /** - * Tries to spawn loot for a given TreeBlock with the given TreeDefinition for a given player + * Tries to spawn loot for a given TreeBlock with the given TreeDefinition for a given Player * * @param treeDefinition The TreeDefinition to use * @param treeBlock The TreeBlock to drop for * @param player The Player to drop for + * @param isForEntireTree If the loot is for the entire tree */ - public void dropTreeLoot(TreeDefinition treeDefinition, ITreeBlock treeBlock, Player player, boolean hasSilkTouch) { + public void dropTreeLoot(TreeDefinition treeDefinition, ITreeBlock treeBlock, Player player, boolean hasSilkTouch, boolean isForEntireTree) { VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter(); HookManager hookManager = this.ultimateTimber.getHookManager(); @@ -228,28 +236,32 @@ public class TreeDefinitionManager extends Manager { // Get the loot that we should try to drop List toTry = new ArrayList<>(); - if (hasSilkTouch) { - lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); + if (isForEntireTree) { + toTry.addAll(treeDefinition.getEntireTreeLoot()); } else { - switch (treeBlock.getTreeBlockType()) { - case LOG: - toTry.addAll(treeDefinition.getLogLoot()); - toTry.addAll(this.globalLogLoot); - if (treeDefinition.shouldDropOriginalLog()) { - if (hookManager.shouldApplyDoubleDropsHooks(player)) + if (hasSilkTouch) { + lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); + } else { + switch (treeBlock.getTreeBlockType()) { + case LOG: + toTry.addAll(treeDefinition.getLogLoot()); + toTry.addAll(this.globalLogLoot); + if (treeDefinition.shouldDropOriginalLog()) { + if (hookManager.shouldApplyDoubleDropsHooks(player)) + lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); - lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); - } - break; - case LEAF: - toTry.addAll(treeDefinition.getLeafLoot()); - toTry.addAll(this.globalLeafLoot); - if (treeDefinition.shouldDropOriginalLeaf()) { - if (hookManager.shouldApplyDoubleDropsHooks(player)) + } + break; + case LEAF: + toTry.addAll(treeDefinition.getLeafLoot()); + toTry.addAll(this.globalLeafLoot); + if (treeDefinition.shouldDropOriginalLeaf()) { + if (hookManager.shouldApplyDoubleDropsHooks(player)) + lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); - lootedItems.addAll(versionAdapter.getBlockDrops(treeDefinition, treeBlock)); - } - break; + } + break; + } } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java index d13714f..4e3abd3 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java @@ -4,6 +4,7 @@ import com.songoda.ultimatetimber.UltimateTimber; import com.songoda.ultimatetimber.adapter.VersionAdapter; import com.songoda.ultimatetimber.events.TreeFallEvent; import com.songoda.ultimatetimber.events.TreeFellEvent; +import com.songoda.ultimatetimber.misc.OnlyToppleWhile; import com.songoda.ultimatetimber.tree.DetectedTree; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -62,7 +63,7 @@ public class TreeFallManager extends Manager implements Listener { if (!ConfigurationManager.Setting.ALLOW_CREATIVE_MODE.getBoolean() && player.getGameMode().equals(GameMode.CREATIVE)) isValid = false; - if (ConfigurationManager.Setting.ONLY_TOPPLE_WHILE_SNEAKING.getBoolean() && !player.isSneaking()) + if (!this.checkToppleWhile(player)) isValid = false; if (ConfigurationManager.Setting.REQUIRE_CHOP_PERMISSION.getBoolean() && !player.hasPermission("ultimatetimber.chop")) @@ -71,6 +72,9 @@ public class TreeFallManager extends Manager implements Listener { if (!choppingManager.isChopping(player)) isValid = false; + if (choppingManager.isInCooldown(player)) + isValid = false; + if (treeAnimationManager.isBlockInAnimation(block)) { isValid = false; event.setCancelled(true); @@ -114,6 +118,8 @@ public class TreeFallManager extends Manager implements Listener { // Valid tree and meets all conditions past this point event.setCancelled(true); + choppingManager.cooldownPlayer(player); + // Destroy initiated block if enabled if (ConfigurationManager.Setting.DESTROY_INITIATED_BLOCK.getBoolean()) { detectedTree.getDetectedTreeBlocks().getInitialLogBlock().getBlock().setType(Material.AIR); @@ -125,10 +131,28 @@ public class TreeFallManager extends Manager implements Listener { hookManager.applyExperienceHooks(player, detectedTree.getDetectedTreeBlocks()); treeAnimationManager.runAnimation(detectedTree, player); + treeDefinitionManager.dropTreeLoot(detectedTree.getTreeDefinition(), detectedTree.getDetectedTreeBlocks().getInitialLogBlock(), player, false, true); // Trigger fell event TreeFellEvent treeFellEvent = new TreeFellEvent(player, detectedTree); Bukkit.getPluginManager().callEvent(treeFellEvent); } + /** + * Checks if a player is doing a certain action required to topple a tree + * + * @param player The player to check + * @return True if the check passes, otherwise false + */ + private boolean checkToppleWhile(Player player) { + switch (OnlyToppleWhile.fromString(ConfigurationManager.Setting.ONLY_TOPPLE_WHILE.getString())) { + case SNEAKING: + return player.isSneaking(); + case NOT_SNEAKING: + return !player.isSneaking(); + default: + return true; + } + } + } diff --git a/UltimateTimber/Plugin/src/main/resources/config-current.yml b/UltimateTimber/Plugin/src/main/resources/config-current.yml index a5604c5..2a271a8 100644 --- a/UltimateTimber/Plugin/src/main/resources/config-current.yml +++ b/UltimateTimber/Plugin/src/main/resources/config-current.yml @@ -49,17 +49,27 @@ destroy-initiated-block: false # Default: true only-detect-logs-upwards: true -# Only topple over trees while the player is sneaking -# Default: false -only-topple-while-sneaking: false +# Only topple trees while the player is doing something +# Valid values: SNEAKING, NOT_SNEAKING, ALWAYS +# Default: ALWAYS +only-topple-while: ALWAYS # Allow toppling trees in creative mode # Default: true allow-creative-mode: true # Require the player to have the permission 'ultimatetimber.chop' to topple trees -# Default: true -require-chop-permission: true +# Default: false +require-chop-permission: false + +# If a player should only be allowed to chop one tree per cooldown length +# Default: false +player-tree-topple-cooldown: false + +# The amount of seconds a player has to wait before they can chop a tree again +# Does nothing if player-tree-topple-cooldown is false +# Default: 5 +player-tree-topple-cooldown-length: 5 # Allow players to topple trees regardless of what they are holding in their hand # Default: false @@ -178,6 +188,7 @@ trees: 1: material: APPLE chance: 0.5 + entire-tree-loot: [] required-tools: [] spruce: logs: @@ -198,6 +209,7 @@ trees: 0: material: SPRUCE_SAPLING chance: 5 + entire-tree-loot: [] required-tools: [] birch: logs: @@ -218,6 +230,7 @@ trees: 0: material: BIRCH_SAPLING chance: 5 + entire-tree-loot: [] required-tools: [] jungle: logs: @@ -238,6 +251,7 @@ trees: 0: material: JUNGLE_SAPLING chance: 2.5 + entire-tree-loot: [] required-tools: [] acacia: logs: @@ -258,6 +272,7 @@ trees: 0: material: ACACIA_SAPLING chance: 5 + entire-tree-loot: [] required-tools: [] dark_oak: logs: @@ -281,6 +296,7 @@ trees: 1: material: APPLE chance: 0.5 + entire-tree-loot: [] required-tools: [] brown_mushroom: logs: @@ -299,6 +315,7 @@ trees: 0: material: BROWN_MUSHROOM chance: 25 + entire-tree-loot: [] required-tools: [] red_mushroom: logs: @@ -317,6 +334,7 @@ trees: 0: material: RED_MUSHROOM chance: 25 + entire-tree-loot: [] required-tools: [] # All soil types that the tree type's saplings can be planted on @@ -331,6 +349,7 @@ global-plantable-soil: # To add more, increment the number by 1 # The chance is out of 100 and can contain decimals # The default examples here are to show what you can do with custom loot +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% global-log-loot: 0: material: DIAMOND @@ -347,10 +366,21 @@ global-log-loot: # The loot applies to each leaf broken in the tree # To add more, increment the number by 1 # The chance is out of 100 and can contain decimals +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% global-leaf-loot: 0: material: GOLDEN_APPLE - chance: 0.5 + chance: 0.1 + +# Custom entire tree loot that is available for all tree types +# The loot will be dropped only one time for the entire tree +# To add more, increment the number by 1 +# The chance is out of 100 and can contain decimals +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% +global-entire-tree-loot: + 0: + material: DIAMOND + chance: 0 # Tools that must be used to topple over a tree # Applies to all tree types diff --git a/UltimateTimber/Plugin/src/main/resources/config-legacy.yml b/UltimateTimber/Plugin/src/main/resources/config-legacy.yml index 0a3e9cd..a07df52 100644 --- a/UltimateTimber/Plugin/src/main/resources/config-legacy.yml +++ b/UltimateTimber/Plugin/src/main/resources/config-legacy.yml @@ -50,17 +50,27 @@ destroy-initiated-block: false # Default: true only-detect-logs-upwards: true -# Only topple over trees while the player is sneaking -# Default: false -only-topple-while-sneaking: false +# Only topple trees while the player is doing something +# Valid values: SNEAKING, NOT_SNEAKING, ALWAYS +# Default: ALWAYS +only-topple-while: ALWAYS # Allow toppling trees in creative mode # Default: true allow-creative-mode: true # Require the player to have the permission 'ultimatetimber.chop' to topple trees -# Default: true -require-chop-permission: true +# Default: false +require-chop-permission: false + +# If a player should only be allowed to chop one tree per cooldown length +# Default: false +player-tree-topple-cooldown: false + +# The amount of seconds a player has to wait before they can chop a tree again +# Does nothing if player-tree-topple-cooldown is false +# Default: 5 +player-tree-topple-cooldown-length: 5 # Allow players to topple trees regardless of what they are holding in their hand # Default: false @@ -176,6 +186,7 @@ trees: 1: material: APPLE chance: 0.5 + entire-tree-loot: [] required-tools: [] spruce: logs: @@ -193,6 +204,7 @@ trees: 0: material: SAPLING:1 chance: 5 + entire-tree-loot: [] required-tools: [] birch: logs: @@ -210,6 +222,7 @@ trees: 0: material: SAPLING:2 chance: 5 + entire-tree-loot: [] required-tools: [] jungle: logs: @@ -227,6 +240,7 @@ trees: 0: material: SAPLING:3 chance: 2.5 + entire-tree-loot: [] required-tools: [] acacia: logs: @@ -244,6 +258,7 @@ trees: 0: material: SAPLING:4 chance: 5 + entire-tree-loot: [] required-tools: [] dark_oak: logs: @@ -264,6 +279,7 @@ trees: 1: material: APPLE chance: 0.5 + entire-tree-loot: [] required-tools: [] brown_mushroom: logs: @@ -282,6 +298,7 @@ trees: 0: material: BROWN_MUSHROOM chance: 25 + entire-tree-loot: [] required-tools: [] red_mushroom: logs: @@ -300,6 +317,7 @@ trees: 0: material: RED_MUSHROOM chance: 25 + entire-tree-loot: [] required-tools: [] # All soil types that the tree type's saplings can be planted on @@ -314,6 +332,7 @@ global-plantable-soil: # To add more, increment the number by 1 # The chance is out of 100 and can contain decimals # The default examples here are to show what you can do with custom loot +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% global-log-loot: 0: material: DIAMOND @@ -330,11 +349,22 @@ global-log-loot: # The loot applies to each leaf broken in the tree # To add more, increment the number by 1 # The chance is out of 100 and can contain decimals +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% global-leaf-loot: 0: material: GOLDEN_APPLE chance: 0.5 +# Custom entire tree loot that is available for all tree types +# The loot will be dropped only one time for the entire tree +# To add more, increment the number by 1 +# The chance is out of 100 and can contain decimals +# Valid command placeholders: %player%, %type%, %xPos%, %yPos%, %zPos% +global-entire-tree-loot: + 0: + material: DIAMOND + chance: 0 + # Tools that must be used to topple over a tree # Applies to all tree types global-required-tools: diff --git a/UltimateTimber/Plugin/src/main/resources/plugin.yml b/UltimateTimber/Plugin/src/main/resources/plugin.yml index 9a3daf7..425da61 100644 --- a/UltimateTimber/Plugin/src/main/resources/plugin.yml +++ b/UltimateTimber/Plugin/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: UltimateTimber version: @version@ -author: Songoda +authors: [Songoda, Esophose] main: com.songoda.ultimatetimber.UltimateTimber api-version: 1.13 softdepend: [mcMMO, Jobs] @@ -16,6 +16,7 @@ permissions: ultimatetimber.chop: true ultimatetimber.bonusloot: true ultimatetimber.reload: true + ultimatetimber.bypasscooldown: true ultimatetimber.chop: description: Allows players to trigger the trees toppling down effect default: op @@ -25,3 +26,6 @@ permissions: ultimatetimber.reload: description: Reloads the configuration file default: op + ultimatetimber.bypasscooldown: + description: Allows a player to bypass the tree topple cooldown + default: op