diff --git a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java
index 0f80aae0a..2fab74dd4 100644
--- a/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java
+++ b/api/src/main/java/org/geysermc/geyser/api/item/custom/CustomItemData.java
@@ -142,11 +142,11 @@ public interface CustomItemData {
* Gets the attack damage of the item.
* This is purely visual, and only applied to tools
*
- *
Returns 0 if not set. When 0, Geyser takes the Java item attack damage when based on a vanilla item, or uses 0 when porting a modded item.
+ * Returns -1 if not set. When not set, Geyser takes the Java item attack damage when based on a vanilla item, or uses 0 when porting a modded item.
*
* @return the attack damage of the item
*/
- @NonNegative int attackDamage();
+ int attackDamage();
/**
* Gets the armor type of the item.
@@ -161,11 +161,13 @@ public interface CustomItemData {
/**
* Gets the armor protection value of the item.
*
- * Only has a function when {@link CustomItemData#armorType} is set.
+ * Only has a function when {@link CustomItemData#armorType} is set, or when the Java item is an armor item (when based on a vanilla item).
+ *
+ * Returns -1 if not set. When not set, Geyser takes the Java item protection value when based on a vanilla item, or uses 0 when porting a modded item.
*
* @return the armor protection value of the item
*/
- @NonNegative int protectionValue();
+ int protectionValue();
/**
* Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and
diff --git a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java
index 4eaddaa6b..28fedb145 100644
--- a/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java
+++ b/core/src/main/java/org/geysermc/geyser/item/GeyserCustomItemData.java
@@ -204,9 +204,9 @@ public class GeyserCustomItemData implements CustomItemData {
protected Set tags = new HashSet<>();
private int stackSize = 0;
private int maxDamage = -1;
- private int attackDamage = 0;
+ private int attackDamage = -1;
private String armorType = null;
- private int protectionValue = 0;
+ private int protectionValue = -1;
private boolean hat = false;
private boolean foil = false;
private boolean edible = false;
diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java
index f2d233318..1f7bcf506 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java
@@ -182,10 +182,11 @@ public class CustomItemRegistryPopulator {
int protectionValue = 0;
if (mapping.getArmorType() != null) {
armorType = mapping.getArmorType();
- protectionValue = mapping.getProtectionValue();
+ protectionValue = customItemData.protectionValue() == -1 ? mapping.getProtectionValue() : customItemData.protectionValue();
} else if (customItemData.armorType() != null) {
armorType = customItemData.armorType();
- protectionValue = customItemData.protectionValue();
+ // Using 0 as fallback here because the Java item doesn't have an armor type - so its protection value would be 0
+ protectionValue = customItemData.protectionValue() == -1 ? 0 : customItemData.protectionValue();
}
if (armorType != null) {
@@ -244,13 +245,13 @@ public class CustomItemRegistryPopulator {
boolean canDestroyInCreative = true;
if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here.
- canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, customItemData.attackDamage());
+ canDestroyInCreative = computeToolProperties(Objects.requireNonNull(customItemData.toolType()), itemProperties, componentBuilder, Math.max(0, customItemData.attackDamage()));
}
itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative);
String armorType = customItemData.armorType();
if (armorType != null) {
- computeArmorProperties(armorType, customItemData.protectionValue(), itemProperties, componentBuilder);
+ computeArmorProperties(armorType, Math.max(0, customItemData.protectionValue()), itemProperties, componentBuilder);
}
if (customItemData.isEdible()) {