mirror of
https://github.com/songoda/UltimateTimber.git
synced 2025-02-09 08:11:24 +01:00
Add the ability to limit tools to a custom axe with NBT.
This commit is contained in:
parent
5dcb528eea
commit
8be488173f
@ -17,11 +17,12 @@ public class TreeDefinition {
|
||||
private final boolean dropOriginalLog, dropOriginalLeaf;
|
||||
private final Set<TreeLoot> logLoot, leafLoot, entireTreeLoot;
|
||||
private final Set<ItemStack> requiredTools;
|
||||
private final boolean requiredAxe;
|
||||
|
||||
public TreeDefinition(String key, Set<CompatibleMaterial> logMaterial, Set<CompatibleMaterial> leafMaterial, CompatibleMaterial saplingMaterial,
|
||||
Set<CompatibleMaterial> plantableSoilMaterial, double maxLogDistanceFromTrunk, int maxLeafDistanceFromLog,
|
||||
boolean detectLeavesDiagonally, boolean dropOriginalLog, boolean dropOriginalLeaf, Set<TreeLoot> logLoot,
|
||||
Set<TreeLoot> leafLoot, Set<TreeLoot> entireTreeLoot, Set<ItemStack> requiredTools) {
|
||||
Set<TreeLoot> leafLoot, Set<TreeLoot> entireTreeLoot, Set<ItemStack> requiredTools, boolean requiredAxe) {
|
||||
this.key = key;
|
||||
this.logMaterial = logMaterial;
|
||||
this.leafMaterial = leafMaterial;
|
||||
@ -36,6 +37,7 @@ public class TreeDefinition {
|
||||
this.leafLoot = leafLoot;
|
||||
this.entireTreeLoot = entireTreeLoot;
|
||||
this.requiredTools = requiredTools;
|
||||
this.requiredAxe = requiredAxe;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,4 +166,12 @@ public class TreeDefinition {
|
||||
return Collections.unmodifiableSet(this.requiredTools);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not does this TreeDefinition require a custom axe.
|
||||
*
|
||||
* @return True if the TreeDefinition requires a custom axe
|
||||
*/
|
||||
public boolean isRequiredAxe() {
|
||||
return requiredAxe;
|
||||
}
|
||||
}
|
||||
|
@ -457,3 +457,20 @@ global-required-tools:
|
||||
- GOLDEN_AXE
|
||||
- DIAMOND_AXE
|
||||
- NETHERITE_AXE
|
||||
|
||||
# Require the custom axe
|
||||
# Applies to all tree types
|
||||
global-required-axe: false
|
||||
|
||||
# Axe item
|
||||
required-axe:
|
||||
type: DIAMOND_AXE
|
||||
name: '&aAn Epic Axe'
|
||||
lore:
|
||||
- "&7This axe... it's awesome."
|
||||
- "&7It can chop down trees real fast."
|
||||
enchants:
|
||||
- 'DURABILITY:3'
|
||||
- 'DIG_SPEED:5'
|
||||
# NBT to identify the axe by.
|
||||
nbt: 'ultimatetimber_axe'
|
@ -15,6 +15,10 @@ command:
|
||||
description: 'Toggles your chopping mode'
|
||||
enabled: '&7Chopping Mode: &aEnabled'
|
||||
disabled: '&7Chopping Mode: &cDisabled'
|
||||
give:
|
||||
not-a-player: '&cNot a player.'
|
||||
given: '&fGiven to player &a%player%'
|
||||
no-axe: '&cAxe could not be loaded.'
|
||||
|
||||
# Event Messages
|
||||
|
||||
|
@ -5,9 +5,18 @@ import com.songoda.core.SongodaPlugin;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.configuration.Config;
|
||||
import com.songoda.core.hooks.LogManager;
|
||||
import com.songoda.ultimatetimber.commands.CommandGiveAxe;
|
||||
import com.songoda.ultimatetimber.commands.CommandReload;
|
||||
import com.songoda.ultimatetimber.commands.CommandToggle;
|
||||
import com.songoda.ultimatetimber.manager.*;
|
||||
import com.songoda.ultimatetimber.manager.ChoppingManager;
|
||||
import com.songoda.ultimatetimber.manager.ConfigurationManager;
|
||||
import com.songoda.ultimatetimber.manager.Manager;
|
||||
import com.songoda.ultimatetimber.manager.PlacedBlockManager;
|
||||
import com.songoda.ultimatetimber.manager.SaplingManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeAnimationManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeDefinitionManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeDetectionManager;
|
||||
import com.songoda.ultimatetimber.manager.TreeFallManager;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -49,8 +58,10 @@ public class UltimateTimber extends SongodaPlugin {
|
||||
// Setup plugin commands
|
||||
this.commandManager = new com.songoda.core.commands.CommandManager(this);
|
||||
this.commandManager.addMainCommand("ut")
|
||||
.addSubCommands(new CommandReload(this),
|
||||
new CommandToggle(this)
|
||||
.addSubCommands(
|
||||
new CommandReload(this),
|
||||
new CommandToggle(this),
|
||||
new CommandGiveAxe(this)
|
||||
);
|
||||
|
||||
// Register managers
|
||||
|
@ -0,0 +1,80 @@
|
||||
package com.songoda.ultimatetimber.commands;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.core.utils.PlayerUtils;
|
||||
import com.songoda.ultimatetimber.UltimateTimber;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CommandGiveAxe extends AbstractCommand {
|
||||
|
||||
private final UltimateTimber plugin;
|
||||
|
||||
public CommandGiveAxe(UltimateTimber plugin) {
|
||||
super(CommandType.CONSOLE_OK, true, "give");
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
|
||||
if (args.length < 1)
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
|
||||
Player player = Bukkit.getPlayer(args[0]);
|
||||
if (player == null) {
|
||||
if (args[0].trim().equalsIgnoreCase("me")) {
|
||||
if (!(sender instanceof Player))
|
||||
return ReturnType.NEEDS_PLAYER;
|
||||
player = (Player) sender;
|
||||
} else {
|
||||
plugin.getLocale().getMessageOrDefault("command.give.not-a-player", "&cNot a player.")
|
||||
.sendPrefixedMessage(sender);
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack axe = plugin.getTreeDefinitionManager().getRequiredAxe();
|
||||
|
||||
if (axe == null) {
|
||||
plugin.getLocale().getMessageOrDefault("command.give.no-axe", "&cThe axe could not be loaded.")
|
||||
.sendPrefixedMessage(sender);
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
player.getInventory().addItem(axe);
|
||||
plugin.getLocale().getMessageOrDefault("command.give.given", "&fAxe given to &a%player%")
|
||||
.processPlaceholder("player", player.getName())
|
||||
.sendPrefixedMessage(sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... args) {
|
||||
List<String> suggestions = null;
|
||||
if (args.length == 1) {
|
||||
suggestions = PlayerUtils.getVisiblePlayerNames(commandSender, args[0]);
|
||||
suggestions.add("me");
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "ultimatetimber.give";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "give <player/me> (amount)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Give a required axe.";
|
||||
}
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
package com.songoda.ultimatetimber.manager;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import com.songoda.core.hooks.McMMOHook;
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.core.utils.TextUtils;
|
||||
import com.songoda.ultimatetimber.UltimateTimber;
|
||||
import com.songoda.ultimatetimber.tree.ITreeBlock;
|
||||
import com.songoda.ultimatetimber.tree.TreeBlockType;
|
||||
@ -10,13 +15,21 @@ import com.songoda.ultimatetimber.tree.TreeLoot;
|
||||
import com.songoda.ultimatetimber.utils.BlockUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TreeDefinitionManager extends Manager {
|
||||
|
||||
@ -26,6 +39,10 @@ public class TreeDefinitionManager extends Manager {
|
||||
private final Set<TreeLoot> globalLogLoot, globalLeafLoot, globalEntireTreeLoot;
|
||||
private final Set<ItemStack> globalRequiredTools;
|
||||
|
||||
private boolean globalAxeRequired;
|
||||
private ItemStack requiredAxe;
|
||||
private String requiredAxeKey;
|
||||
|
||||
public TreeDefinitionManager(UltimateTimber ultimateTimber) {
|
||||
super(ultimateTimber);
|
||||
this.random = new Random();
|
||||
@ -68,6 +85,7 @@ public class TreeDefinitionManager extends Manager {
|
||||
Set<TreeLoot> leafLoot = new HashSet<>();
|
||||
Set<TreeLoot> entireTreeLoot = new HashSet<>();
|
||||
Set<ItemStack> requiredTools = new HashSet<>();
|
||||
boolean requiredAxe;
|
||||
|
||||
for (String materialString : tree.getStringList("logs")) {
|
||||
CompatibleMaterial material = CompatibleMaterial.getMaterial(materialString);
|
||||
@ -116,8 +134,10 @@ public class TreeDefinitionManager extends Manager {
|
||||
requiredTools.add(material.getItem());
|
||||
}
|
||||
|
||||
requiredAxe = tree.getBoolean("required-axe", false);
|
||||
|
||||
this.treeDefinitions.add(new TreeDefinition(key, logMaterials, leafMaterials, saplingMaterial, plantableSoilMaterial, maxLogDistanceFromTrunk,
|
||||
maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, entireTreeLoot, requiredTools));
|
||||
maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, entireTreeLoot, requiredTools, requiredAxe));
|
||||
}
|
||||
|
||||
// Load global plantable soil
|
||||
@ -148,6 +168,94 @@ public class TreeDefinitionManager extends Manager {
|
||||
if (tool == null) continue;
|
||||
this.globalRequiredTools.add(tool);
|
||||
}
|
||||
|
||||
this.globalAxeRequired = config.getBoolean("global-required-axe", false);
|
||||
|
||||
// Load required axe
|
||||
if (config.contains("required-axe"))
|
||||
loadAxe(config);
|
||||
}
|
||||
|
||||
private void loadAxe(YamlConfiguration config) {
|
||||
|
||||
// Reset the axe loaded, but load the NBT anyway in case someone wanted to use another plugin to give it.
|
||||
this.requiredAxeKey = config.getString("required-axe.nbt");
|
||||
this.requiredAxe = null;
|
||||
|
||||
String typeString = config.getString("required-axe.type");
|
||||
|
||||
if (Strings.isNullOrEmpty(typeString)) {
|
||||
plugin.getLogger().warning("Required-axe has to have a material set.");
|
||||
return;
|
||||
}
|
||||
|
||||
CompatibleMaterial material = CompatibleMaterial.getMaterial(typeString);
|
||||
|
||||
if (material == null) {
|
||||
plugin.getLogger().warning("Material " + typeString + " is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack item = material.getItem();
|
||||
|
||||
// Apply NBT
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(item);
|
||||
nbtItem.set(requiredAxeKey, true);
|
||||
item = nbtItem.finish();
|
||||
|
||||
// Add display name and lore
|
||||
String displayName = TextUtils.formatText(config.getString("required-axe.name"));
|
||||
List<String> lore = config.getStringList("required-axe.lore").stream()
|
||||
.map(TextUtils::formatText)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName(displayName);
|
||||
meta.setLore(lore);
|
||||
|
||||
// Enchants
|
||||
for (String enchantString : config.getStringList("required-axe.enchants")) {
|
||||
String[] arr = enchantString.split(":");
|
||||
int level = arr.length > 1 ? Math.max(1, parseInt(arr[1])) : 1;
|
||||
|
||||
// Enchantment#getKey is not present on versions below 1.13
|
||||
Enchantment enchantment;
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
NamespacedKey key = NamespacedKey.minecraft(arr[0].trim().toLowerCase());
|
||||
enchantment = Enchantment.getByKey(key);
|
||||
|
||||
// Try to fall back to #getByName() if someone uses the old names.
|
||||
if (enchantment == null)
|
||||
enchantment = Enchantment.getByName(arr[0].trim());
|
||||
} else
|
||||
enchantment = Enchantment.getByName(arr[0].trim());
|
||||
|
||||
if (enchantment == null) {
|
||||
plugin.getLogger().warning("Enchantment " + arr[0].trim() + " is invalid.");
|
||||
continue;
|
||||
}
|
||||
|
||||
meta.addEnchant(enchantment, level, true);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
this.requiredAxe = item;
|
||||
}
|
||||
|
||||
private int parseInt(String str) {
|
||||
try {
|
||||
return Integer.parseInt(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack getRequiredAxe() {
|
||||
return this.requiredAxe;
|
||||
}
|
||||
|
||||
public boolean isGlobalAxeRequired() {
|
||||
return globalAxeRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -210,13 +318,24 @@ public class TreeDefinitionManager extends Manager {
|
||||
public boolean isToolValidForAnyTreeDefinition(ItemStack tool) {
|
||||
if (ConfigurationManager.Setting.IGNORE_REQUIRED_TOOLS.getBoolean())
|
||||
return true;
|
||||
|
||||
for (TreeDefinition treeDefinition : this.treeDefinitions) {
|
||||
if (treeDefinition.isRequiredAxe() || isGlobalAxeRequired()) {
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(tool);
|
||||
if (nbtItem.has(requiredAxeKey))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (TreeDefinition treeDefinition : this.treeDefinitions)
|
||||
for (ItemStack requiredTool : treeDefinition.getRequiredTools())
|
||||
if (requiredTool.getType().equals(tool.getType()))
|
||||
return true;
|
||||
|
||||
for (ItemStack requiredTool : this.globalRequiredTools)
|
||||
if (requiredTool.getType().equals(tool.getType()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -228,11 +347,20 @@ public class TreeDefinitionManager extends Manager {
|
||||
* @return True if the tool is allowed for toppling the given TreeDefinition
|
||||
*/
|
||||
public boolean isToolValidForTreeDefinition(TreeDefinition treeDefinition, ItemStack tool) {
|
||||
|
||||
if (ConfigurationManager.Setting.IGNORE_REQUIRED_TOOLS.getBoolean())
|
||||
return true;
|
||||
|
||||
// If the tree definition requires the custom axe, don't allow any other checks to pass.
|
||||
if (treeDefinition.isRequiredAxe() || isGlobalAxeRequired()) {
|
||||
NBTItem nbtItem = NmsManager.getNbt().of(tool);
|
||||
return nbtItem.has(requiredAxeKey);
|
||||
}
|
||||
|
||||
for (ItemStack requiredTool : treeDefinition.getRequiredTools())
|
||||
if (requiredTool.getType().equals(tool.getType()))
|
||||
return true;
|
||||
|
||||
for (ItemStack requiredTool : this.globalRequiredTools)
|
||||
if (requiredTool.getType().equals(tool.getType()))
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user