mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge 5b864ab88e
into ce62824899
This commit is contained in:
commit
2de5f0b3bf
6 changed files with 479 additions and 319 deletions
|
@ -25,6 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.api.item.custom;
|
||||
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.api.GeyserApi;
|
||||
|
@ -114,6 +116,88 @@ public interface CustomItemData {
|
|||
*/
|
||||
@NonNull Set<String> tags();
|
||||
|
||||
/**
|
||||
* Gets the stack size of the item.
|
||||
*
|
||||
* <p>Returns 0 if not set. When not set, Geyser defaults to the stack count of the Java item when based on a vanilla item, or 64 when registering a non-vanilla item.</p>
|
||||
*
|
||||
* <p>Note that, to copy Java behaviour, setting the stack size of an item to a value above 1 will set the max damage to 0. If a max damage value above 0 was explicitly set, an exception will be thrown.</p>
|
||||
*
|
||||
* @return the stack size of the item
|
||||
*/
|
||||
@NonNegative int stackSize();
|
||||
|
||||
/**
|
||||
* Gets the max damage of the item.
|
||||
*
|
||||
* <p>Returns -1 if not set. When not set, Geyser defaults to the maximum damage of the Java item when based on a vanilla item, or uses 0 when registering a non-vanilla item.</p>
|
||||
*
|
||||
* <p>Note that, to copy Java behaviour, setting the max damage value of an item to a value above 0 will set the stack size to 1. If a stack size above 1 was explicitly set, an exception will be thrown.</p>
|
||||
*
|
||||
* @return the max damage of the item
|
||||
*/
|
||||
int maxDamage();
|
||||
|
||||
/**
|
||||
* Gets the attack damage of the item.
|
||||
* This is purely visual, and only applied to tools
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @return the attack damage of the item
|
||||
*/
|
||||
int attackDamage();
|
||||
|
||||
/**
|
||||
* Gets the armor type of the item.
|
||||
*
|
||||
* <p>This can be "boots", "leggings", "chestplate", or "helmet", and makes the item able to be equipped into its respective equipment slot.
|
||||
* This should only be set if the Java item can be placed into the specified equipment slot.</p>
|
||||
*
|
||||
* @return the armor type of the item
|
||||
*/
|
||||
@Nullable String armorType();
|
||||
|
||||
/**
|
||||
* Gets the armor protection value of the item.
|
||||
*
|
||||
* <p>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).</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @return the armor protection value of the item
|
||||
*/
|
||||
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
|
||||
* normally allow the player to equip it. This is not meant for armor.
|
||||
*
|
||||
* @return if the item is a hat
|
||||
*/
|
||||
boolean isHat();
|
||||
|
||||
/**
|
||||
* Gets if the item is a foil. This is used to determine if the item should be rendered with an enchantment glint effect.
|
||||
*
|
||||
* @return if the item is a foil
|
||||
*/
|
||||
boolean isFoil();
|
||||
|
||||
/**
|
||||
* Gets if the item is edible.
|
||||
*
|
||||
* @return if the item is edible
|
||||
*/
|
||||
boolean isEdible();
|
||||
|
||||
/**
|
||||
* Gets if the food item can always be eaten.
|
||||
*
|
||||
* @return if the item is allowed to be eaten all the time
|
||||
*/
|
||||
boolean canAlwaysEat();
|
||||
|
||||
static CustomItemData.Builder builder() {
|
||||
return GeyserApi.api().provider(CustomItemData.Builder.class);
|
||||
}
|
||||
|
@ -144,6 +228,24 @@ public interface CustomItemData {
|
|||
|
||||
Builder tags(@Nullable Set<String> tags);
|
||||
|
||||
Builder stackSize(@Positive int stackSize);
|
||||
|
||||
Builder maxDamage(@NonNegative int maxDamage);
|
||||
|
||||
Builder attackDamage(@NonNegative int attackDamage);
|
||||
|
||||
Builder armorType(@Nullable String armorType);
|
||||
|
||||
Builder protectionValue(@NonNegative int protectionValue);
|
||||
|
||||
Builder hat(boolean isHat);
|
||||
|
||||
Builder foil(boolean isFoil);
|
||||
|
||||
Builder edible(boolean isEdible);
|
||||
|
||||
Builder canAlwaysEat(boolean canAlwaysEat);
|
||||
|
||||
CustomItemData build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package org.geysermc.geyser.api.item.custom;
|
||||
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.api.GeyserApi;
|
||||
|
@ -43,35 +44,6 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
*/
|
||||
@NonNull String identifier();
|
||||
|
||||
/**
|
||||
* Gets the java item id of the item.
|
||||
*
|
||||
* @return the java item id of the item
|
||||
*/
|
||||
@NonNegative int javaId();
|
||||
|
||||
/**
|
||||
* Gets the stack size of the item.
|
||||
*
|
||||
* @return the stack size of the item
|
||||
*/
|
||||
@NonNegative int stackSize();
|
||||
|
||||
/**
|
||||
* Gets the max damage of the item.
|
||||
*
|
||||
* @return the max damage of the item
|
||||
*/
|
||||
int maxDamage();
|
||||
|
||||
/**
|
||||
* Gets the attack damage of the item.
|
||||
* This is purely visual, and only applied to tools
|
||||
*
|
||||
* @return the attack damage of the item
|
||||
*/
|
||||
int attackDamage();
|
||||
|
||||
/**
|
||||
* Gets the tool type of the item.
|
||||
*
|
||||
|
@ -87,18 +59,11 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
@Nullable String toolTier();
|
||||
|
||||
/**
|
||||
* Gets the armor type of the item.
|
||||
* Gets the java item id of the item.
|
||||
*
|
||||
* @return the armor type of the item
|
||||
* @return the java item id of the item
|
||||
*/
|
||||
@Nullable String armorType();
|
||||
|
||||
/**
|
||||
* Gets the armor protection value of the item.
|
||||
*
|
||||
* @return the armor protection value of the item
|
||||
*/
|
||||
int protectionValue();
|
||||
@NonNegative int javaId();
|
||||
|
||||
/**
|
||||
* Gets the item's translation string.
|
||||
|
@ -114,35 +79,6 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
*/
|
||||
@Nullable Set<String> repairMaterials();
|
||||
|
||||
/**
|
||||
* Gets if the item is a hat. This is used to determine if the item should be rendered on the player's head, and
|
||||
* normally allow the player to equip it. This is not meant for armor.
|
||||
*
|
||||
* @return if the item is a hat
|
||||
*/
|
||||
boolean isHat();
|
||||
|
||||
/**
|
||||
* Gets if the item is a foil. This is used to determine if the item should be rendered with an enchantment glint effect.
|
||||
*
|
||||
* @return if the item is a foil
|
||||
*/
|
||||
boolean isFoil();
|
||||
|
||||
/**
|
||||
* Gets if the item is edible.
|
||||
*
|
||||
* @return if the item is edible
|
||||
*/
|
||||
boolean isEdible();
|
||||
|
||||
/**
|
||||
* Gets if the food item can always be eaten.
|
||||
*
|
||||
* @return if the item is allowed to be eaten all the time
|
||||
*/
|
||||
boolean canAlwaysEat();
|
||||
|
||||
/**
|
||||
* Gets if the item is chargable, like a bow.
|
||||
*
|
||||
|
@ -150,6 +86,13 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
*/
|
||||
boolean isChargeable();
|
||||
|
||||
/**
|
||||
* Gets the block the item places.
|
||||
*
|
||||
* @return the block the item places
|
||||
*/
|
||||
String block();
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #displayHandheld()} instead.
|
||||
* Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld.
|
||||
|
@ -161,13 +104,6 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
return displayHandheld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block the item places.
|
||||
*
|
||||
* @return the block the item places
|
||||
*/
|
||||
String block();
|
||||
|
||||
static NonVanillaCustomItemData.Builder builder() {
|
||||
return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class);
|
||||
}
|
||||
|
@ -176,54 +112,6 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
@Override
|
||||
Builder name(@NonNull String name);
|
||||
|
||||
Builder identifier(@NonNull String identifier);
|
||||
|
||||
Builder javaId(@NonNegative int javaId);
|
||||
|
||||
Builder stackSize(@NonNegative int stackSize);
|
||||
|
||||
Builder maxDamage(int maxDamage);
|
||||
|
||||
Builder attackDamage(int attackDamage);
|
||||
|
||||
Builder toolType(@Nullable String toolType);
|
||||
|
||||
Builder toolTier(@Nullable String toolTier);
|
||||
|
||||
Builder armorType(@Nullable String armorType);
|
||||
|
||||
Builder protectionValue(int protectionValue);
|
||||
|
||||
Builder translationString(@Nullable String translationString);
|
||||
|
||||
Builder repairMaterials(@Nullable Set<String> repairMaterials);
|
||||
|
||||
Builder hat(boolean isHat);
|
||||
|
||||
Builder foil(boolean isFoil);
|
||||
|
||||
Builder edible(boolean isEdible);
|
||||
|
||||
Builder canAlwaysEat(boolean canAlwaysEat);
|
||||
|
||||
Builder chargeable(boolean isChargeable);
|
||||
|
||||
Builder block(String block);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #displayHandheld(boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Builder tool(boolean isTool) {
|
||||
return displayHandheld(isTool);
|
||||
}
|
||||
|
||||
@Override
|
||||
Builder creativeCategory(int creativeCategory);
|
||||
|
||||
@Override
|
||||
Builder creativeGroup(@Nullable String creativeGroup);
|
||||
|
||||
@Override
|
||||
Builder customItemOptions(@NonNull CustomItemOptions customItemOptions);
|
||||
|
||||
|
@ -239,6 +127,12 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
@Override
|
||||
Builder displayHandheld(boolean displayHandheld);
|
||||
|
||||
@Override
|
||||
Builder creativeCategory(int creativeCategory);
|
||||
|
||||
@Override
|
||||
Builder creativeGroup(@Nullable String creativeGroup);
|
||||
|
||||
@Override
|
||||
Builder textureSize(int textureSize);
|
||||
|
||||
|
@ -248,6 +142,57 @@ public interface NonVanillaCustomItemData extends CustomItemData {
|
|||
@Override
|
||||
Builder tags(@Nullable Set<String> tags);
|
||||
|
||||
@Override
|
||||
Builder stackSize(@Positive int stackSize);
|
||||
|
||||
@Override
|
||||
Builder maxDamage(@NonNegative int maxDamage);
|
||||
|
||||
@Override
|
||||
Builder attackDamage(@NonNegative int attackDamage);
|
||||
|
||||
@Override
|
||||
Builder armorType(@Nullable String armorType);
|
||||
|
||||
@Override
|
||||
Builder protectionValue(@NonNegative int protectionValue);
|
||||
|
||||
@Override
|
||||
Builder hat(boolean isHat);
|
||||
|
||||
@Override
|
||||
Builder foil(boolean isFoil);
|
||||
|
||||
@Override
|
||||
Builder edible(boolean isEdible);
|
||||
|
||||
@Override
|
||||
Builder canAlwaysEat(boolean canAlwaysEat);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #displayHandheld(boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Builder tool(boolean isTool) {
|
||||
return displayHandheld(isTool);
|
||||
}
|
||||
|
||||
Builder identifier(@NonNull String identifier);
|
||||
|
||||
Builder javaId(@NonNegative int javaId);
|
||||
|
||||
Builder toolType(@Nullable String toolType);
|
||||
|
||||
Builder toolTier(@Nullable String toolTier);
|
||||
|
||||
Builder translationString(@Nullable String translationString);
|
||||
|
||||
Builder repairMaterials(@Nullable Set<String> repairMaterials);
|
||||
|
||||
Builder chargeable(boolean isChargeable);
|
||||
|
||||
Builder block(String block);
|
||||
|
||||
NonVanillaCustomItemData build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.item;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemData;
|
||||
|
@ -41,6 +44,8 @@ import java.util.Set;
|
|||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class GeyserCustomItemData implements CustomItemData {
|
||||
private static final List<String> VALID_ARMOR_TYPES = List.of("boots", "leggings", "chestplate", "helmet");
|
||||
|
||||
private final String name;
|
||||
private final CustomItemOptions customItemOptions;
|
||||
private final String displayName;
|
||||
|
@ -52,29 +57,37 @@ public class GeyserCustomItemData implements CustomItemData {
|
|||
private final int textureSize;
|
||||
private final CustomRenderOffsets renderOffsets;
|
||||
private final Set<String> tags;
|
||||
private final int stackSize;
|
||||
private final int maxDamage;
|
||||
private final int attackDamage;
|
||||
private final String armorType;
|
||||
private final int protectionValue;
|
||||
private final boolean isHat;
|
||||
private final boolean isFoil;
|
||||
private final boolean isEdible;
|
||||
private final boolean canAlwaysEat;
|
||||
|
||||
public GeyserCustomItemData(String name,
|
||||
CustomItemOptions customItemOptions,
|
||||
String displayName,
|
||||
String icon,
|
||||
boolean allowOffhand,
|
||||
boolean displayHandheld,
|
||||
OptionalInt creativeCategory,
|
||||
String creativeGroup,
|
||||
int textureSize,
|
||||
CustomRenderOffsets renderOffsets,
|
||||
Set<String> tags) {
|
||||
this.name = name;
|
||||
this.customItemOptions = customItemOptions;
|
||||
this.displayName = displayName;
|
||||
this.icon = icon;
|
||||
this.allowOffhand = allowOffhand;
|
||||
this.displayHandheld = displayHandheld;
|
||||
this.creativeCategory = creativeCategory;
|
||||
this.creativeGroup = creativeGroup;
|
||||
this.textureSize = textureSize;
|
||||
this.renderOffsets = renderOffsets;
|
||||
this.tags = tags;
|
||||
public GeyserCustomItemData(Builder builder) {
|
||||
this.name = builder.name;
|
||||
this.customItemOptions = builder.customItemOptions;
|
||||
this.displayName = builder.displayName;
|
||||
this.icon = builder.icon;
|
||||
this.allowOffhand = builder.allowOffhand;
|
||||
this.displayHandheld = builder.displayHandheld;
|
||||
this.creativeCategory = builder.creativeCategory;
|
||||
this.creativeGroup = builder.creativeGroup;
|
||||
this.textureSize = builder.textureSize;
|
||||
this.renderOffsets = builder.renderOffsets;
|
||||
this.tags = builder.tags;
|
||||
this.stackSize = builder.stackSize;
|
||||
this.maxDamage = builder.maxDamage;
|
||||
this.attackDamage = builder.attackDamage;
|
||||
this.armorType = builder.armorType;
|
||||
this.protectionValue = builder.protectionValue;
|
||||
this.isHat = builder.hat;
|
||||
this.isFoil = builder.foil;
|
||||
this.isEdible = builder.edible;
|
||||
this.canAlwaysEat = builder.canAlwaysEat;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,6 +145,51 @@ public class GeyserCustomItemData implements CustomItemData {
|
|||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stackSize() {
|
||||
return stackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxDamage() {
|
||||
return maxDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackDamage() {
|
||||
return attackDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String armorType() {
|
||||
return armorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int protectionValue() {
|
||||
return protectionValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHat() {
|
||||
return isHat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoil() {
|
||||
return isFoil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEdible() {
|
||||
return isEdible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlwaysEat() {
|
||||
return canAlwaysEat;
|
||||
}
|
||||
|
||||
public static class Builder implements CustomItemData.Builder {
|
||||
protected String name = null;
|
||||
protected CustomItemOptions customItemOptions = null;
|
||||
|
@ -144,6 +202,15 @@ public class GeyserCustomItemData implements CustomItemData {
|
|||
protected int textureSize = 16;
|
||||
protected CustomRenderOffsets renderOffsets = null;
|
||||
protected Set<String> tags = new HashSet<>();
|
||||
private int stackSize = 0;
|
||||
private int maxDamage = -1;
|
||||
private int attackDamage = -1;
|
||||
private String armorType = null;
|
||||
private int protectionValue = -1;
|
||||
private boolean hat = false;
|
||||
private boolean foil = false;
|
||||
private boolean edible = false;
|
||||
private boolean canAlwaysEat = false;
|
||||
|
||||
@Override
|
||||
public Builder name(@NonNull String name) {
|
||||
|
@ -211,6 +278,89 @@ public class GeyserCustomItemData implements CustomItemData {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder stackSize(@Positive int stackSize) {
|
||||
if (stackSize < 1) {
|
||||
throw new IllegalArgumentException("Stack size cannot be below 1 (" + stackSize + " was given)");
|
||||
} else if (stackSize > 1) {
|
||||
if (this.maxDamage > 0) {
|
||||
throw new IllegalArgumentException("Stack size cannot be above 1 when max damage is above 0 (" + stackSize + " was given)");
|
||||
}
|
||||
// Explicitly set max damage to 0 instead of falling back to the Java vanilla item value
|
||||
this.maxDamage = 0;
|
||||
}
|
||||
|
||||
this.stackSize = stackSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder maxDamage(@NonNegative int maxDamage) {
|
||||
if (maxDamage < 0) {
|
||||
throw new IllegalArgumentException("Max damage cannot be below 0 (" + maxDamage + " was given)");
|
||||
} else if (maxDamage > 0) {
|
||||
if (this.stackSize > 1) {
|
||||
throw new IllegalArgumentException("Max damage cannot be above 0 when stack size is above 1 (" + maxDamage + " was given)");
|
||||
}
|
||||
// Explicitly set stack size to 1 instead of falling back to the Java vanilla item value
|
||||
this.stackSize = 1;
|
||||
}
|
||||
|
||||
this.maxDamage = maxDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder attackDamage(@NonNegative int attackDamage) {
|
||||
if (attackDamage < 0) {
|
||||
throw new IllegalArgumentException("Protection value cannot be below 0 (" + attackDamage + " was given)");
|
||||
}
|
||||
this.attackDamage = attackDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder armorType(@Nullable String armorType) {
|
||||
if (!VALID_ARMOR_TYPES.contains(armorType)) {
|
||||
throw new IllegalArgumentException("Invalid armor type " + armorType + "! Can be \"boots\", \"leggings\", \"chestplate\", or \"helmet\"");
|
||||
}
|
||||
this.armorType = armorType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder protectionValue(@NonNegative int protectionValue) {
|
||||
if (protectionValue < 0) {
|
||||
throw new IllegalArgumentException("Protection value cannot be below 0 (" + protectionValue + " was given)");
|
||||
}
|
||||
this.protectionValue = protectionValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hat(boolean isHat) {
|
||||
this.hat = isHat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder foil(boolean isFoil) {
|
||||
this.foil = isFoil;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder edible(boolean isEdible) {
|
||||
this.edible = isEdible;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder canAlwaysEat(boolean canAlwaysEat) {
|
||||
this.canAlwaysEat = canAlwaysEat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomItemData build() {
|
||||
if (this.name == null || this.customItemOptions == null) {
|
||||
|
@ -223,8 +373,8 @@ public class GeyserCustomItemData implements CustomItemData {
|
|||
if (this.icon == null) {
|
||||
this.icon = this.name;
|
||||
}
|
||||
return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand,
|
||||
this.displayHandheld, this.creativeCategory, this.creativeGroup, this.textureSize, this.renderOffsets, this.tags);
|
||||
|
||||
return new GeyserCustomItemData(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ package org.geysermc.geyser.item;
|
|||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
|
||||
|
@ -40,44 +42,22 @@ import java.util.Set;
|
|||
public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData implements NonVanillaCustomItemData {
|
||||
private final String identifier;
|
||||
private final int javaId;
|
||||
private final int stackSize;
|
||||
private final int maxDamage;
|
||||
private final int attackDamage;
|
||||
private final String toolType;
|
||||
private final String toolTier;
|
||||
private final String armorType;
|
||||
private final int protectionValue;
|
||||
private final String translationString;
|
||||
private final Set<String> repairMaterials;
|
||||
private final boolean isHat;
|
||||
private final boolean isFoil;
|
||||
private final boolean isTool;
|
||||
private final boolean isEdible;
|
||||
private final boolean canAlwaysEat;
|
||||
private final boolean isChargeable;
|
||||
private final String block;
|
||||
|
||||
public GeyserNonVanillaCustomItemData(Builder builder) {
|
||||
super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand,
|
||||
builder.displayHandheld, builder.creativeCategory, builder.creativeGroup,
|
||||
builder.textureSize, builder.renderOffsets, builder.tags);
|
||||
super(builder);
|
||||
|
||||
this.identifier = builder.identifier;
|
||||
this.javaId = builder.javaId;
|
||||
this.stackSize = builder.stackSize;
|
||||
this.maxDamage = builder.maxDamage;
|
||||
this.attackDamage = builder.attackDamage;
|
||||
this.toolType = builder.toolType;
|
||||
this.toolTier = builder.toolTier;
|
||||
this.armorType = builder.armorType;
|
||||
this.protectionValue = builder.protectionValue;
|
||||
this.translationString = builder.translationString;
|
||||
this.repairMaterials = builder.repairMaterials;
|
||||
this.isHat = builder.hat;
|
||||
this.isFoil = builder.foil;
|
||||
this.isTool = builder.tool;
|
||||
this.isEdible = builder.edible;
|
||||
this.canAlwaysEat = builder.canAlwaysEat;
|
||||
this.isChargeable = builder.chargeable;
|
||||
this.block = builder.block;
|
||||
}
|
||||
|
@ -92,21 +72,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return javaId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stackSize() {
|
||||
return stackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxDamage() {
|
||||
return maxDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackDamage() {
|
||||
return attackDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toolType() {
|
||||
return toolType;
|
||||
|
@ -117,16 +82,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return toolTier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String armorType() {
|
||||
return armorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int protectionValue() {
|
||||
return protectionValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translationString() {
|
||||
return translationString;
|
||||
|
@ -137,26 +92,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return repairMaterials;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHat() {
|
||||
return isHat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoil() {
|
||||
return isFoil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEdible() {
|
||||
return isEdible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlwaysEat() {
|
||||
return canAlwaysEat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChargeable() {
|
||||
return isChargeable;
|
||||
|
@ -170,28 +105,10 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
public static class Builder extends GeyserCustomItemData.Builder implements NonVanillaCustomItemData.Builder {
|
||||
private String identifier = null;
|
||||
private int javaId = -1;
|
||||
|
||||
private int stackSize = 64;
|
||||
|
||||
private int maxDamage = 0;
|
||||
|
||||
private int attackDamage = 0;
|
||||
|
||||
private String toolType = null;
|
||||
private String toolTier = null;
|
||||
|
||||
private String armorType = null;
|
||||
private int protectionValue = 0;
|
||||
|
||||
private String translationString;
|
||||
|
||||
private Set<String> repairMaterials;
|
||||
|
||||
private boolean hat = false;
|
||||
private boolean foil = false;
|
||||
private boolean tool = false;
|
||||
private boolean edible = false;
|
||||
private boolean canAlwaysEat = false;
|
||||
private boolean chargeable = false;
|
||||
private String block = null;
|
||||
|
||||
|
@ -206,6 +123,16 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder displayName(@NonNull String displayName) {
|
||||
return (Builder) super.displayName(displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder icon(@NonNull String icon) {
|
||||
return (Builder) super.icon(icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder allowOffhand(boolean allowOffhand) {
|
||||
return (Builder) super.allowOffhand(allowOffhand);
|
||||
|
@ -217,13 +144,13 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
}
|
||||
|
||||
@Override
|
||||
public Builder displayName(@NonNull String displayName) {
|
||||
return (Builder) super.displayName(displayName);
|
||||
public Builder creativeCategory(int creativeCategory) {
|
||||
return (Builder) super.creativeCategory(creativeCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder icon(@NonNull String icon) {
|
||||
return (Builder) super.icon(icon);
|
||||
public Builder creativeGroup(@Nullable String creativeGroup) {
|
||||
return (Builder) super.creativeGroup(creativeGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -241,6 +168,51 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return (Builder) super.tags(tags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder stackSize(@Positive int stackSize) {
|
||||
return (Builder) super.stackSize(stackSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder maxDamage(@NonNegative int maxDamage) {
|
||||
return (Builder) super.maxDamage(maxDamage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder attackDamage(@NonNegative int attackDamage) {
|
||||
return (Builder) super.attackDamage(attackDamage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder armorType(@Nullable String armorType) {
|
||||
return (Builder) super.armorType(armorType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder protectionValue(@NonNegative int protectionValue) {
|
||||
return (Builder) super.protectionValue(protectionValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hat(boolean isHat) {
|
||||
return (Builder) super.hat(isHat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder foil(boolean isFoil) {
|
||||
return (Builder) super.foil(isFoil);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder edible(boolean isEdible) {
|
||||
return (Builder) super.edible(isEdible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder canAlwaysEat(boolean canAlwaysEat) {
|
||||
return (Builder) super.canAlwaysEat(canAlwaysEat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder identifier(@NonNull String identifier) {
|
||||
this.identifier = identifier;
|
||||
|
@ -253,24 +225,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder stackSize(int stackSize) {
|
||||
this.stackSize = stackSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder maxDamage(int maxDamage) {
|
||||
this.maxDamage = maxDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonVanillaCustomItemData.Builder attackDamage(int attackDamage) {
|
||||
this.attackDamage = attackDamage;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toolType(@Nullable String toolType) {
|
||||
this.toolType = toolType;
|
||||
|
@ -283,18 +237,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder armorType(@Nullable String armorType) {
|
||||
this.armorType = armorType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder protectionValue(int protectionValue) {
|
||||
this.protectionValue = protectionValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder translationString(@Nullable String translationString) {
|
||||
this.translationString = translationString;
|
||||
|
@ -307,40 +249,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder creativeCategory(int creativeCategory) {
|
||||
return (Builder) super.creativeCategory(creativeCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder creativeGroup(@Nullable String creativeGroup) {
|
||||
return (Builder) super.creativeGroup(creativeGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hat(boolean isHat) {
|
||||
this.hat = isHat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder foil(boolean isFoil) {
|
||||
this.foil = isFoil;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder edible(boolean isEdible) {
|
||||
this.edible = isEdible;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder canAlwaysEat(boolean canAlwaysEat) {
|
||||
this.canAlwaysEat = canAlwaysEat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder chargeable(boolean isChargeable) {
|
||||
this.chargeable = isChargeable;
|
||||
|
|
|
@ -213,6 +213,42 @@ public class MappingsReader_v1 extends MappingsReader {
|
|||
customItemData.tags(tagsSet);
|
||||
}
|
||||
|
||||
if (node.has("stack_size")) {
|
||||
customItemData.stackSize(node.get("stack_size").asInt());
|
||||
}
|
||||
|
||||
if (node.has("max_damage")) {
|
||||
customItemData.maxDamage(node.get("max_damage").asInt());
|
||||
}
|
||||
|
||||
if (node.has("attack_damage")) {
|
||||
customItemData.attackDamage(node.get("attack_damage").asInt());
|
||||
}
|
||||
|
||||
if (node.has("armor_type")) {
|
||||
customItemData.armorType(node.get("armor_type").asText());
|
||||
}
|
||||
|
||||
if (node.has("protection_value")) {
|
||||
customItemData.protectionValue(node.get("protection_value").asInt());
|
||||
}
|
||||
|
||||
if (node.has("hat")) {
|
||||
customItemData.hat(node.get("hat").asBoolean());
|
||||
}
|
||||
|
||||
if (node.has("foil")) {
|
||||
customItemData.foil(node.get("foil").asBoolean());
|
||||
}
|
||||
|
||||
if (node.has("edible")) {
|
||||
customItemData.edible(node.get("edible").asBoolean());
|
||||
}
|
||||
|
||||
if (node.has("can_always_eat")) {
|
||||
customItemData.canAlwaysEat(node.get("can_always_eat").asBoolean());
|
||||
}
|
||||
|
||||
return customItemData.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -130,8 +130,8 @@ public class CustomItemRegistryPopulator {
|
|||
Set<String> repairMaterials = customItemData.repairMaterials();
|
||||
|
||||
Item.Builder itemBuilder = Item.builder()
|
||||
.stackSize(customItemData.stackSize())
|
||||
.maxDamage(customItemData.maxDamage());
|
||||
.stackSize(customItemData.stackSize() == 0 ? 64 : customItemData.stackSize())
|
||||
.maxDamage(Math.max(customItemData.maxDamage(), 0));
|
||||
Item item = new Item(customIdentifier, itemBuilder) {
|
||||
@Override
|
||||
public boolean isValidRepairItem(Item other) {
|
||||
|
@ -151,8 +151,7 @@ public class CustomItemRegistryPopulator {
|
|||
.javaItem(item)
|
||||
.build();
|
||||
|
||||
NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId,
|
||||
customItemData.isHat(), customItemData.displayHandheld(), protocolVersion);
|
||||
NbtMapBuilder builder = createComponentNbt(customItemData, customItemId, protocolVersion);
|
||||
ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build());
|
||||
|
||||
return new NonVanillaItemRegistration(componentItemData, item, customItemMapping);
|
||||
|
@ -167,30 +166,50 @@ public class CustomItemRegistryPopulator {
|
|||
NbtMapBuilder itemProperties = NbtMap.builder();
|
||||
NbtMapBuilder componentBuilder = NbtMap.builder();
|
||||
|
||||
setupBasicItemInfo(javaItem.maxDamage(), javaItem.maxStackSize(), mapping.getToolType() != null || customItemData.displayHandheld(), customItemData, itemProperties, componentBuilder, protocolVersion);
|
||||
setupBasicItemInfo(customItemData.maxDamage() < 0 ? javaItem.maxDamage() : customItemData.maxDamage(),
|
||||
customItemData.stackSize() == 0 ? javaItem.maxStackSize() : customItemData.stackSize(),
|
||||
mapping.getToolType() != null || customItemData.displayHandheld(),
|
||||
customItemData, itemProperties, componentBuilder, protocolVersion);
|
||||
|
||||
boolean canDestroyInCreative = true;
|
||||
if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here.
|
||||
canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder, javaItem.attackDamage());
|
||||
if (mapping.getToolType() != null) {
|
||||
canDestroyInCreative = computeToolProperties(mapping.getToolType(), itemProperties, componentBuilder,
|
||||
customItemData.attackDamage() == 0 ? javaItem.attackDamage() : customItemData.attackDamage());
|
||||
}
|
||||
itemProperties.putBoolean("can_destroy_in_creative", canDestroyInCreative);
|
||||
|
||||
String armorType = null;
|
||||
int protectionValue = 0;
|
||||
if (mapping.getArmorType() != null) {
|
||||
computeArmorProperties(mapping.getArmorType(), mapping.getProtectionValue(), itemProperties, componentBuilder);
|
||||
armorType = mapping.getArmorType();
|
||||
protectionValue = customItemData.protectionValue() == -1 ? mapping.getProtectionValue() : customItemData.protectionValue();
|
||||
} else if (customItemData.armorType() != null) {
|
||||
armorType = customItemData.armorType();
|
||||
// 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) {
|
||||
computeArmorProperties(armorType, protectionValue, itemProperties, componentBuilder);
|
||||
}
|
||||
|
||||
if (mapping.getFirstBlockRuntimeId() != null) {
|
||||
computeBlockItemProperties(mapping.getBedrockIdentifier(), componentBuilder);
|
||||
}
|
||||
|
||||
if (mapping.isEdible()) {
|
||||
computeConsumableProperties(itemProperties, componentBuilder, 1, false);
|
||||
if (mapping.isEdible() || customItemData.isEdible()) {
|
||||
computeConsumableProperties(itemProperties, componentBuilder, 1,
|
||||
customItemData.canAlwaysEat());
|
||||
}
|
||||
|
||||
if (mapping.isEntityPlacer()) {
|
||||
computeEntityPlacerProperties(componentBuilder);
|
||||
}
|
||||
|
||||
if (customItemData.isFoil()) {
|
||||
itemProperties.putBoolean("foil", true);
|
||||
}
|
||||
|
||||
switch (mapping.getBedrockIdentifier()) {
|
||||
case "minecraft:fire_charge", "minecraft:flint_and_steel" -> computeBlockItemProperties("minecraft:fire", componentBuilder);
|
||||
case "minecraft:bow", "minecraft:crossbow", "minecraft:trident" -> computeChargeableProperties(itemProperties, componentBuilder, mapping.getBedrockIdentifier(), protocolVersion);
|
||||
|
@ -200,7 +219,7 @@ public class CustomItemRegistryPopulator {
|
|||
}
|
||||
|
||||
// Hardcoded on Java, and should extend to the custom item
|
||||
boolean isHat = (javaItem.equals(Items.SKELETON_SKULL) || javaItem.equals(Items.WITHER_SKELETON_SKULL)
|
||||
boolean isHat = (customItemData.isHat() || javaItem.equals(Items.SKELETON_SKULL) || javaItem.equals(Items.WITHER_SKELETON_SKULL)
|
||||
|| javaItem.equals(Items.CARVED_PUMPKIN) || javaItem.equals(Items.ZOMBIE_HEAD)
|
||||
|| javaItem.equals(Items.PIGLIN_HEAD) || javaItem.equals(Items.DRAGON_HEAD)
|
||||
|| javaItem.equals(Items.CREEPER_HEAD) || javaItem.equals(Items.PLAYER_HEAD)
|
||||
|
@ -213,26 +232,26 @@ public class CustomItemRegistryPopulator {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName,
|
||||
int customItemId, boolean isHat, boolean displayHandheld, int protocolVersion) {
|
||||
private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, int customItemId, int protocolVersion) {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.putString("name", customItemName)
|
||||
builder.putString("name", customItemData.identifier())
|
||||
.putInt("id", customItemId);
|
||||
|
||||
NbtMapBuilder itemProperties = NbtMap.builder();
|
||||
NbtMapBuilder componentBuilder = NbtMap.builder();
|
||||
|
||||
setupBasicItemInfo(customItemData.maxDamage(), customItemData.stackSize(), displayHandheld, customItemData, itemProperties, componentBuilder, protocolVersion);
|
||||
setupBasicItemInfo(Math.max(customItemData.maxDamage(), 0), customItemData.stackSize() == 0 ? 64 : customItemData.stackSize(),
|
||||
customItemData.displayHandheld(), customItemData, itemProperties, componentBuilder, protocolVersion);
|
||||
|
||||
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()) {
|
||||
|
@ -247,7 +266,7 @@ public class CustomItemRegistryPopulator {
|
|||
computeChargeableProperties(itemProperties, componentBuilder, "minecraft:" + tooltype, protocolVersion);
|
||||
}
|
||||
|
||||
computeRenderOffsets(isHat, customItemData, componentBuilder);
|
||||
computeRenderOffsets(customItemData.isHat(), customItemData, componentBuilder);
|
||||
|
||||
if (customItemData.isFoil()) {
|
||||
itemProperties.putBoolean("foil", true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue