Fix arrow dupe bug

Fixes #4430
This commit is contained in:
nossr50 2021-02-26 16:06:13 -08:00
parent 82b0304091
commit 735a90fb35
4 changed files with 108 additions and 7 deletions

View File

@ -1,5 +1,6 @@
Version 2.1.175
Fixed a bug where mcMMO would occasionally give a 65 item stack from a double smelt on a furnace
Fixed a bug where arrows could be duped when fired from a crossbow with piercing enchantment
Version 2.1.174
Some legacy color codes in our locale file were swapped to &-code equivalents (thanks ViaSnake)

View File

@ -19,6 +19,7 @@ import com.gmail.nossr50.skills.taming.Taming;
import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer;
@ -156,8 +157,7 @@ public class EntityListener implements Listener {
Player player = (Player) event.getEntity().getShooter();
/* WORLD GUARD MAIN FLAG CHECK */
if(WorldGuardUtils.isWorldGuardLoaded())
{
if(WorldGuardUtils.isWorldGuardLoaded()) {
if(!WorldGuardManager.getInstance().hasMainFlag(player))
return;
}
@ -174,10 +174,9 @@ public class EntityListener implements Listener {
if(!projectile.hasMetadata(mcMMO.arrowDistanceKey))
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation()));
for (Enchantment enchantment : player.getInventory().getItemInMainHand().getEnchantments().keySet()) {
if (enchantment.getKey().equals(piercingEnchantment)) {
return;
}
//Check both hands
if(ItemUtils.doesPlayerHaveEnchantmentInHands(player, "piercing")) {
return;
}
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ARCHERY_ARROW_RETRIEVAL, player)) {

View File

@ -10,6 +10,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.FurnaceRecipe;
@ -18,6 +19,7 @@ import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@ -35,14 +37,98 @@ public final class ItemUtils {
* @param item Item to check
* @return true if the item is a bow, false otherwise
*/
public static boolean isBow(ItemStack item) {
public static boolean isBow(@NotNull ItemStack item) {
return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
}
public static boolean isCrossbow(@NotNull ItemStack item) {
return mcMMO.getMaterialMapStore().isCrossbow(item.getType().getKey().getKey());
}
public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == material;
}
public static boolean doesPlayerHaveEnchantmentOnArmor(@NotNull Player player, @NotNull String enchantmentByName) {
Enchantment enchantment = getEnchantment(enchantmentByName);
if(enchantment == null)
return false;
return doesPlayerHaveEnchantmentOnArmor(player, enchantment);
}
public static boolean doesPlayerHaveEnchantmentOnArmor(@NotNull Player player, @NotNull Enchantment enchantment) {
for(ItemStack itemStack : player.getInventory().getArmorContents()) {
if(itemStack != null) {
if(hasEnchantment(itemStack, enchantment))
return true;
}
}
return false;
}
public static boolean doesPlayerHaveEnchantmentOnArmorOrHands(@NotNull Player player, @NotNull String enchantmentName) {
Enchantment enchantment = getEnchantment(enchantmentName);
if(enchantment == null)
return false;
return doesPlayerHaveEnchantmentOnArmorOrHands(player, enchantment);
}
public static boolean doesPlayerHaveEnchantmentOnArmorOrHands(@NotNull Player player, @NotNull Enchantment enchantment) {
if(doesPlayerHaveEnchantmentOnArmor(player, enchantment))
return true;
if(doesPlayerHaveEnchantmentInHands(player, enchantment))
return true;
return false;
}
public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull NamespacedKey enchantmentNameKey) {
Enchantment enchantment = Enchantment.getByKey(enchantmentNameKey);
if(enchantment == null)
return false;
return doesPlayerHaveEnchantmentInHands(player, enchantment);
}
public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull String enchantmentName) {
Enchantment enchantment = getEnchantment(enchantmentName);
if(enchantment == null)
return false;
return doesPlayerHaveEnchantmentInHands(player, enchantment);
}
public static boolean doesPlayerHaveEnchantmentInHands(@NotNull Player player, @NotNull Enchantment enchantment) {
return hasEnchantment(player.getInventory().getItemInMainHand(), enchantment) ||
hasEnchantment(player.getInventory().getItemInOffHand(), enchantment);
}
public static boolean hasEnchantment(@NotNull ItemStack itemStack, @NotNull Enchantment enchantment) {
if(itemStack.getItemMeta() != null) {
return itemStack.getItemMeta().hasEnchant(enchantment);
}
return false;
}
public static @Nullable Enchantment getEnchantment(@NotNull String enchantmentName) {
for(Enchantment enchantment : Enchantment.values()) {
if(enchantment.getKey().getKey().equalsIgnoreCase(enchantmentName)) {
return enchantment;
}
}
return null;
}
/**
* Checks if the item is a sword.
*

View File

@ -49,6 +49,7 @@ public class MaterialMapStore {
private final @NotNull HashSet<String> pickAxes;
private final @NotNull HashSet<String> tridents;
private final @NotNull HashSet<String> bows;
private final @NotNull HashSet<String> crossbows;
private final @NotNull HashSet<String> tools;
private final @NotNull HashSet<String> enchantables;
@ -88,6 +89,7 @@ public class MaterialMapStore {
diamondTools = new HashSet<>();
netheriteTools = new HashSet<>();
bows = new HashSet<>();
crossbows = new HashSet<>();
stringTools = new HashSet<>();
tools = new HashSet<>();
@ -447,6 +449,7 @@ public class MaterialMapStore {
fillTridents();
fillStringTools();
fillBows();
fillCrossbows();
//Tools collection
tools.addAll(woodTools);
@ -464,6 +467,10 @@ public class MaterialMapStore {
bows.add("bow");
}
private void fillCrossbows() {
crossbows.add("crossbow");
}
private void fillStringTools() {
stringTools.add("bow");
stringTools.add("fishing_rod");
@ -771,6 +778,14 @@ public class MaterialMapStore {
return bows.contains(id);
}
public boolean isCrossbow(@NotNull Material material) {
return isCrossbow(material.getKey().getKey());
}
public boolean isCrossbow(@NotNull String id) {
return crossbows.contains(id);
}
public boolean isLeatherArmor(@NotNull Material material) {
return isLeatherArmor(material.getKey().getKey());
}