mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-22 04:37:42 +01:00
Untargeted weapon durability changes
This commit is contained in:
parent
cd5421b781
commit
8253113d33
@ -95,7 +95,7 @@ public class MMOItems extends LuminePlugin {
|
||||
private VaultSupport vaultSupport;
|
||||
private RPGHandler rpgPlugin;
|
||||
|
||||
private static final int MYTHICLIB_COMPATIBILITY_INDEX = 7;
|
||||
private static final int MYTHICLIB_COMPATIBILITY_INDEX = 8;
|
||||
|
||||
public MMOItems() { plugin = this; }
|
||||
|
||||
|
@ -13,7 +13,6 @@ import net.Indyuce.mmoitems.api.event.item.CustomDurabilityRepair;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.util.LoreUpdate;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import net.Indyuce.mmoitems.stat.data.DoubleData;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -23,8 +22,8 @@ import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@ -38,213 +37,188 @@ import java.util.Random;
|
||||
* @author indyuce
|
||||
*/
|
||||
public class DurabilityItem {
|
||||
private final NBTItem nbtItem;
|
||||
@Nullable
|
||||
private final Player player;
|
||||
private final int maxDurability, unbreakingLevel, initialDurability;
|
||||
private final boolean barHidden;
|
||||
private final NBTItem nbtItem;
|
||||
private final int maxDurability, unbreakingLevel, initialDurability;
|
||||
private final boolean barHidden;
|
||||
private final Player player;
|
||||
|
||||
private int durability;
|
||||
private int durability;
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* Use to handle durability changes for MMOItems
|
||||
* without using heavy MMOItem class methods.
|
||||
*
|
||||
* @param player Player holding the item
|
||||
* @param item Item with durability
|
||||
*/
|
||||
public DurabilityItem(@Nullable Player player, @NotNull ItemStack item) {
|
||||
this(player, NBTItem.get(item));
|
||||
}
|
||||
/**
|
||||
* Use to handle durability changes for MMOItems
|
||||
* without using heavy MMOItem class methods.
|
||||
*
|
||||
* @param player Player holding the item
|
||||
* @param item Item with durability
|
||||
*/
|
||||
public DurabilityItem(@NotNull Player player, @NotNull ItemStack item) {
|
||||
this(player, NBTItem.get(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to handle durability changes for MMOItems
|
||||
* without using heavy MMOItem class methods
|
||||
*
|
||||
* @param player Player holding the item
|
||||
* @param item Item with durability
|
||||
*/
|
||||
public DurabilityItem(@Nullable Player player, @NotNull NBTItem item) {
|
||||
/*Validate.notNull(this.player = player, "Player cannot be null");*/
|
||||
this.player = player;
|
||||
Validate.notNull(nbtItem = item, "Item cannot be null");
|
||||
/**
|
||||
* Use to handle durability changes for MMOItems
|
||||
* without using heavy MMOItem class methods
|
||||
*
|
||||
* @param player Player holding the item
|
||||
* @param nbtItem Item with durability
|
||||
*/
|
||||
public DurabilityItem(@NotNull Player player, @NotNull NBTItem nbtItem) {
|
||||
this.player = Objects.requireNonNull(player, "Player cannot be null");
|
||||
this.nbtItem = Objects.requireNonNull(nbtItem, "Item cannot be null");
|
||||
|
||||
maxDurability = nbtItem.getInteger("MMOITEMS_MAX_DURABILITY");
|
||||
initialDurability = durability = nbtItem.hasTag("MMOITEMS_DURABILITY") ? nbtItem.getInteger("MMOITEMS_DURABILITY") : maxDurability;
|
||||
barHidden = nbtItem.getBoolean("MMOITEMS_DURABILITY_BAR");
|
||||
maxDurability = nbtItem.getInteger("MMOITEMS_MAX_DURABILITY");
|
||||
initialDurability = durability = nbtItem.hasTag("MMOITEMS_DURABILITY") ? nbtItem.getInteger("MMOITEMS_DURABILITY") : maxDurability;
|
||||
barHidden = nbtItem.getBoolean("MMOITEMS_DURABILITY_BAR");
|
||||
|
||||
unbreakingLevel = (nbtItem.getItem().getItemMeta() != null && nbtItem.getItem().getItemMeta().hasEnchant(Enchantment.DURABILITY)) ?
|
||||
nbtItem.getItem().getItemMeta().getEnchantLevel(Enchantment.DURABILITY) :
|
||||
0;
|
||||
}
|
||||
unbreakingLevel = (nbtItem.getItem().getItemMeta() != null && nbtItem.getItem().getItemMeta().hasEnchant(Enchantment.DURABILITY)) ?
|
||||
nbtItem.getItem().getItemMeta().getEnchantLevel(Enchantment.DURABILITY) : 0;
|
||||
}
|
||||
|
||||
@Nullable public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public int getMaxDurability() {
|
||||
return maxDurability;
|
||||
}
|
||||
public int getMaxDurability() {
|
||||
return maxDurability;
|
||||
}
|
||||
|
||||
public int getDurability() {
|
||||
return durability;
|
||||
}
|
||||
public int getDurability() {
|
||||
return durability;
|
||||
}
|
||||
|
||||
// If the green vanilla durability bar should show
|
||||
public boolean isBarHidden() {
|
||||
return barHidden;
|
||||
}
|
||||
public boolean isBarHidden() {
|
||||
return barHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Not used anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isUnbreakable() {
|
||||
return nbtItem.getBoolean("Unbreakable");
|
||||
}
|
||||
public int getUnbreakingLevel() {
|
||||
return unbreakingLevel;
|
||||
}
|
||||
|
||||
public int getUnbreakingLevel() {
|
||||
return unbreakingLevel;
|
||||
}
|
||||
public NBTItem getNBTItem() {
|
||||
return nbtItem;
|
||||
}
|
||||
|
||||
public NBTItem getNBTItem() {
|
||||
return nbtItem;
|
||||
}
|
||||
public boolean isBroken() {
|
||||
return durability <= 0;
|
||||
}
|
||||
|
||||
public boolean isBroken() {
|
||||
return nbtItem.hasTag("MMOITEMS_DURABILITY") && durability <= 0;
|
||||
}
|
||||
public boolean isLostWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_WILL_BREAK");
|
||||
}
|
||||
|
||||
public boolean isLostWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_WILL_BREAK");
|
||||
}
|
||||
public boolean isDowngradedWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_BREAK_DOWNGRADE");
|
||||
}
|
||||
public boolean isDowngradedWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_BREAK_DOWNGRADE");
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Assuming you already called {@link #isDowngradedWhenBroken()}</b>, when the item is
|
||||
* being broken. This method will downgrade the item for one level and apply changes to
|
||||
* the stored {@link #getNBTItem()}.
|
||||
*
|
||||
* If the item cannot be downgraded (due to not having upgrade data / reaching minimum
|
||||
* upgrades), this method will return <code>null</code>, no change will be made to the
|
||||
* NBTItem, and you should break the item.
|
||||
*
|
||||
* @return If the item could not be downgraded, and thus should break, will be <code>null</code>.
|
||||
* If the item was successfully downgraded, this will uuuh, will return the NBTItem of
|
||||
* the downgraded version.
|
||||
*/
|
||||
@Nullable public ItemStack shouldBreakWhenDowngraded() {
|
||||
ItemTag uTag = ItemTag.getTagAtPath(ItemStats.UPGRADE.getNBTPath(), getNBTItem(), SupportedNBTTagValues.STRING);
|
||||
if (uTag == null) { return null; }
|
||||
/**
|
||||
* @return If the item actually supports custom durability. It is completely
|
||||
* disabled when the player is in creative mode just like vanilla durability.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return maxDurability > 0 && player.getGameMode() != GameMode.CREATIVE;
|
||||
}
|
||||
|
||||
try {
|
||||
public DurabilityItem addDurability(int gain) {
|
||||
Validate.isTrue(gain > 0, "Durability gain must be greater than 0");
|
||||
|
||||
// Read data
|
||||
UpgradeData data = new UpgradeData(new JsonParser().parse((String) uTag.getValue()).getAsJsonObject());
|
||||
CustomDurabilityRepair event = new CustomDurabilityRepair(this, gain);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return this;
|
||||
|
||||
// If it cannot be downgraded (reached min), DEATH
|
||||
if (data.getLevel() <= data.getMin()) { return null; }
|
||||
durability = Math.min(durability + gain, maxDurability);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Downgrading operation
|
||||
LiveMMOItem mmo = new LiveMMOItem(getNBTItem());
|
||||
public DurabilityItem decreaseDurability(int loss) {
|
||||
Validate.isTrue(loss > 0, "Loss must be greater than 0");
|
||||
|
||||
// Remove one level
|
||||
mmo.getUpgradeTemplate().upgradeTo(mmo, data.getLevel() - 1);
|
||||
/*
|
||||
* Calculate the chance of the item not losing any durability because of
|
||||
* the vanilla unbreaking enchantment ; an item with unbreaking X has 1
|
||||
* 1 chance out of (X + 1) to lose a durability point, that's 50% chance
|
||||
* -> 33% chance -> 25% chance -> 20% chance...
|
||||
*/
|
||||
if (getUnbreakingLevel() > 0 && RANDOM.nextInt(getUnbreakingLevel()) != 0)
|
||||
return this;
|
||||
|
||||
// Build NBT
|
||||
NBTItem preRet = mmo.newBuilder().buildNBT();
|
||||
CustomDurabilityDamage event = new CustomDurabilityDamage(this, loss);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return this;
|
||||
|
||||
// Set durability to zero (full repair)
|
||||
DurabilityItem dur = new DurabilityItem(getPlayer(), preRet);
|
||||
dur.addDurability(dur.getMaxDurability());
|
||||
durability = Math.max(0, Math.min(durability - loss, maxDurability));
|
||||
|
||||
// Yes
|
||||
return dur.toItem();
|
||||
// Play sound when item breaks
|
||||
if (isBroken()) {
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
PlayerData.get(player).getInventory().scheduleUpdate();
|
||||
}
|
||||
|
||||
} catch (JsonSyntaxException |IllegalStateException exception) { return null; }
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since
|
||||
*
|
||||
* @return If the item actually supports custom durability.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return maxDurability > 0 && player != null && player.getGameMode() != GameMode.CREATIVE;
|
||||
}
|
||||
/**
|
||||
* This method not only generates the newest item version taking into account
|
||||
* 1) item damage
|
||||
* 2) item breaking
|
||||
* 3) item downgrade
|
||||
*
|
||||
* @return Newest version of the damaged item
|
||||
*/
|
||||
public ItemStack toItem() {
|
||||
|
||||
public DurabilityItem addDurability(int gain) {
|
||||
Validate.isTrue(gain > 0, "Durability gain must be greater than 0");
|
||||
// No modification needs to be done
|
||||
if (durability == initialDurability)
|
||||
return nbtItem.getItem();
|
||||
|
||||
CustomDurabilityRepair event = new CustomDurabilityRepair(this, gain);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return this;
|
||||
// Checks for possible downgrade
|
||||
ItemTag uTag = ItemTag.getTagAtPath(ItemStats.UPGRADE.getNBTPath(), getNBTItem(), SupportedNBTTagValues.STRING);
|
||||
if (uTag != null)
|
||||
try {
|
||||
UpgradeData data = new UpgradeData(new JsonParser().parse((String) uTag.getValue()).getAsJsonObject());
|
||||
|
||||
durability = Math.min(durability + gain, maxDurability);
|
||||
return this;
|
||||
}
|
||||
// If it cannot be downgraded (reached min), DEATH
|
||||
if (data.getLevel() <= data.getMin())
|
||||
return null;
|
||||
|
||||
public DurabilityItem decreaseDurability(int loss) {
|
||||
CustomDurabilityDamage event = new CustomDurabilityDamage(this, loss);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled())
|
||||
return this;
|
||||
// Remove one level and FULLY repair item
|
||||
LiveMMOItem mmo = new LiveMMOItem(getNBTItem());
|
||||
mmo.getUpgradeTemplate().upgradeTo(mmo, data.getLevel() - 1);
|
||||
NBTItem preRet = mmo.newBuilder().buildNBT();
|
||||
preRet.addTag(new ItemTag("MMOITEMS_DURABILITY", maxDurability));
|
||||
return preRet.toItem();
|
||||
|
||||
/*
|
||||
* Calculate the chance of the item not losing any durability because of
|
||||
* the vanilla unbreaking enchantment ; an item with unbreaking X has 1
|
||||
* 1 chance out of (X + 1) to lose a durability point, that's 50% chance
|
||||
* -> 33% chance -> 25% chance -> 20% chance...
|
||||
*/
|
||||
if (getUnbreakingLevel() > 0 && RANDOM.nextInt(getUnbreakingLevel()) > 0)
|
||||
return this;
|
||||
} catch (JsonSyntaxException | IllegalStateException ignored) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
durability = Math.max(0, Math.min(durability - loss, maxDurability));
|
||||
/*
|
||||
* Cross multiplication to display the current item durability on the
|
||||
* item durability bar. (1 - ratio) because minecraft works with item
|
||||
* damage, and item damage is the complementary of the remaining
|
||||
* durability.
|
||||
*
|
||||
* Make sure the vanilla bar displays at least 1 damage for display
|
||||
* issues. Also makes sure the item can be mended using the vanilla
|
||||
* enchant.
|
||||
*/
|
||||
if (!barHidden) {
|
||||
int damage = (durability == maxDurability) ? 0 : Math.max(1, (int) ((1. - ((double) durability / maxDurability)) * nbtItem.getItem().getType().getMaxDurability()));
|
||||
nbtItem.addTag(new ItemTag("Damage", damage));
|
||||
}
|
||||
|
||||
// When the item breaks
|
||||
if (durability <= 0 && player != null) {
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
|
||||
PlayerData.get(player).getInventory().scheduleUpdate();
|
||||
}
|
||||
nbtItem.addTag(new ItemTag("MMOITEMS_DURABILITY", durability));
|
||||
|
||||
return this;
|
||||
}
|
||||
// Apply the NBT tags
|
||||
ItemStack item = nbtItem.toItem();
|
||||
|
||||
public ItemStack toItem() {
|
||||
|
||||
// No modification needs to be done
|
||||
if (durability == initialDurability)
|
||||
return nbtItem.getItem();
|
||||
|
||||
/*
|
||||
* Cross multiplication to display the current item durability on the
|
||||
* item durability bar. (1 - ratio) because minecraft works with item
|
||||
* damage, and item damage is the complementary of the remaining
|
||||
* durability.
|
||||
*
|
||||
* Make sure the vanilla bar displays at least 1 damage for display
|
||||
* issues. Also makes sure the item can be mended using the vanilla
|
||||
* enchant.
|
||||
*/
|
||||
if (!barHidden) {
|
||||
int damage = (durability == maxDurability) ? 0
|
||||
: Math.max(1, (int) ((1. - ((double) durability / maxDurability)) * nbtItem.getItem().getType().getMaxDurability()));
|
||||
nbtItem.addTag(new ItemTag("Damage", damage)); }
|
||||
|
||||
nbtItem.addTag(new ItemTag("MMOITEMS_DURABILITY", durability));
|
||||
|
||||
// Apply the NBT tags
|
||||
ItemStack item = nbtItem.toItem();
|
||||
|
||||
// Item lore update
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", String.valueOf(maxDurability)));
|
||||
String old = format.replace("#c", String.valueOf(initialDurability));
|
||||
String replaced = format.replace("#c", String.valueOf(durability));
|
||||
return new LoreUpdate(item, old, replaced).updateLore();
|
||||
}
|
||||
// Item lore update
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", String.valueOf(maxDurability)));
|
||||
String old = format.replace("#c", String.valueOf(initialDurability));
|
||||
String replaced = format.replace("#c", String.valueOf(durability));
|
||||
return new LoreUpdate(item, old, replaced).updateLore();
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +1,38 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.util;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class UntargetedDurabilityItem extends DurabilityItem {
|
||||
private final EquipmentSlot slot;
|
||||
private final EquipmentSlot slot;
|
||||
|
||||
/*
|
||||
* Allows to handle custom durability for target weapons when they are
|
||||
* left/right click while using the same durability system for both weapon
|
||||
* types
|
||||
*/
|
||||
public UntargetedDurabilityItem(Player player, NBTItem item, EquipmentSlot slot) {
|
||||
super(player, item);
|
||||
/**
|
||||
* Allows to handle custom durability for target weapons when
|
||||
* they are left/right clicked while using the same durability
|
||||
* system for both weapon types
|
||||
*/
|
||||
public UntargetedDurabilityItem(Player player, NBTItem item, EquipmentSlot slot) {
|
||||
super(player, item);
|
||||
|
||||
this.slot = slot;
|
||||
}
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UntargetedDurabilityItem decreaseDurability(int loss) {
|
||||
return (UntargetedDurabilityItem) super.decreaseDurability(loss);
|
||||
}
|
||||
@Override
|
||||
public UntargetedDurabilityItem decreaseDurability(int loss) {
|
||||
return (UntargetedDurabilityItem) super.decreaseDurability(loss);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
public void inventoryUpdate() {
|
||||
|
||||
// Cannot update null player
|
||||
if (getPlayer() == null) { return; }
|
||||
if (isBroken() && isLostWhenBroken()) {
|
||||
if (slot == EquipmentSlot.OFF_HAND)
|
||||
getPlayer().getInventory().setItemInOffHand(null);
|
||||
else
|
||||
getPlayer().getInventory().setItemInMainHand(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// If it broke (funny)
|
||||
if (isBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (isDowngradedWhenBroken()) {
|
||||
|
||||
ItemStack counterUpgraded = shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
|
||||
// Edit item
|
||||
getNBTItem().getItem().setItemMeta(counterUpgraded.getItemMeta());
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
if (slot == EquipmentSlot.OFF_HAND) {
|
||||
getPlayer().getInventory().setItemInOffHand(null);
|
||||
|
||||
} else { getPlayer().getInventory().setItemInMainHand(null); }
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getNBTItem().getItem().setItemMeta(toItem().getItemMeta());
|
||||
}
|
||||
getNBTItem().getItem().setItemMeta(toItem().getItemMeta());
|
||||
}
|
||||
}
|
||||
|
@ -26,17 +26,17 @@ public class Crossbow extends UntargetedWeapon {
|
||||
if (getPlayer().getGameMode() != GameMode.CREATIVE && !getPlayer().getInventory().containsAtLeast(new ItemStack(Material.ARROW), 1))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")),
|
||||
CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
if (durItem.isValid())
|
||||
durItem.decreaseDurability(1).update();
|
||||
durItem.decreaseDurability(1).inventoryUpdate();
|
||||
|
||||
// consume arrow
|
||||
// has to be after the CD check
|
||||
|
@ -35,17 +35,18 @@ public class Lute extends UntargetedWeapon {
|
||||
|
||||
@Override
|
||||
public void untargetedAttack(EquipmentSlot slot) {
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
double attackSpeed = 1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed"));
|
||||
if (!applyWeaponCosts(attackSpeed, CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
double attackSpeed = 1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed"));
|
||||
if (!applyWeaponCosts(attackSpeed, CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
if (durItem.isValid())
|
||||
durItem.decreaseDurability(1).update();
|
||||
durItem.decreaseDurability(1).inventoryUpdate();
|
||||
|
||||
double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7);
|
||||
double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range"));
|
||||
|
@ -28,18 +28,18 @@ public class Musket extends UntargetedWeapon {
|
||||
|
||||
@Override
|
||||
public void untargetedAttack(EquipmentSlot slot) {
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
|
||||
if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")),
|
||||
CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")),
|
||||
CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
if (durItem.isValid())
|
||||
durItem.decreaseDurability(1).update();
|
||||
durItem.decreaseDurability(1).inventoryUpdate();
|
||||
|
||||
double attackDamage = stats.getStat("ATTACK_DAMAGE");
|
||||
double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range"));
|
||||
|
@ -32,17 +32,17 @@ public class Staff extends UntargetedWeapon {
|
||||
@Override
|
||||
public void untargetedAttack(EquipmentSlot slot) {
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")),
|
||||
CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
if (durItem.isValid())
|
||||
durItem.decreaseDurability(1).update();
|
||||
durItem.decreaseDurability(1).inventoryUpdate();
|
||||
|
||||
double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 1);
|
||||
double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range"));
|
||||
|
@ -29,17 +29,17 @@ public class Whip extends UntargetedWeapon {
|
||||
@Override
|
||||
public void untargetedAttack(EquipmentSlot slot) {
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot);
|
||||
if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")),
|
||||
CooldownType.ATTACK))
|
||||
return;
|
||||
|
||||
UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot);
|
||||
if (durItem.isBroken())
|
||||
return;
|
||||
|
||||
if (durItem.isValid())
|
||||
durItem.decreaseDurability(1).update();
|
||||
durItem.decreaseDurability(1).inventoryUpdate();
|
||||
|
||||
double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7);
|
||||
double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range"));
|
||||
|
@ -1,9 +1,8 @@
|
||||
package net.Indyuce.mmoitems.api.item.mmoitem;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
@ -15,7 +14,7 @@ public abstract class ReadMMOItem extends MMOItem {
|
||||
/**
|
||||
* This class is used when reading an MMOItem from an ItemStack (the
|
||||
* opposite of ItemStackBuilder, like an ItemStackReader)
|
||||
*
|
||||
*
|
||||
* @param item
|
||||
* The NBTItem being read to generate an MMOItem
|
||||
*/
|
||||
@ -29,19 +28,11 @@ public abstract class ReadMMOItem extends MMOItem {
|
||||
public int getDamage() {
|
||||
|
||||
// Does it use custom durability?
|
||||
if (hasData(ItemStats.MAX_DURABILITY)) {
|
||||
if (hasData(ItemStats.MAX_DURABILITY))
|
||||
return getNBT().hasTag("MMOITEMS_DURABILITY") ? getNBT().getInteger("MMOITEMS_MAX_DURABILITY") - getNBT().getInteger("MMOITEMS_DURABILITY") : 0;
|
||||
|
||||
// Use the correct class
|
||||
DurabilityItem dItem = new DurabilityItem(null, getNBT());
|
||||
|
||||
int max = dItem.getMaxDurability();
|
||||
int current = dItem.getDurability();
|
||||
|
||||
// Difference
|
||||
return max - current;
|
||||
|
||||
// Its using vanilla durability-yo
|
||||
} else {
|
||||
// Its using vanilla durability-yo
|
||||
else {
|
||||
|
||||
// Uh use the item stack I guess
|
||||
ItemStack asStack = getNBT().getItem();
|
||||
|
@ -22,145 +22,115 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DurabilityListener implements Listener {
|
||||
private final List<DamageCause> ignoredCauses = Arrays.asList(DamageCause.DROWNING, DamageCause.SUICIDE, DamageCause.FALL, DamageCause.VOID,
|
||||
DamageCause.FIRE_TICK, DamageCause.SUFFOCATION, DamageCause.POISON, DamageCause.WITHER, DamageCause.STARVATION, DamageCause.MAGIC);
|
||||
private final List<DamageCause> ignoredCauses = Arrays.asList(DamageCause.DROWNING, DamageCause.SUICIDE, DamageCause.FALL, DamageCause.VOID,
|
||||
DamageCause.FIRE_TICK, DamageCause.SUFFOCATION, DamageCause.POISON, DamageCause.WITHER, DamageCause.STARVATION, DamageCause.MAGIC);
|
||||
|
||||
private final EquipmentSlot[] armorSlots = { EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET };
|
||||
private final EquipmentSlot[] armorSlots = {EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET};
|
||||
|
||||
/**
|
||||
* Handles custom durability for non-'vanilla durability' items
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerDamage(EntityDamageEvent event) {
|
||||
if (event.getEntityType() != EntityType.PLAYER || ignoredCauses.contains(event.getCause()))
|
||||
return;
|
||||
/**
|
||||
* Handles custom durability for non-'vanilla durability' items
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerDamage(EntityDamageEvent event) {
|
||||
if (event.getEntityType() != EntityType.PLAYER || ignoredCauses.contains(event.getCause()))
|
||||
return;
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
int damage = Math.max((int) event.getDamage() / 4, 1);
|
||||
for (EquipmentSlot slot : armorSlots)
|
||||
if (hasItem(player, slot))
|
||||
handleVanillaDamage(player.getInventory().getItem(slot), player, slot, damage);
|
||||
}
|
||||
Player player = (Player) event.getEntity();
|
||||
int damage = Math.max((int) event.getDamage() / 4, 1);
|
||||
for (EquipmentSlot slot : armorSlots)
|
||||
if (hasItem(player, slot))
|
||||
handleVanillaDamage(player.getInventory().getItem(slot), player, slot, damage);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerMeleeAttack(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamage() == 0 || event.getCause() != DamageCause.ENTITY_ATTACK || !(event.getEntity() instanceof LivingEntity)
|
||||
|| !(event.getDamager() instanceof Player) || event.getEntity().hasMetadata("NPC") || event.getDamager().hasMetadata("NPC"))
|
||||
return;
|
||||
Player player = (Player) event.getDamager();
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerMeleeAttack(EntityDamageByEntityEvent event) {
|
||||
if (event.getDamage() == 0 || event.getCause() != DamageCause.ENTITY_ATTACK || !(event.getEntity() instanceof LivingEntity)
|
||||
|| !(event.getDamager() instanceof Player) || event.getEntity().hasMetadata("NPC") || event.getDamager().hasMetadata("NPC"))
|
||||
return;
|
||||
Player player = (Player) event.getDamager();
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
|
||||
handleVanillaDamage(item, player, EquipmentSlot.HAND, 1);
|
||||
}
|
||||
handleVanillaDamage(item, player, EquipmentSlot.HAND, 1);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerBowAttack(EntityShootBowEvent event) {
|
||||
if (!(event.getEntity() instanceof Player))
|
||||
return;
|
||||
Player player = (Player) event.getEntity();
|
||||
ItemStack item = event.getBow();
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerBowAttack(EntityShootBowEvent event) {
|
||||
if (!(event.getEntity() instanceof Player))
|
||||
return;
|
||||
Player player = (Player) event.getEntity();
|
||||
ItemStack item = event.getBow();
|
||||
|
||||
handleVanillaDamage(item, player, EquipmentSlot.HAND, 1);
|
||||
}
|
||||
handleVanillaDamage(item, player, EquipmentSlot.HAND, 1);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void itemDamage(PlayerItemDamageEvent event) {
|
||||
DurabilityItem item = new DurabilityItem(event.getPlayer(), event.getItem());
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void itemDamage(PlayerItemDamageEvent event) {
|
||||
DurabilityItem item = new DurabilityItem(event.getPlayer(), event.getItem());
|
||||
if (item.isValid()) {
|
||||
|
||||
if (item.isValid()) {
|
||||
// Calculate item durability loss
|
||||
item.decreaseDurability(event.getDamage());
|
||||
|
||||
// Calculate item durability loss
|
||||
item.decreaseDurability(event.getDamage());
|
||||
/*
|
||||
* If the item is broken and if it is meant to be lost when broken,
|
||||
* do NOT cancel the event and make sure the item is destroyed
|
||||
*/
|
||||
if (item.isBroken()) {
|
||||
|
||||
/*
|
||||
* If the item is broken and if it is meant to be lost when broken,
|
||||
* do NOT cancel the event and make sure the item is destroyed
|
||||
*/
|
||||
if (item.isBroken()) {
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (item.isDowngradedWhenBroken()) {
|
||||
// Delete item
|
||||
event.setDamage(999);
|
||||
|
||||
ItemStack counterUpgraded = item.shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
// Allow event to proceed
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Counter Event
|
||||
event.setCancelled(true);
|
||||
event.getItem().setItemMeta(counterUpgraded.getItemMeta());
|
||||
event.setCancelled(true);
|
||||
event.getItem().setItemMeta(item.toItem().getItemMeta());
|
||||
}
|
||||
}
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
event.setDamage(999);
|
||||
|
||||
// Allow event to proceed
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
event.getItem().setItemMeta(item.toItem().getItemMeta());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void mendEvent(PlayerItemMendEvent event) {
|
||||
DurabilityItem durItem = new DurabilityItem(event.getPlayer(), event.getItem());
|
||||
if (durItem.isValid()) {
|
||||
event.getItem().setItemMeta(durItem.addDurability(event.getRepairAmount()).toItem().getItemMeta());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void mendEvent(PlayerItemMendEvent event) {
|
||||
DurabilityItem durItem = new DurabilityItem(event.getPlayer(), event.getItem());
|
||||
if (durItem.isValid()) {
|
||||
event.getItem().setItemMeta(durItem.addDurability(event.getRepairAmount()).toItem().getItemMeta());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is for all the items which have 0 max durability
|
||||
* i.E which are not breakable hence the {@link Material#getMaxDurability()} call
|
||||
*/
|
||||
private void handleVanillaDamage(ItemStack stack, Player player, EquipmentSlot slot, int damage) {
|
||||
DurabilityItem item = new DurabilityItem(player, stack);
|
||||
private void handleVanillaDamage(ItemStack stack, Player player, EquipmentSlot slot, int damage) {
|
||||
DurabilityItem item = new DurabilityItem(player, stack);
|
||||
|
||||
if (item.isValid() && stack.getType().getMaxDurability() == 0) {
|
||||
item.decreaseDurability(damage);
|
||||
if (item.isValid() && stack.getType().getMaxDurability() == 0) {
|
||||
item.decreaseDurability(damage);
|
||||
|
||||
if (item.isBroken()) {
|
||||
if (item.isBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (item.isDowngradedWhenBroken()) {
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
ItemStack counterUpgraded = item.shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
// Delete item
|
||||
player.getInventory().setItem(slot, null);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f);
|
||||
|
||||
// Edit item
|
||||
player.getInventory().getItem(slot).setItemMeta(counterUpgraded.getItemMeta());
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
player.getInventory().getItem(slot).setItemMeta(item.toItem().getItemMeta());
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
player.getInventory().setItem(slot, null);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f);
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
player.getInventory().getItem(slot).setItemMeta(item.toItem().getItemMeta());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasItem(Player player, EquipmentSlot slot) {
|
||||
return player.getInventory().getItem(slot) != null && player.getInventory().getItem(slot).getType() != Material.AIR;
|
||||
}
|
||||
private boolean hasItem(Player player, EquipmentSlot slot) {
|
||||
return player.getInventory().getItem(slot) != null && player.getInventory().getItem(slot).getType() != Material.AIR;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user