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 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 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 Version 2.1.174
Some legacy color codes in our locale file were swapped to &-code equivalents (thanks ViaSnake) 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.taming.TamingManager;
import com.gmail.nossr50.skills.unarmed.UnarmedManager; import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer; import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer;
@ -156,8 +157,7 @@ public class EntityListener implements Listener {
Player player = (Player) event.getEntity().getShooter(); Player player = (Player) event.getEntity().getShooter();
/* WORLD GUARD MAIN FLAG CHECK */ /* WORLD GUARD MAIN FLAG CHECK */
if(WorldGuardUtils.isWorldGuardLoaded()) if(WorldGuardUtils.isWorldGuardLoaded()) {
{
if(!WorldGuardManager.getInstance().hasMainFlag(player)) if(!WorldGuardManager.getInstance().hasMainFlag(player))
return; return;
} }
@ -174,11 +174,10 @@ public class EntityListener implements Listener {
if(!projectile.hasMetadata(mcMMO.arrowDistanceKey)) if(!projectile.hasMetadata(mcMMO.arrowDistanceKey))
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation())); projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation()));
for (Enchantment enchantment : player.getInventory().getItemInMainHand().getEnchantments().keySet()) { //Check both hands
if (enchantment.getKey().equals(piercingEnchantment)) { if(ItemUtils.doesPlayerHaveEnchantmentInHands(player, "piercing")) {
return; return;
} }
}
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ARCHERY_ARROW_RETRIEVAL, player)) { if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ARCHERY_ARROW_RETRIEVAL, player)) {
projectile.setMetadata(mcMMO.trackedArrow, mcMMO.metadataValue); projectile.setMetadata(mcMMO.trackedArrow, mcMMO.metadataValue);

View File

@ -10,6 +10,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.FurnaceRecipe; 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.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -35,14 +37,98 @@ public final class ItemUtils {
* @param item Item to check * @param item Item to check
* @return true if the item is a bow, false otherwise * @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()); 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) { public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == 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. * 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> pickAxes;
private final @NotNull HashSet<String> tridents; private final @NotNull HashSet<String> tridents;
private final @NotNull HashSet<String> bows; private final @NotNull HashSet<String> bows;
private final @NotNull HashSet<String> crossbows;
private final @NotNull HashSet<String> tools; private final @NotNull HashSet<String> tools;
private final @NotNull HashSet<String> enchantables; private final @NotNull HashSet<String> enchantables;
@ -88,6 +89,7 @@ public class MaterialMapStore {
diamondTools = new HashSet<>(); diamondTools = new HashSet<>();
netheriteTools = new HashSet<>(); netheriteTools = new HashSet<>();
bows = new HashSet<>(); bows = new HashSet<>();
crossbows = new HashSet<>();
stringTools = new HashSet<>(); stringTools = new HashSet<>();
tools = new HashSet<>(); tools = new HashSet<>();
@ -447,6 +449,7 @@ public class MaterialMapStore {
fillTridents(); fillTridents();
fillStringTools(); fillStringTools();
fillBows(); fillBows();
fillCrossbows();
//Tools collection //Tools collection
tools.addAll(woodTools); tools.addAll(woodTools);
@ -464,6 +467,10 @@ public class MaterialMapStore {
bows.add("bow"); bows.add("bow");
} }
private void fillCrossbows() {
crossbows.add("crossbow");
}
private void fillStringTools() { private void fillStringTools() {
stringTools.add("bow"); stringTools.add("bow");
stringTools.add("fishing_rod"); stringTools.add("fishing_rod");
@ -771,6 +778,14 @@ public class MaterialMapStore {
return bows.contains(id); 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) { public boolean isLeatherArmor(@NotNull Material material) {
return isLeatherArmor(material.getKey().getKey()); return isLeatherArmor(material.getKey().getKey());
} }