SongodaCore/Core/src/main/java/com/songoda/core/world/SItemStack.java

123 lines
3.9 KiB
Java

package com.songoda.core.world;
import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.compatibility.CompatibleSound;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.Nms;
import org.bukkit.Bukkit;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
public class SItemStack {
protected final com.songoda.core.nms.world.SItemStack sItem;
protected final ItemStack item;
public SItemStack(ItemStack item) {
this.item = item;
this.sItem = Nms.getImplementations().getWorld().getItemStack(item);
}
public SItemStack(CompatibleHand hand, Player player) {
this.item = hand.getItem(player);
this.sItem = Nms.getImplementations().getWorld().getItemStack(item);
}
public ItemStack addDamage(Player player, int damage) {
return addDamage(player, damage, false);
}
/**
* Damage the selected item
*
* @param player the player whose item you want to damage
* @param damage the amount of damage to apply to the item
*/
public ItemStack addDamage(Player player, int damage, boolean respectVanillaUnbreakingEnchantments) {
if (item == null) {
return null;
}
if (item.getItemMeta() == null) {
return item;
}
int maxDurability = item.getType().getMaxDurability();
int durability;
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_11)
? Nms.getImplementations().getNbt().of(item).has("Unbreakable")
: item.getItemMeta().isUnbreakable()) {
return item;
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
// ItemStack.setDurability(short) still works in 1.13-1.14, but use these methods now
ItemMeta meta = item.getItemMeta();
if (meta instanceof Damageable) {
Damageable damageable = ((Damageable) meta);
if (respectVanillaUnbreakingEnchantments) {
damage = shouldApplyDamage(meta.getEnchantLevel(Enchantment.DURABILITY), damage);
}
damageable.setDamage(((Damageable) meta).getDamage() + damage);
item.setItemMeta(meta);
durability = damageable.getDamage();
} else {
return item;
}
} else {
if (respectVanillaUnbreakingEnchantments) {
damage = shouldApplyDamage(item.getEnchantmentLevel(Enchantment.DURABILITY), damage);
}
item.setDurability((short) Math.max(0, item.getDurability() + damage));
durability = item.getDurability();
}
if (durability >= maxDurability && player != null) {
destroy(player);
}
return item;
}
public void destroy(Player player) {
destroy(player, 1);
}
public void destroy(Player player, int amount) {
PlayerItemBreakEvent breakEvent = new PlayerItemBreakEvent(player, item);
Bukkit.getServer().getPluginManager().callEvent(breakEvent);
sItem.breakItem(player, amount);
CompatibleSound.ENTITY_ITEM_BREAK.play(player);
}
public ItemStack getItem() {
return item;
}
private static int shouldApplyDamage(int unbreakingEnchantLevel, int damageAmount) {
int result = 0;
for (int i = 0; i < damageAmount; ++i) {
if (shouldApplyDamage(unbreakingEnchantLevel)) {
++result;
}
}
return result;
}
private static boolean shouldApplyDamage(int unbreakingEnchantLevel) {
if (unbreakingEnchantLevel <= 0) {
return true;
}
return Math.random() <= 1.0 / (unbreakingEnchantLevel + 1);
}
}