From e97036ab7b72c5512d136fbcc68223670a45568b Mon Sep 17 00:00:00 2001 From: Indyuce Date: Tue, 20 Dec 2022 12:25:44 +0100 Subject: [PATCH] Custom repairs are now comp with MMOCore --- .../java/net/Indyuce/mmoitems/ItemStats.java | 2 +- ...Repair.java => ItemCustomRepairEvent.java} | 8 ++- .../api/event/item/RepairItemEvent.java | 26 ++++---- .../api/interaction/util/DurabilityItem.java | 5 +- .../mmoitems/comp/mmocore/MMOCoreHook.java | 64 +++++++++++++++++++ .../Indyuce/mmoitems/stat/RepairPower.java | 33 +++++----- .../mmoitems/stat/RepairPowerPercent.java | 39 ++++++----- .../mmoitems/stat/RepairReference.java | 11 ++++ .../net/Indyuce/mmoitems/stat/RepairType.java | 11 ---- .../net/Indyuce/mmoitems/util/MMOUtils.java | 27 ++++++++ .../Indyuce/mmoitems/util/RepairUtils.java | 31 ++++----- 11 files changed, 171 insertions(+), 86 deletions(-) rename MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/{CustomDurabilityRepair.java => ItemCustomRepairEvent.java} (85%) create mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairReference.java delete mode 100644 MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairType.java diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java index 3430741b..ae88f41d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/ItemStats.java @@ -163,7 +163,7 @@ public class ItemStats { //todo CAN_UNSOCKET = new CanUnsocket(), REPAIR = new RepairPower(), REPAIR_PERCENT = new RepairPowerPercent(), - REPAIR_TYPE = new RepairType(), + REPAIR_TYPE = new RepairReference(), INEDIBLE = new BooleanStat("INEDIBLE", Material.POISONOUS_POTATO, "Inedible", new String[]{"Players won't be able to right-click this consumable.", "", "No effects of it will take place."}, new String[]{"consumable"}), DISABLE_RIGHT_CLICK_CONSUME = new DisableStat("RIGHT_CLICK_CONSUME", Material.BAKED_POTATO, "Infinite Consume", new String[]{"consumable"}, "Players will be able to right-click this consumable", "and benefit from its effects, but it won't be consumed."), KNOCKBACK = new DoubleStat("KNOCKBACK", VersionMaterial.IRON_HORSE_ARMOR.toMaterial(), "Knockback", new String[]{"Using this musket will knock", "the user back if positive."}, new String[]{"musket"}), diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/CustomDurabilityRepair.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/ItemCustomRepairEvent.java similarity index 85% rename from MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/CustomDurabilityRepair.java rename to MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/ItemCustomRepairEvent.java index 7513985c..b2612c22 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/CustomDurabilityRepair.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/ItemCustomRepairEvent.java @@ -7,7 +7,7 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -public class CustomDurabilityRepair extends Event implements Cancellable { +public class ItemCustomRepairEvent extends Event implements Cancellable { @NotNull private final DurabilityItem sourceItem; @@ -17,7 +17,7 @@ public class CustomDurabilityRepair extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); - public CustomDurabilityRepair(@NotNull DurabilityItem item, int impendingRepair) { + public ItemCustomRepairEvent(@NotNull DurabilityItem item, int impendingRepair) { sourceItem = item; durabilityIncrease = impendingRepair; } @@ -61,4 +61,8 @@ public class CustomDurabilityRepair extends Event implements Cancellable { public HandlerList getHandlers() { return handlers; } + + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/RepairItemEvent.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/RepairItemEvent.java index 3cc45af7..2521540c 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/RepairItemEvent.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/event/item/RepairItemEvent.java @@ -1,20 +1,21 @@ package net.Indyuce.mmoitems.api.event.item; -import org.bukkit.event.HandlerList; - +import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.api.event.PlayerDataEvent; import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem; import net.Indyuce.mmoitems.api.player.PlayerData; -import io.lumine.mythic.lib.api.item.NBTItem; +import org.bukkit.event.HandlerList; +/** + * When a consumable is used to repair a VANILLA item. + */ public class RepairItemEvent extends PlayerDataEvent { private static final HandlerList handlers = new HandlerList(); private final VolatileMMOItem consumable; private final NBTItem target; - private int repaired = -1; - private double repairedPercent = -1; + private int repaired; /** * Called when a player repairs an item using a consumable @@ -32,14 +33,6 @@ public class RepairItemEvent extends PlayerDataEvent { this.repaired = repaired; } - public RepairItemEvent(PlayerData playerData, VolatileMMOItem consumable, NBTItem target, double repaired) { - super(playerData); - - this.consumable = consumable; - this.target = target; - this.repairedPercent = repaired; - } - public VolatileMMOItem getConsumable() { return consumable; } @@ -52,12 +45,15 @@ public class RepairItemEvent extends PlayerDataEvent { return repaired; } + @Deprecated public double getRepairedPercent() { - return repairedPercent; + final boolean customWeapon = target.hasTag("MMOITEMS_DURABILITY"); + final double maxDurability = customWeapon ? target.getDouble("MMOITEMS_MAX_DURABILITY") : target.getItem().getType().getMaxDurability(); + return (double) getRepaired() / maxDurability; } public void setRepaired(int repaired) { - this.repaired = repaired; + this.repaired = Math.max(0, repaired); } public HandlerList getHandlers() { diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java index ce0271f8..084568cb 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java @@ -9,7 +9,7 @@ import io.lumine.mythic.lib.api.item.SupportedNBTTagValues; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.event.item.CustomDurabilityDamage; -import net.Indyuce.mmoitems.api.event.item.CustomDurabilityRepair; +import net.Indyuce.mmoitems.api.event.item.ItemCustomRepairEvent; import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem; import net.Indyuce.mmoitems.api.item.util.LoreUpdate; import net.Indyuce.mmoitems.api.player.PlayerData; @@ -126,10 +126,11 @@ public class DurabilityItem { return maxDurability > 0 && player.getGameMode() != GameMode.CREATIVE; } + @NotNull public DurabilityItem addDurability(int gain) { Validate.isTrue(gain > 0, "Durability gain must be greater than 0"); - CustomDurabilityRepair event = new CustomDurabilityRepair(this, gain); + ItemCustomRepairEvent event = new ItemCustomRepairEvent(this, gain); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return this; diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mmocore/MMOCoreHook.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mmocore/MMOCoreHook.java index 5a73779b..30684005 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mmocore/MMOCoreHook.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/mmocore/MMOCoreHook.java @@ -8,8 +8,13 @@ import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute; import net.Indyuce.mmocore.api.player.stats.StatType; +import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.Profession; +import net.Indyuce.mmocore.experience.source.RepairItemExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.event.item.ItemCustomRepairEvent; +import net.Indyuce.mmoitems.api.event.item.RepairItemEvent; import net.Indyuce.mmoitems.api.player.PlayerData; import net.Indyuce.mmoitems.api.player.RPGPlayer; import net.Indyuce.mmoitems.comp.mmocore.stat.ExtraAttribute; @@ -17,8 +22,12 @@ import net.Indyuce.mmoitems.comp.mmocore.stat.RequiredAttribute; import net.Indyuce.mmoitems.comp.mmocore.stat.RequiredProfession; import net.Indyuce.mmoitems.comp.rpg.RPGHandler; import net.Indyuce.mmoitems.stat.type.DoubleStat; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; import java.util.Locale; @@ -133,4 +142,59 @@ public class MMOCoreHook implements RPGHandler, Listener { data.giveStamina(value, PlayerResourceUpdateEvent.UpdateReason.OTHER); } } + + /** + * This fixes https://gitlab.com/phoenix-dvpmt/mmocore/-/issues/616 + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void handleVanillaRepairs(RepairItemEvent event) { + final ExperienceSourceManager expManager = MMOCore.plugin.experience.getManager(RepairItemExperienceSource.class); + if (expManager == null) + return; + + final ItemStack item = event.getTargetItem().getItem(); + if (!MMOCore.plugin.smithingManager.hasExperience(item.getType())) + return; + + final Player player = event.getPlayer(); + final net.Indyuce.mmocore.api.player.PlayerData playerData = net.Indyuce.mmocore.api.player.PlayerData.get(player); + final int effectiveRepair = Math.min(event.getRepaired(), ((Damageable) item.getItemMeta()).getDamage()); + + for (RepairItemExperienceSource source : expManager.getSources()) + if (source.matches(playerData, item)) { + + /* + * Calculate exp based on amount of durability which was repaired, + * substract damage from old item durability. + */ + final double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType()) * effectiveRepair / 100; + source.getDispenser().giveExperience(playerData, exp, playerData.getPlayer().getLocation(), EXPSource.SOURCE); + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void handleCustomRepairs(ItemCustomRepairEvent event) { + final ExperienceSourceManager expManager = MMOCore.plugin.experience.getManager(RepairItemExperienceSource.class); + if (expManager == null) + return; + + final ItemStack item = event.getSourceItem().getNBTItem().getItem(); + if (!MMOCore.plugin.smithingManager.hasExperience(item.getType())) + return; + + final Player player = event.getPlayer(); + final net.Indyuce.mmocore.api.player.PlayerData playerData = net.Indyuce.mmocore.api.player.PlayerData.get(player); + final int effectiveRepair = Math.min(event.getDurabilityIncrease(), event.getSourceItem().getMaxDurability() - event.getSourceItem().getDurability()); + + for (RepairItemExperienceSource source : expManager.getSources()) + if (source.matches(playerData, item)) { + + /* + * Calculate exp based on amount of durability which was repaired, + * substract damage from old item durability. + */ + final double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType()) * effectiveRepair / 100; + source.getDispenser().giveExperience(playerData, exp, playerData.getPlayer().getLocation(), EXPSource.SOURCE); + } + } } \ No newline at end of file diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java index 78fb04c7..cf9d4b14 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPower.java @@ -2,9 +2,7 @@ package net.Indyuce.mmoitems.stat; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.ItemStats; -import net.Indyuce.mmoitems.util.MMOUtils; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.event.item.RepairItemEvent; import net.Indyuce.mmoitems.api.interaction.Consumable; import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData; @@ -12,49 +10,48 @@ import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.listener.CustomSoundListener; import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.DoubleStat; +import net.Indyuce.mmoitems.util.MMOUtils; import net.Indyuce.mmoitems.util.RepairUtils; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class RepairPower extends DoubleStat implements ConsumableItemInteraction { public RepairPower() { - super("REPAIR", Material.ANVIL, "Repair", new String[]{"The amount of durability your item", "can repair when set an item."}, + super("REPAIR", Material.ANVIL, "Repair Power", new String[]{"The flat amount of durability your item", "can repair when set an item."}, new String[]{"consumable"}); } + private static final String REPAIR_TYPE_TAG = "MMOITEMS_REPAIR_TYPE"; + @Override public boolean handleConsumableEffect(@NotNull InventoryClickEvent event, @NotNull PlayerData playerData, @NotNull Consumable consumable, @NotNull NBTItem target, Type targetType) { int repairPower = (int) consumable.getNBTItem().getStat(ItemStats.REPAIR.getId()); if (repairPower <= 0) return false; - // custom durability - Player player = playerData.getPlayer(); - - final String type = "MMOITEMS_REPAIR_TYPE"; - if ((target.hasTag(type) || consumable.getNBTItem().hasTag(type)) && - !target.getString(type).equals(consumable.getNBTItem().getString(type))) { + // Check repair reference + final Player player = playerData.getPlayer(); + final @Nullable String repairType1 = target.getString(REPAIR_TYPE_TAG); + final @Nullable String repairType2 = target.getString(REPAIR_TYPE_TAG); + if (!MMOUtils.checkReference(repairType1, repairType2)) { Message.UNABLE_TO_REPAIR.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player); player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f); return false; } + // Custom durability if (target.hasTag("MMOITEMS_DURABILITY")) { - RepairItemEvent called = new RepairItemEvent(playerData, consumable.getMMOItem(), target, repairPower); - Bukkit.getPluginManager().callEvent(called); - if (called.isCancelled()) - return false; - DurabilityItem durItem = new DurabilityItem(player, target); + final DurabilityItem durItem = new DurabilityItem(player, target); if (durItem.getDurability() < durItem.getMaxDurability()) { - target.getItem().setItemMeta(durItem.addDurability(called.getRepaired()).toItem().getItemMeta()); + target.getItem().setItemMeta(durItem.addDurability(repairPower).toItem().getItemMeta()); Message.REPAIRED_ITEM - .format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(called.getRepaired())) + .format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairPower)) .send(player); CustomSoundListener.playConsumableSound(consumable.getItem(), player); } @@ -62,6 +59,6 @@ public class RepairPower extends DoubleStat implements ConsumableItemInteraction } // vanilla durability - return RepairUtils.repairVanillaItem(playerData, target, consumable, -1, repairPower); + return RepairUtils.repairVanillaItem(playerData, target, consumable, repairPower); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPowerPercent.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPowerPercent.java index d7cf0bb7..0b96f585 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPowerPercent.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairPowerPercent.java @@ -2,9 +2,7 @@ package net.Indyuce.mmoitems.stat; import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.ItemStats; -import net.Indyuce.mmoitems.util.MMOUtils; import net.Indyuce.mmoitems.api.Type; -import net.Indyuce.mmoitems.api.event.item.RepairItemEvent; import net.Indyuce.mmoitems.api.interaction.Consumable; import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem; import net.Indyuce.mmoitems.api.player.PlayerData; @@ -12,8 +10,8 @@ import net.Indyuce.mmoitems.api.util.message.Message; import net.Indyuce.mmoitems.listener.CustomSoundListener; import net.Indyuce.mmoitems.stat.type.ConsumableItemInteraction; import net.Indyuce.mmoitems.stat.type.DoubleStat; +import net.Indyuce.mmoitems.util.MMOUtils; import net.Indyuce.mmoitems.util.RepairUtils; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; @@ -29,35 +27,36 @@ public class RepairPowerPercent extends DoubleStat implements ConsumableItemInte new String[]{"consumable"}); } + private static final String REPAIR_TYPE_TAG = "MMOITEMS_REPAIR_TYPE"; + @Override public boolean handleConsumableEffect(@NotNull InventoryClickEvent event, @NotNull PlayerData playerData, @NotNull Consumable consumable, @NotNull NBTItem target, @Nullable Type targetType) { - double repairPower = consumable.getNBTItem().getStat(ItemStats.REPAIR_PERCENT.getId()); + final double repairPower = consumable.getNBTItem().getStat(ItemStats.REPAIR_PERCENT.getId()); if (repairPower <= 0) return false; - // custom durability - Player player = playerData.getPlayer(); - - final String type = "MMOITEMS_REPAIR_TYPE"; - if ((target.hasTag(type) || consumable.getNBTItem().hasTag(type)) && - !target.getString(type).equals(consumable.getNBTItem().getString(type))) { + // Check repair reference + final Player player = playerData.getPlayer(); + final @Nullable String repairType1 = target.getString(REPAIR_TYPE_TAG); + final @Nullable String repairType2 = target.getString(REPAIR_TYPE_TAG); + if (!MMOUtils.checkReference(repairType1, repairType2)) { Message.UNABLE_TO_REPAIR.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem())).send(player); player.getPlayer().playSound(player.getPlayer().getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.5f); return false; } - if (target.hasTag("MMOITEMS_DURABILITY")) { - RepairItemEvent called = new RepairItemEvent(playerData, consumable.getMMOItem(), target, repairPower); - Bukkit.getPluginManager().callEvent(called); - if (called.isCancelled()) - return false; + final boolean customWeapon = target.hasTag("MMOITEMS_DURABILITY"); + final double maxDurability = customWeapon ? target.getDouble("MMOITEMS_MAX_DURABILITY") : target.getItem().getType().getMaxDurability(); + final int repairAmount = (int) (repairPower * maxDurability); - DurabilityItem durItem = new DurabilityItem(player, target); + // Custom durability + if (customWeapon) { + + final DurabilityItem durItem = new DurabilityItem(player, target); if (durItem.getDurability() < durItem.getMaxDurability()) { - int repaired = (int) (durItem.getMaxDurability() * repairPower / 100); - target.getItem().setItemMeta(durItem.addDurability(repaired).toItem().getItemMeta()); + target.getItem().setItemMeta(durItem.addDurability(repairAmount).toItem().getItemMeta()); Message.REPAIRED_ITEM - .format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repaired)) + .format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairAmount)) .send(player); CustomSoundListener.playConsumableSound(consumable.getItem(), player); } @@ -65,6 +64,6 @@ public class RepairPowerPercent extends DoubleStat implements ConsumableItemInte } // vanilla durability - return RepairUtils.repairVanillaItem(playerData, target, consumable, repairPower, -1); + return RepairUtils.repairVanillaItem(playerData, target, consumable, repairAmount); } } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairReference.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairReference.java new file mode 100644 index 00000000..5bf80d57 --- /dev/null +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairReference.java @@ -0,0 +1,11 @@ +package net.Indyuce.mmoitems.stat; + +import net.Indyuce.mmoitems.stat.type.GemStoneStat; +import net.Indyuce.mmoitems.stat.type.StringStat; +import org.bukkit.Material; + +public class RepairReference extends StringStat implements GemStoneStat { + public RepairReference() { + super("REPAIR_TYPE", Material.ANVIL, "Repair Reference", new String[]{"If items have a repair type they can", "only be repaired by consumables", "with the same repair type.", "(And vice-versa)"}, new String[]{"all"}); + } +} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairType.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairType.java deleted file mode 100644 index 1b3a1620..00000000 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/stat/RepairType.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.Indyuce.mmoitems.stat; - -import net.Indyuce.mmoitems.stat.type.GemStoneStat; -import net.Indyuce.mmoitems.stat.type.StringStat; -import org.bukkit.Material; - -public class RepairType extends StringStat implements GemStoneStat { - public RepairType() { - super("REPAIR_TYPE", Material.ANVIL, "Repair Type", new String[]{"If items have a repair type they can", "only be repaired by consumables", "with the same repair type.", "(And vice-versa)"}, new String[]{"all"}); - } -} diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java index 513fdbcf..d47eed22 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/MMOUtils.java @@ -54,6 +54,33 @@ public class MMOUtils { } } + private static final String UNIVERSAL_REFERENCE = "all"; + + /** + * References are helpful to classify items that can interact together. + * They are a piece of text stored as an NBTTag for instance. Items can + * interact (in a certain way) only if the corresponding reference match. + *

+ * A null reference is considered just like a non-null reference. + * Any item can interact with an item with the universal reference 'all' + *

+ * TODO + * This is a simple symmetrical computation. Used for: + * - for item upgrading + * - item repairing + * + * @param ref1 First reference + * @param ref2 Second reference + * @return If items can interact + */ + public static boolean checkReference(@Nullable String ref1, @Nullable String ref2) { + if (ref1 == null) + return ref2 == null || ref2.equals(UNIVERSAL_REFERENCE); + if (ref2 == null) + return ref1 == null || ref1.equals(UNIVERSAL_REFERENCE); + return ref1.equals(UNIVERSAL_REFERENCE) || ref2.equals(UNIVERSAL_REFERENCE) || ref1.equals(ref2); + } + /** * Source: https://gist.github.com/Mystiflow/c42f45bac9916c84e381155f72a96d84 */ diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java index e4c9c9c4..6793a482 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/util/RepairUtils.java @@ -24,38 +24,35 @@ public class RepairUtils { throw new IllegalStateException("Utility class"); } - /** - * Repairs a vanilla item. - * It will not work with MMOItems items. + * Repairs a vanilla item. This method does NOT work with + * custom MI items and will NOT call the corresponding custom event. * - * @param playerData The player data. - * @param target The target item. - * @param consumable The consumable item. - * @param repairPercentage The repair percentage. (set to -1 to disable) - * @param repairUses The repair uses. (set to -1 to disable) + * @param playerData The player data. + * @param target The target item. + * @param consumable The consumable item. + * @param repairAmount The repair uses. * @return True if the item was repaired. */ - public static boolean repairVanillaItem(@NotNull PlayerData playerData, @NotNull NBTItem target, @NotNull Consumable consumable, double repairPercentage, int repairUses) { + public static boolean repairVanillaItem(@NotNull PlayerData playerData, @NotNull NBTItem target, @NotNull Consumable consumable, int repairAmount) { final Player player = playerData.getPlayer(); - final boolean percentage = repairPercentage > 0; if (target.getBoolean("Unbreakable") || !target.getItem().hasItemMeta() || !(target.getItem().getItemMeta() instanceof Damageable meta) || ((Damageable) target.getItem().getItemMeta()).getDamage() <= 0) return false; - RepairItemEvent called = percentage ? new RepairItemEvent(playerData, consumable.getMMOItem(), target, repairPercentage) : new RepairItemEvent(playerData, consumable.getMMOItem(), target, repairUses); + + final RepairItemEvent called = new RepairItemEvent(playerData, consumable.getMMOItem(), target, repairAmount); Bukkit.getPluginManager().callEvent(called); if (called.isCancelled()) return false; - int repaired = percentage ? (int) ((repairPercentage / 100) * target.getItem().getType().getMaxDurability()) : repairUses; - meta.setDamage(Math.max(0, meta.getDamage() - repaired)); + + repairAmount = called.getRepaired(); + meta.setDamage(Math.max(0, meta.getDamage() - repairAmount)); target.getItem().setItemMeta(meta); Message.REPAIRED_ITEM.format(ChatColor.YELLOW, - "#item#", - MMOUtils.getDisplayName(target.getItem()), - "#amount#", - String.valueOf(repaired)) + "#item#", MMOUtils.getDisplayName(target.getItem()), + "#amount#", String.valueOf(repairAmount)) .send(player); CustomSoundListener.playConsumableSound(consumable.getItem(), player); return true;