From 2ef3204dde863b71ce0476902a20147eb0fec2e4 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Fri, 15 Sep 2023 03:24:01 +0800 Subject: [PATCH] custom durability --- .../api/manager/ItemManager.java | 2 + build.gradle.kts | 34 +-- .../mechanic/action/ActionManagerImpl.java | 20 ++ .../mechanic/fishing/FishingManagerImpl.java | 228 ++++++++---------- .../mechanic/item/ItemManagerImpl.java | 119 ++++++++- .../customfishing/util/ItemUtils.java | 67 +++++ 6 files changed, 318 insertions(+), 152 deletions(-) create mode 100644 plugin/src/main/java/net/momirealms/customfishing/util/ItemUtils.java diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/ItemManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/ItemManager.java index 3ade0f9c..16f37bb1 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/ItemManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/ItemManager.java @@ -73,4 +73,6 @@ public interface ItemManager { void dropItem(Player player, Location hookLocation, Location playerLocation, Loot loot, Map args); void dropItem(Location hookLocation, Location playerLocation, ItemStack itemStack); + + boolean isCustomFishingItem(ItemStack itemStack); } diff --git a/build.gradle.kts b/build.gradle.kts index ca2f9c7f..ef67483b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { allprojects { - version = "2.0-beta-0914" + version = "2.0-beta-0915" apply() apply(plugin = "java") @@ -61,18 +61,6 @@ subprojects { archiveFileName.set("CustomFishing-" + project.name + "-" + project.version + ".jar") } - if ("api" == project.name) { - publishing { - publications { - create("maven_public", MavenPublication::class) { - groupId = "net.momirealms" - artifactId = "CustomFishing-API" - from(components.getByName("java")) - } - } - } - } - publishing { publications { create("mavenJava") { @@ -84,14 +72,14 @@ subprojects { } } -// tasks.javadoc.configure { -// options.quiet() -// } -// -// if ("api" == project.name) { -// java { -// withSourcesJar() -// withJavadocJar() -// } -// } + tasks.javadoc.configure { + options.quiet() + } + + if ("api" == project.name) { + java { + withSourcesJar() + withJavadocJar() + } + } } \ No newline at end of file diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java index dc3a144b..1d782e2b 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/action/ActionManagerImpl.java @@ -86,6 +86,7 @@ public class ActionManagerImpl implements ActionManager { this.registerHologramAction(); this.registerFakeItemAction(); this.registerFishFindAction(); + this.registerFoodAction(); } public void load() { @@ -329,6 +330,25 @@ public class ActionManagerImpl implements ActionManager { }); } + private void registerFoodAction() { + registerAction("food", (args, chance) -> { + int food = (int) (ConfigUtils.getDoubleValue(args) * 2); + return condition -> { + if (Math.random() > chance) return; + Player player = condition.getPlayer(); + player.setFoodLevel(player.getFoodLevel() + food); + }; + }); + registerAction("saturation", (args, chance) -> { + double saturation = ConfigUtils.getDoubleValue(args); + return condition -> { + if (Math.random() > chance) return; + Player player = condition.getPlayer(); + player.setSaturation((float) (player.getSaturation() + saturation)); + }; + }); + } + private void registerExpAction() { registerAction("exp", (args, chance) -> { int xp = (int) args; diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java index 76b46fa1..ac3a944c 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.mechanic.fishing; import com.destroystokyo.paper.event.player.PlayerJumpEvent; +import de.tr7zw.changeme.nbtapi.NBTCompound; import de.tr7zw.changeme.nbtapi.NBTItem; import net.momirealms.customfishing.CustomFishingPluginImpl; import net.momirealms.customfishing.api.common.Pair; @@ -46,14 +47,13 @@ import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.api.util.WeightUtils; import net.momirealms.customfishing.mechanic.requirement.RequirementManagerImpl; import net.momirealms.customfishing.setting.CFConfig; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Statistic; +import net.momirealms.customfishing.util.ItemUtils; +import org.bukkit.*; import org.bukkit.entity.*; import org.bukkit.event.*; import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.player.*; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; @@ -141,30 +141,6 @@ public class FishingManagerImpl implements Listener, FishingManager { this.selectState(event); } - @EventHandler - public void onPickUp(PlayerAttemptPickupItemEvent event) { - if (event.isCancelled()) return; - ItemStack itemStack = event.getItem().getItemStack(); - NBTItem nbtItem = new NBTItem(itemStack); - if (!nbtItem.hasTag("owner")) return; - if (!Objects.equals(nbtItem.getString("owner"), event.getPlayer().getName())) { - event.setCancelled(true); - } else { - nbtItem.removeKey("owner"); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - - @EventHandler - public void onMove(InventoryPickupItemEvent event) { - if (event.isCancelled()) return; - ItemStack itemStack = event.getItem().getItemStack(); - NBTItem nbtItem = new NBTItem(itemStack); - if (!nbtItem.hasTag("owner")) return; - nbtItem.removeKey("owner"); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - @EventHandler public void onQuit(PlayerQuitEvent event) { this.removeHook(event.getPlayer().getUniqueId()); @@ -200,19 +176,6 @@ public class FishingManagerImpl implements Listener, FishingManager { } } - @EventHandler - public void onConsumeItem(PlayerItemConsumeEvent event) { - if (event.isCancelled()) return; - ItemStack itemStack = event.getItem(); - String id = plugin.getItemManager().getAnyItemID(itemStack); - Loot loot = plugin.getLootManager().getLoot(id); - if (loot != null) { - Condition condition = new Condition(event.getPlayer()); - GlobalSettings.triggerLootActions(ActionTrigger.CONSUME, condition); - loot.triggerActions(ActionTrigger.CONSUME, condition); - } - } - @EventHandler public void onLeftClick(PlayerInteractEvent event) { if (event.useItemInHand() == Event.Result.DENY) @@ -227,30 +190,6 @@ public class FishingManagerImpl implements Listener, FishingManager { } } - @EventHandler - public void onInteractWithUtils(PlayerInteractEvent event) { - if (event.useItemInHand() == Event.Result.DENY) - return; - ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand(); - if (itemStack.getType() == Material.AIR) - return; - if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_AIR || event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) - return; - - String id = plugin.getItemManager().getAnyItemID(itemStack); - EffectCarrier carrier = plugin.getEffectManager().getEffect("util", id); - if (carrier == null) - return; - Condition condition = new Condition(event.getPlayer()); - if (!RequirementManager.isRequirementsMet(carrier.getRequirements(), condition)) - return; - Action[] actions = carrier.getActions(ActionTrigger.INTERACT); - if (actions != null) - for (Action action : actions) { - action.trigger(condition); - } - } - @Override public boolean removeHook(UUID uuid) { FishHook hook = hookCacheMap.remove(uuid); @@ -275,6 +214,25 @@ public class FishingManagerImpl implements Listener, FishingManager { case CAUGHT_ENTITY -> onCaughtEntity(event); case CAUGHT_FISH -> onCaughtFish(event); case BITE -> onBite(event); + case IN_GROUND -> onInGround(event); + } + } + + private void onInGround(PlayerFishEvent event) { + final Player player = event.getPlayer(); + FishHook hook = event.getHook(); + if (player.getGameMode() != GameMode.CREATIVE) { + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand(); + if (itemStack.getType() == Material.FISHING_ROD) { + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound compound = nbtItem.getCompound("CustomFishing"); + if (compound != null && compound.hasTag("max_dur")) { + event.setCancelled(true); + hook.remove(); + ItemUtils.loseDurability(itemStack, 2); + } + } } } @@ -355,6 +313,19 @@ public class FishingManagerImpl implements Listener, FishingManager { // should not reach this but in case entity.remove(); } + return; + } + + if (player.getGameMode() != GameMode.CREATIVE) { + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand(); + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound nbtCompound = nbtItem.getCompound("CustomFishing"); + if (nbtCompound != null && nbtCompound.hasTag("max_dur")) { + event.getHook().remove(); + event.setCancelled(true); + ItemUtils.loseDurability(itemStack, 5); + } } } @@ -463,6 +434,7 @@ public class FishingManagerImpl implements Listener, FishingManager { success(temp, event.getHook()); } } + return; } } @@ -489,21 +461,27 @@ public class FishingManagerImpl implements Listener, FishingManager { if (bonus != null) tempFishingState.getEffect().merge(bonus); - if (gamingPlayer.isSuccessful()) - success(tempFishingState, fishHook); - else - fail(tempFishingState, fishHook); - gamingPlayer.cancel(); gamingPlayerMap.remove(uuid); plugin.getScheduler().runTaskSync(() -> { + + if (player.getGameMode() != GameMode.CREATIVE) + outer: { + ItemStack rod = tempFishingState.getPreparation().getRodItemStack(); + PlayerItemDamageEvent damageEvent = new PlayerItemDamageEvent(player, rod, 1, 1); + Bukkit.getPluginManager().callEvent(damageEvent); + if (damageEvent.isCancelled()) { + break outer; + } + ItemUtils.loseDurability(rod, 1); + } + fishHook.remove(); - ItemStack rod = tempFishingState.getPreparation().getRodItemStack(); - PlayerItemDamageEvent damageEvent = new PlayerItemDamageEvent(player, rod, 1); - Bukkit.getPluginManager().callEvent(damageEvent); - if (damageEvent.isCancelled()) { - return; - } + + if (gamingPlayer.isSuccessful()) + success(tempFishingState, fishHook); + else + fail(tempFishingState, fishHook); }, fishHook.getLocation()); } @@ -519,24 +497,21 @@ public class FishingManagerImpl implements Listener, FishingManager { } } - plugin.getScheduler().runTaskSync(() -> { - // call event - FishingResultEvent fishingResultEvent = new FishingResultEvent( - fishingPreparation.getPlayer(), - FishingResultEvent.Result.FAILURE, - loot, - fishingPreparation.getArgs() - ); - Bukkit.getPluginManager().callEvent(fishingResultEvent); - if (fishingResultEvent.isCancelled()) { - return; - } + // call event + FishingResultEvent fishingResultEvent = new FishingResultEvent( + fishingPreparation.getPlayer(), + FishingResultEvent.Result.FAILURE, + loot, + fishingPreparation.getArgs() + ); + Bukkit.getPluginManager().callEvent(fishingResultEvent); + if (fishingResultEvent.isCancelled()) { + return; + } - GlobalSettings.triggerLootActions(ActionTrigger.FAILURE, fishingPreparation); - loot.triggerActions(ActionTrigger.FAILURE, fishingPreparation); - fishingPreparation.triggerActions(ActionTrigger.FAILURE); - - }, hook.getLocation()); + GlobalSettings.triggerLootActions(ActionTrigger.FAILURE, fishingPreparation); + loot.triggerActions(ActionTrigger.FAILURE, fishingPreparation); + fishingPreparation.triggerActions(ActionTrigger.FAILURE); } public void success(TempFishingState state, FishHook hook) { @@ -546,47 +521,44 @@ public class FishingManagerImpl implements Listener, FishingManager { var player = fishingPreparation.getPlayer(); fishingPreparation.insertArg("{size-multiplier}", String.format("%.2f", effect.getSizeMultiplier())); - plugin.getScheduler().runTaskSync(() -> { + // call event + FishingResultEvent fishingResultEvent = new FishingResultEvent( + player, + FishingResultEvent.Result.SUCCESS, + loot, + fishingPreparation.getArgs() + ); + Bukkit.getPluginManager().callEvent(fishingResultEvent); + if (fishingResultEvent.isCancelled()) { + return; + } - // call event - FishingResultEvent fishingResultEvent = new FishingResultEvent( - player, - FishingResultEvent.Result.SUCCESS, - loot, - fishingPreparation.getArgs() - ); - Bukkit.getPluginManager().callEvent(fishingResultEvent); - if (fishingResultEvent.isCancelled()) { - return; - } - - switch (loot.getType()) { - case ITEM -> { - int amount = (int) effect.getMultipleLootChance(); - amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1; - // build the items for multiple times instead of using setAmount() to make sure that each item is unique - if (loot.getID().equals("vanilla")) { - ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId()); - if (itemStack != null) { - fishingPreparation.insertArg("{loot}", ""); - for (int i = 0; i < amount; i++) { - plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), itemStack.clone()); - doSuccessActions(loot, effect, fishingPreparation, player); - } - } - } else { + switch (loot.getType()) { + case ITEM -> { + int amount = (int) effect.getMultipleLootChance(); + amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1; + // build the items for multiple times instead of using setAmount() to make sure that each item is unique + if (loot.getID().equals("vanilla")) { + ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId()); + if (itemStack != null) { + fishingPreparation.insertArg("{loot}", ""); for (int i = 0; i < amount; i++) { - plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot, fishingPreparation.getArgs()); + plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), itemStack.clone()); doSuccessActions(loot, effect, fishingPreparation, player); } } - return; + } else { + for (int i = 0; i < amount; i++) { + plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot, fishingPreparation.getArgs()); + doSuccessActions(loot, effect, fishingPreparation, player); + } } - case ENTITY -> plugin.getEntityManager().summonEntity(hook.getLocation(), player.getLocation(), loot); - case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot); + return; } - doSuccessActions(loot, effect, fishingPreparation, player); - }, hook.getLocation()); + case ENTITY -> plugin.getEntityManager().summonEntity(hook.getLocation(), player.getLocation(), loot); + case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot); + } + doSuccessActions(loot, effect, fishingPreparation, player); } private void doSuccessActions(Loot loot, Effect effect, FishingPreparation fishingPreparation, Player player) { @@ -683,7 +655,7 @@ public class FishingManagerImpl implements Listener, FishingManager { return; } plugin.debug("Game: " + random); - startFishingGame(player, gamePair.get().left().getGameSetting(effect), gamePair.get().right()); + startFishingGame(player, Objects.requireNonNull(gamePair.get().left().getGameSetting(effect)), gamePair.get().right()); } @Override diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java index ec90c515..b783be7c 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/item/ItemManagerImpl.java @@ -24,6 +24,12 @@ import net.momirealms.customfishing.api.common.Key; import net.momirealms.customfishing.api.common.Pair; import net.momirealms.customfishing.api.common.Tuple; import net.momirealms.customfishing.api.manager.ItemManager; +import net.momirealms.customfishing.api.manager.RequirementManager; +import net.momirealms.customfishing.api.mechanic.GlobalSettings; +import net.momirealms.customfishing.api.mechanic.action.Action; +import net.momirealms.customfishing.api.mechanic.action.ActionTrigger; +import net.momirealms.customfishing.api.mechanic.condition.Condition; +import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier; import net.momirealms.customfishing.api.mechanic.item.BuildableItem; import net.momirealms.customfishing.api.mechanic.item.ItemBuilder; import net.momirealms.customfishing.api.mechanic.item.ItemLibrary; @@ -33,26 +39,40 @@ import net.momirealms.customfishing.compatibility.item.CustomFishingItemImpl; import net.momirealms.customfishing.compatibility.item.VanillaItemImpl; import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl; import net.momirealms.customfishing.setting.CFConfig; +import net.momirealms.customfishing.util.ItemUtils; import net.momirealms.customfishing.util.NBTUtils; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.event.player.PlayerAttemptPickupItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.event.player.PlayerItemMendEvent; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.plaf.IconUIResource; import java.io.File; import java.util.*; import java.util.concurrent.ThreadLocalRandom; -public class ItemManagerImpl implements ItemManager { +public class ItemManagerImpl implements ItemManager, Listener { private static ItemManager instance; private final CustomFishingPlugin plugin; @@ -71,9 +91,11 @@ public class ItemManagerImpl implements ItemManager { public void load() { this.loadItemsFromPluginFolder(); LogUtils.info("Loaded " + buildableItemMap.size() + " items."); + Bukkit.getPluginManager().registerEvents(this, plugin); } public void unload() { + HandlerList.unregisterAll(this); HashMap tempMap = new HashMap<>(this.buildableItemMap); this.buildableItemMap.clear(); for (Map.Entry entry : tempMap.entrySet()) { @@ -673,4 +695,99 @@ public class ItemManagerImpl implements ItemManager { return actualAmount; } + + @EventHandler + public void onPickUp(PlayerAttemptPickupItemEvent event) { + if (event.isCancelled()) return; + ItemStack itemStack = event.getItem().getItemStack(); + NBTItem nbtItem = new NBTItem(itemStack); + if (!nbtItem.hasTag("owner")) return; + if (!Objects.equals(nbtItem.getString("owner"), event.getPlayer().getName())) { + event.setCancelled(true); + } else { + nbtItem.removeKey("owner"); + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + } + } + + @EventHandler + public void onMove(InventoryPickupItemEvent event) { + if (event.isCancelled()) return; + ItemStack itemStack = event.getItem().getItemStack(); + NBTItem nbtItem = new NBTItem(itemStack); + if (!nbtItem.hasTag("owner")) return; + nbtItem.removeKey("owner"); + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + } + + + @EventHandler + public void onConsumeItem(PlayerItemConsumeEvent event) { + if (event.isCancelled()) return; + ItemStack itemStack = event.getItem(); + String id = getAnyItemID(itemStack); + Loot loot = plugin.getLootManager().getLoot(id); + if (loot != null) { + Condition condition = new Condition(event.getPlayer()); + GlobalSettings.triggerLootActions(ActionTrigger.CONSUME, condition); + loot.triggerActions(ActionTrigger.CONSUME, condition); + } + } + + @EventHandler + public void onRepairItem(PrepareAnvilEvent event) { + ItemStack result = event.getInventory().getResult(); + if (result == null || result.getType() == Material.AIR) return; + NBTItem nbtItem = new NBTItem(result); + NBTCompound compound = nbtItem.getCompound("CustomFishing"); + if (compound == null || !compound.hasTag("max_dur")) return; + if (!(result.getItemMeta() instanceof Damageable damageable)) { + return; + } + int max_dur = compound.getInteger("max_dur"); + compound.setInteger("cur_dur", (int) (max_dur * (1 - (double) damageable.getDamage() / result.getType().getMaxDurability()))); + event.setResult(nbtItem.getItem()); + } + + @EventHandler + public void onMending(PlayerItemMendEvent event) { + if (event.isCancelled()) return; + ItemStack itemStack = event.getItem(); + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound compound = nbtItem.getCompound("CustomFishing"); + if (compound == null) return; + event.setCancelled(true); + ItemUtils.addDurability(itemStack, event.getRepairAmount()); + } + + @EventHandler + public void onInteractWithUtils(PlayerInteractEvent event) { + if (event.useItemInHand() == Event.Result.DENY) + return; + ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand(); + if (itemStack.getType() == Material.AIR) + return; + if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_AIR || event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) + return; + + String id = getAnyItemID(itemStack); + EffectCarrier carrier = plugin.getEffectManager().getEffect("util", id); + if (carrier == null) + return; + Condition condition = new Condition(event.getPlayer()); + if (!RequirementManager.isRequirementsMet(carrier.getRequirements(), condition)) + return; + Action[] actions = carrier.getActions(ActionTrigger.INTERACT); + if (actions != null) + for (Action action : actions) { + action.trigger(condition); + } + } + + @Override + public boolean isCustomFishingItem(ItemStack itemStack) { + if (itemStack == null || itemStack.getType() == Material.AIR) return false; + NBTItem nbtItem = new NBTItem(itemStack); + return nbtItem.hasTag("CustomFishing"); + } } \ No newline at end of file diff --git a/plugin/src/main/java/net/momirealms/customfishing/util/ItemUtils.java b/plugin/src/main/java/net/momirealms/customfishing/util/ItemUtils.java new file mode 100644 index 00000000..56f4c8ff --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customfishing/util/ItemUtils.java @@ -0,0 +1,67 @@ +package net.momirealms.customfishing.util; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; + +public class ItemUtils { + + public static void loseDurability(ItemStack itemStack, int amount) { + if (itemStack.getItemMeta() instanceof Damageable damageable) { + if (damageable.isUnbreakable()) { + return; + } + int unBreakingLevel = itemStack.getEnchantmentLevel(Enchantment.DURABILITY); + if (Math.random() > (double) 1 / (unBreakingLevel + 1)) { + return; + } + + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); + if (cfCompound != null && cfCompound.hasTag("max_dur")) { + int max = cfCompound.getInteger("max_dur"); + int current = cfCompound.getInteger("cur_dur") - amount; + cfCompound.setInteger("cur_dur", current); + int damage = (int) (itemStack.getType().getMaxDurability() * (1 - ((double) current / max))); + nbtItem.setInteger("Damage", damage); + if (current > 0) { + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + } else { + itemStack.setAmount(0); + } + } else { + int damage = damageable.getDamage() + amount; + if (damage > itemStack.getType().getMaxDurability()) { + itemStack.setAmount(0); + } else { + damageable.setDamage(damage); + itemStack.setItemMeta(damageable); + } + } + } + } + + public static void addDurability(ItemStack itemStack, int amount) { + if (itemStack.getItemMeta() instanceof Damageable damageable) { + if (damageable.isUnbreakable()) { + return; + } + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound cfCompound = nbtItem.getCompound("CustomFishing"); + if (cfCompound != null && cfCompound.hasTag("max_dur")) { + int max = cfCompound.getInteger("max_dur"); + int current = Math.min(max, cfCompound.getInteger("cur_dur") + amount); + cfCompound.setInteger("cur_dur", current); + int damage = (int) (itemStack.getType().getMaxDurability() * (1 - ((double) current / max))); + nbtItem.setInteger("Damage", damage); + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + } else { + int damage = Math.max(damageable.getDamage() - amount, 0); + damageable.setDamage(damage); + itemStack.setItemMeta(damageable); + } + } + } +}