Skip to content

Commit

Permalink
fix: actually remove item meta when converting from custom -> vanilla…
Browse files Browse the repository at this point in the history
… max durability (fixes #276)
  • Loading branch information
oddlama committed Nov 14, 2024
1 parent 06832e9 commit 117d225
Showing 1 changed file with 32 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import net.kyori.adventure.text.Component;


// TODO: what about inventory based item repair?

public class DurabilityManager extends Listener<Core> {
Expand Down Expand Up @@ -53,11 +52,14 @@ private static void remove_lore(final ItemStack item_stack) {
}

/**
* Sets the item's damage regarding our custom durability. The durability will get
* clamped to plausible values. Damage values >= max will result in item breakage.
* Sets the item's damage regarding our custom durability. The durability will
* get
* clamped to plausible values. Damage values >= max will result in item
* breakage.
* The maximum value will be taken from the item tag if it exists.
*/
private static void set_damage_and_update_item(final CustomItem custom_item, final ItemStack item_stack, int damage) {
private static void set_damage_and_update_item(final CustomItem custom_item, final ItemStack item_stack,
int damage) {
// Honor unbreakable flag
final var ro_meta = item_stack.getItemMeta();
if (ro_meta.isUnbreakable()) {
Expand All @@ -72,7 +74,8 @@ private static void set_damage_and_update_item(final CustomItem custom_item, fin
*/
public static boolean initialize_or_update_max(final CustomItem custom_item, final ItemStack item_stack) {
// Remember damage if set.
var old_damage = item_stack.getItemMeta().getPersistentDataContainer().getOrDefault(ITEM_DURABILITY_DAMAGE, PersistentDataType.INTEGER, -1);
var old_damage = item_stack.getItemMeta().getPersistentDataContainer().getOrDefault(ITEM_DURABILITY_DAMAGE,
PersistentDataType.INTEGER, -1);

// First, remove all components.
item_stack.editMeta(meta -> {
Expand All @@ -92,8 +95,8 @@ public static boolean initialize_or_update_max(final CustomItem custom_item, fin
if (item_stack.getItemMeta() instanceof final Damageable damage_meta) {
// If there was no old damage value, initialize proportionally by visual damage.
final var visual_max = item_stack.getType().getMaxDurability();
final var damage_percentage = (double)damage_meta.getDamage() / visual_max;
actual_damage = (int)(custom_item.durability() * damage_percentage);
final var damage_percentage = (double) damage_meta.getDamage() / visual_max;
actual_damage = (int) (custom_item.durability() * damage_percentage);
} else {
// There was no old damage value, but the item has no visual durability.
// Initialize with max durability.
Expand All @@ -109,7 +112,6 @@ public static boolean initialize_or_update_max(final CustomItem custom_item, fin
return true;
}


@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void on_item_damage(final PlayerItemDamageEvent event) {
final var item = event.getItem();
Expand All @@ -129,46 +131,55 @@ public void on_item_damage(final PlayerItemDamageEvent event) {
static public void update_damage(CustomItem custom_item, ItemStack item_stack) {
if (!(item_stack.getItemMeta() instanceof Damageable meta))
return; // everything should be damageable now

boolean updated = false;
PersistentDataContainer data = meta.getPersistentDataContainer();

final int new_max_damage = custom_item.durability() == 0 ? item_stack.getType().getMaxDurability() : custom_item.durability();

final int new_max_damage = custom_item.durability() == 0 ? item_stack.getType().getMaxDurability()
: custom_item.durability();

int old_damage;
int old_max_damage;
// if the item has damage in their data, get the value and remove it from PDC
if(data.has(ITEM_DURABILITY_DAMAGE) && data.has(ITEM_DURABILITY_MAX)) {
if (data.has(ITEM_DURABILITY_DAMAGE) && data.has(ITEM_DURABILITY_MAX)) {
old_damage = data.get(ITEM_DURABILITY_DAMAGE, PersistentDataType.INTEGER);
old_max_damage = data.get(ITEM_DURABILITY_MAX, PersistentDataType.INTEGER);
data.remove(ITEM_DURABILITY_DAMAGE);
data.remove(ITEM_DURABILITY_MAX);
updated = true;
} else {
old_damage = meta.hasDamage() ? meta.getDamage() : 0;
old_max_damage = meta.hasMaxDamage() ? meta.getMaxDamage() : item_stack.getType().getMaxDurability();
}


item_stack.editMeta(Damageable.class, imeta -> {
PersistentDataContainer idata = imeta.getPersistentDataContainer();
idata.remove(ITEM_DURABILITY_DAMAGE);
idata.remove(ITEM_DURABILITY_MAX);
});

remove_lore(item_stack);

if(!updated) updated = old_max_damage != new_max_damage; // only update if there was old data or a different max durability
if(!updated) return; // and do nothing if nothing changed
if (!updated)
updated = old_max_damage != new_max_damage; // only update if there was old data or a different max
// durability
if (!updated)
return; // and do nothing if nothing changed
final int new_damage = scale_damage(old_damage, old_max_damage, new_max_damage);
set_damage_and_max_damage(custom_item, item_stack, new_damage);
}

static public int scale_damage(int old_damage, int old_max_damage, int new_max_damage) {
return old_max_damage == new_max_damage ? old_damage : (int)(new_max_damage * ((float) old_damage / (float) old_max_damage));
return old_max_damage == new_max_damage ? old_damage
: (int) (new_max_damage * ((float) old_damage / (float) old_max_damage));
}

static public boolean set_damage_and_max_damage(CustomItem custom_item, ItemStack item, int damage) {
return item.editMeta(Damageable.class, meta -> {
if(custom_item.durability() != 0) {
return item.editMeta(Damageable.class, meta -> {
if (custom_item.durability() != 0) {
meta.setMaxDamage(custom_item.durability());
} else {
meta.setMaxDamage((int) item.getType().getMaxDurability());
}

meta.setDamage(damage);
});
}
Expand Down

0 comments on commit 117d225

Please sign in to comment.