Skip to content

Commit

Permalink
ExprMaxDurability - add changer for MC 1.20.5+
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaneBeee committed Jun 21, 2024
1 parent 3a5c8cb commit 38d6cc7
Showing 1 changed file with 114 additions and 20 deletions.
134 changes: 114 additions & 20 deletions src/main/java/ch/njol/skript/expressions/ExprMaxDurability.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,140 @@
*/
package ch.njol.skript.expressions;

import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.skript.util.slot.Slot;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Nullable;

@Name("Max Durability")
@Description("The maximum durability of an item.")
@Examples({"maximum durability of diamond sword",
"if max durability of player's tool is not 0: # Item is damageable"})
@Since("2.5")
public class ExprMaxDurability extends SimplePropertyExpression<Object, Long> {
@Description({"The maximum durability of an item. Changing requires Minecraft 1.20.5+",
"Note: 'delete' will remove the max durability from the item (making it a non-damageable item). Delete requires Paper 1.21+"})
@Examples({
"maximum durability of diamond sword",
"if max durability of player's tool is not 0: # Item is damageable",
"set max durability of player's tool to 5000",
"add 5 to max durability of player's tool",
"reset max durability of player's tool",
"delete max durability of player's tool"
})
@Since("2.5, INSERT VERSION (change)")
public class ExprMaxDurability extends SimplePropertyExpression<Object, Integer> {

// Minecraft 1.20.5+ item component "max_damage" (custom item durability)
private static final boolean HAS_MAX_DAMAGE = Skript.methodExists(Damageable.class, "hasMaxDamage");
// Introduced in Paper 1.21
private static final boolean HAS_RESET = Skript.methodExists(Damageable.class, "resetDamage");

static {
register(ExprMaxDurability.class, Long.class, "max[imum] durabilit(y|ies)", "itemstacks/slots");
register(ExprMaxDurability.class, Integer.class, "max[imum] (durabilit(y|ies)|damage)", "itemstacks/slots");
}

@Override
@Nullable
public Long convert(Object o) {
if (o instanceof Slot) {
final ItemStack i = ((Slot) o).getItem();
return i == null ? null : (long) i.getType().getMaxDurability();
} else {
return (long) ((ItemStack) o).getType().getMaxDurability();
public Integer convert(Object object) {
ItemStack itemStack = getItemStack(object);
if (itemStack == null)
return null;
return getMaxDurability(itemStack);
}

@Override
public @Nullable Class<?>[] acceptChange(ChangeMode mode) {
if (HAS_MAX_DAMAGE) {
switch (mode) {
case SET:
case ADD:
case REMOVE:
case RESET:
return CollectionUtils.array(Number.class);
case DELETE:
if (HAS_RESET)
return CollectionUtils.array();
}
}
return null;
}

@Override
public Class<? extends Long> getReturnType() {
return Long.class;
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
int change = delta == null ? 0 : ((Number) delta[0]).intValue();
if (mode == ChangeMode.REMOVE)
change = -change;

for (Object object : getExpr().getArray(event)) {
ItemStack itemStack = getItemStack(object);
if (itemStack == null)
continue;

ItemMeta meta = itemStack.getItemMeta();
if (!(meta instanceof Damageable))
continue;

Damageable damageable = (Damageable) meta;

int newValue;
switch (mode) {
case ADD:
case REMOVE:
newValue = getMaxDurability(itemStack) + change;
break;
case SET:
newValue = change;
break;
case DELETE:
newValue = 0;
break;
default:
newValue = itemStack.getType().getMaxDurability();
}
if (mode == ChangeMode.RESET && HAS_RESET) {
//damageable.resetDamage(); TODO (waiting on Skript to update to Paper 1.21)
} else {
damageable.setMaxDamage(Math.max(1, newValue));
}

itemStack.setItemMeta(meta);
if (object instanceof Slot)
((Slot) object).setItem(itemStack);
}
}

private int getMaxDurability(ItemStack itemStack) {
ItemMeta itemMeta = itemStack.getItemMeta();
if (HAS_MAX_DAMAGE && itemMeta instanceof Damageable) {
Damageable damageable = (Damageable) itemMeta;
if (damageable.hasMaxDamage())
return damageable.getMaxDamage();
}
return itemStack.getType().getMaxDurability();
}

@Nullable
private ItemStack getItemStack(Object object) {
if (object instanceof Slot)
return ((Slot) object).getItem();
else
return (ItemStack) object;
}

@Override
public Class<? extends Integer> getReturnType() {
return Integer.class;
}

@Override
protected String getPropertyName() {
return "max durability";
}

}

0 comments on commit 38d6cc7

Please sign in to comment.