Use unbreakable item meta flag for unbreakable weapons and armor.

This changes how unbreakable items work in MobArena. It removes the legacy "repair logic" and replaces it with the item meta unbreakable flag. This approach should work all the same, except now if weapons and armor in class chests have special durability values, these are preserved in the cloning.

This should make MobArena compatible with plugins that depend on special durability values, such as QualityArmory.
This commit is contained in:
Andreas Troelsen 2018-09-23 15:44:54 +02:00
parent fe5571c75b
commit 32499dbe11
3 changed files with 23 additions and 54 deletions

View File

@ -12,6 +12,7 @@ These changes will (most likely) be included in the next version.
## [Unreleased]
- Like the other user commands, the permission for `/ma ready` now defaults to true.
- Unbreakable weapons and armor now use the unbreakable item flag instead of item durability and on-hit repairs. This means that MobArena's unbreakable items are now compatible with plugins that depend on special durability values, such as QualityArmory.
## [0.103] - 2018-08-28
- It is now possible to add a fixed delay (in seconds) between waves with the new per-arena setting `next-wave-delay`.

View File

@ -47,6 +47,7 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.potion.PotionEffect;
@ -1168,6 +1169,9 @@ public class ArenaImpl implements Arena
int last = contents.length-1;
if (contents[last] != null) {
helmet = contents[last].clone();
if (arenaClass.hasUnbreakableArmor()) {
makeUnbreakable(helmet);
}
contents[last] = null;
}
@ -1177,6 +1181,10 @@ public class ArenaImpl implements Arena
ArmorType type = ArmorType.getType(contents[i]);
if (type == null || type == ArmorType.HELMET) continue;
ItemStack stack = contents[i].clone();
if (arenaClass.hasUnbreakableArmor()) {
makeUnbreakable(stack);
}
switch (type) {
case CHESTPLATE: chestplate = contents[i].clone(); break;
case LEGGINGS: leggings = contents[i].clone(); break;
@ -1190,6 +1198,12 @@ public class ArenaImpl implements Arena
ItemStack fifth = contents[contents.length - 5];
if (fifth != null) {
offhand = fifth.clone();
if (arenaClass.hasUnbreakableWeapons() && ArenaClass.isWeapon(fifth)) {
makeUnbreakable(offhand);
}
if (arenaClass.hasUnbreakableArmor() && ArmorType.getType(fifth) != null) {
makeUnbreakable(offhand);
}
contents[contents.length - 5] = null;
}
@ -1197,7 +1211,7 @@ public class ArenaImpl implements Arena
if (arenaClass.hasUnbreakableWeapons()) {
for (ItemStack stack : contents) {
if (stack != null && arenaClass.isWeapon(stack)) {
stack.setDurability(Short.MIN_VALUE);
makeUnbreakable(stack);
}
}
}
@ -1216,6 +1230,12 @@ public class ArenaImpl implements Arena
autoReady(p);
}
private void makeUnbreakable(ItemStack stack) {
ItemMeta meta = stack.getItemMeta();
meta.setUnbreakable(true);
stack.setItemMeta(meta);
}
private void autoReady(Player p) {
if (settings.getBoolean("auto-ready", false)) {
if (autoStartTimer.getRemaining() <= 0) {

View File

@ -87,7 +87,6 @@ import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.material.Attachable;
import org.bukkit.material.Bed;
import org.bukkit.material.Door;
@ -708,10 +707,7 @@ public class ArenaListener
}
}
// Repair weapons if necessary
if (damager instanceof Player) {
repairWeapon((Player) damager);
} else if (damager instanceof TNTPrimed) {
if (damager instanceof TNTPrimed) {
damager = getPlanter(damager);
}
}
@ -764,9 +760,6 @@ public class ArenaListener
}
if (arena.inArena(player)) {
// Repair armor if necessary
repairArmor(player);
// Cancel PvP damage if disabled
if (!pvpEnabled && damager instanceof Player && !damager.equals(player)) {
event.setCancelled(true);
@ -849,51 +842,6 @@ public class ArenaListener
}
}
private static final EnumSet<Material> REPAIRABLE_TYPES = EnumSet.of(
// Tools and swords
Material.GOLDEN_AXE, Material.GOLDEN_HOE, Material.GOLDEN_PICKAXE, Material.GOLDEN_SHOVEL, Material.GOLDEN_SWORD,
Material.WOODEN_AXE, Material.WOODEN_HOE, Material.WOODEN_PICKAXE, Material.WOODEN_SHOVEL, Material.WOODEN_SWORD,
Material.STONE_AXE, Material.STONE_HOE, Material.STONE_PICKAXE, Material.STONE_SHOVEL, Material.STONE_SWORD,
Material.IRON_AXE, Material.IRON_HOE, Material.IRON_PICKAXE, Material.IRON_SHOVEL, Material.IRON_SWORD,
Material.DIAMOND_AXE, Material.DIAMOND_HOE, Material.DIAMOND_PICKAXE, Material.DIAMOND_SHOVEL, Material.DIAMOND_SWORD,
// Armor
Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS,
Material.GOLDEN_HELMET, Material.GOLDEN_CHESTPLATE, Material.GOLDEN_LEGGINGS, Material.GOLDEN_BOOTS,
Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS,
Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS,
Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS,
// Misc
Material.BOW, Material.FLINT_AND_STEEL, Material.FISHING_ROD, Material.SHEARS, Material.CARROT_ON_A_STICK, Material.SHIELD
);
private void repairWeapon(Player p) {
ArenaPlayer ap = arena.getArenaPlayer(p);
if (ap != null) {
ArenaClass ac = ap.getArenaClass();
if (ac != null && ac.hasUnbreakableWeapons()) {
repair(p.getInventory().getItemInMainHand());
repair(p.getInventory().getItemInOffHand());
}
}
}
private void repairArmor(Player p) {
ArenaClass ac = arena.getArenaPlayer(p).getArenaClass();
if (ac != null && ac.hasUnbreakableArmor()) {
PlayerInventory inv = p.getInventory();
repair(inv.getHelmet());
repair(inv.getChestplate());
repair(inv.getLeggings());
repair(inv.getBoots());
}
}
private void repair(ItemStack stack) {
if (stack != null && REPAIRABLE_TYPES.contains(stack.getType())) {
stack.setDurability((short) 0);
}
}
public void onEntityCombust(EntityCombustEvent event) {
if (monsters.getMonsters().contains(event.getEntity())) {
if (event instanceof EntityCombustByBlockEvent || event instanceof EntityCombustByEntityEvent) {