3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-10-02 08:00:07 +02:00

Mapping option for handheld display & fix for #3346 (#3672)

* Mapping option for handheld display and fix for #3346

* Fix custom items
Dieser Commit ist enthalten in:
ImDaBigBoss 2023-04-11 20:32:31 +02:00 committet von GitHub
Ursprung d22ee51633
Commit 98dceee5e3
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
9 geänderte Dateien mit 106 neuen und 26 gelöschten Zeilen

Datei anzeigen

@ -68,6 +68,13 @@ public interface CustomItemData {
*/ */
boolean allowOffhand(); boolean allowOffhand();
/**
* Gets if the item should be displayed as handheld, like a tool.
*
* @return true if the item should be displayed as handheld, false otherwise
*/
boolean displayHandheld();
/** /**
* Gets the item's texture size. This is to resize the item if the texture is not 16x16. * Gets the item's texture size. This is to resize the item if the texture is not 16x16.
* *
@ -100,6 +107,8 @@ public interface CustomItemData {
Builder allowOffhand(boolean allowOffhand); Builder allowOffhand(boolean allowOffhand);
Builder displayHandheld(boolean displayHandheld);
Builder textureSize(int textureSize); Builder textureSize(int textureSize);
Builder renderOffsets(@Nullable CustomRenderOffsets renderOffsets); Builder renderOffsets(@Nullable CustomRenderOffsets renderOffsets);

Datei anzeigen

@ -56,6 +56,14 @@ public interface CustomItemOptions {
*/ */
@NonNull OptionalInt damagePredicate(); @NonNull OptionalInt damagePredicate();
/**
* Gets if this mapping should just translate to the default item.
* This is used for the damage predicate of damaged 1 damage 0 that is required to allow the default item to exist.
*
* @return true if this mapping should just translate to the default item, false otherwise
*/
boolean defaultItem();
/** /**
* Checks if the item has at least one option set * Checks if the item has at least one option set
* *
@ -78,6 +86,8 @@ public interface CustomItemOptions {
Builder damagePredicate(int damagePredicate); Builder damagePredicate(int damagePredicate);
Builder defaultItem(boolean defaultItem);
CustomItemOptions build(); CustomItemOptions build();
} }
} }

Datei anzeigen

@ -130,17 +130,22 @@ public interface NonVanillaCustomItemData extends CustomItemData {
boolean isHat(); boolean isHat();
/** /**
* @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. * Gets if the item is a tool. This is used to set the render type of the item, if the item is handheld.
* *
* @return if the item is a tool * @return if the item is a tool
*/ */
boolean isTool(); @Deprecated
default boolean isTool() {
return displayHandheld();
}
static NonVanillaCustomItemData.Builder builder() { static NonVanillaCustomItemData.Builder builder() {
return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class); return GeyserApi.api().provider(NonVanillaCustomItemData.Builder.class);
} }
interface Builder extends CustomItemData.Builder { interface Builder extends CustomItemData.Builder {
@Override
Builder name(@NonNull String name); Builder name(@NonNull String name);
Builder identifier(@NonNull String identifier); Builder identifier(@NonNull String identifier);
@ -169,14 +174,29 @@ public interface NonVanillaCustomItemData extends CustomItemData {
Builder hat(boolean isHat); Builder hat(boolean isHat);
Builder tool(boolean isTool); /**
* @deprecated Use {@link #displayHandheld(boolean)} instead.
*/
@Deprecated
default Builder tool(boolean isTool) {
return displayHandheld(isTool);
}
@Override
Builder customItemOptions(@NonNull CustomItemOptions customItemOptions);
@Override @Override
Builder displayName(@NonNull String displayName); Builder displayName(@NonNull String displayName);
@Override
Builder icon(@NonNull String icon);
@Override @Override
Builder allowOffhand(boolean allowOffhand); Builder allowOffhand(boolean allowOffhand);
@Override
Builder displayHandheld(boolean displayHandheld);
@Override @Override
Builder textureSize(int textureSize); Builder textureSize(int textureSize);

Datei anzeigen

@ -41,6 +41,7 @@ public class GeyserCustomItemData implements CustomItemData {
private final String displayName; private final String displayName;
private final String icon; private final String icon;
private final boolean allowOffhand; private final boolean allowOffhand;
private final boolean displayHandheld;
private final int textureSize; private final int textureSize;
private final CustomRenderOffsets renderOffsets; private final CustomRenderOffsets renderOffsets;
@ -49,6 +50,7 @@ public class GeyserCustomItemData implements CustomItemData {
String displayName, String displayName,
String icon, String icon,
boolean allowOffhand, boolean allowOffhand,
boolean displayHandheld,
int textureSize, int textureSize,
CustomRenderOffsets renderOffsets) { CustomRenderOffsets renderOffsets) {
this.name = name; this.name = name;
@ -56,34 +58,47 @@ public class GeyserCustomItemData implements CustomItemData {
this.displayName = displayName; this.displayName = displayName;
this.icon = icon; this.icon = icon;
this.allowOffhand = allowOffhand; this.allowOffhand = allowOffhand;
this.displayHandheld = displayHandheld;
this.textureSize = textureSize; this.textureSize = textureSize;
this.renderOffsets = renderOffsets; this.renderOffsets = renderOffsets;
} }
@Override
public @NotNull String name() { public @NotNull String name() {
return name; return name;
} }
@Override
public CustomItemOptions customItemOptions() { public CustomItemOptions customItemOptions() {
return customItemOptions; return customItemOptions;
} }
@Override
public @NotNull String displayName() { public @NotNull String displayName() {
return displayName; return displayName;
} }
@Override
public @NotNull String icon() { public @NotNull String icon() {
return icon; return icon;
} }
@Override
public boolean allowOffhand() { public boolean allowOffhand() {
return allowOffhand; return allowOffhand;
} }
@Override
public boolean displayHandheld() {
return this.displayHandheld;
}
@Override
public int textureSize() { public int textureSize() {
return textureSize; return textureSize;
} }
@Override
public CustomRenderOffsets renderOffsets() { public CustomRenderOffsets renderOffsets() {
return renderOffsets; return renderOffsets;
} }
@ -95,6 +110,7 @@ public class GeyserCustomItemData implements CustomItemData {
protected String displayName = null; protected String displayName = null;
protected String icon = null; protected String icon = null;
protected boolean allowOffhand = true; // Bedrock doesn't give items offhand allowance unless they serve gameplay purpose, but we want to be friendly with Java protected boolean allowOffhand = true; // Bedrock doesn't give items offhand allowance unless they serve gameplay purpose, but we want to be friendly with Java
protected boolean displayHandheld = false;
protected int textureSize = 16; protected int textureSize = 16;
protected CustomRenderOffsets renderOffsets = null; protected CustomRenderOffsets renderOffsets = null;
@ -128,6 +144,12 @@ public class GeyserCustomItemData implements CustomItemData {
return this; return this;
} }
@Override
public Builder displayHandheld(boolean displayHandheld) {
this.displayHandheld = displayHandheld;
return this;
}
@Override @Override
public Builder textureSize(int textureSize) { public Builder textureSize(int textureSize) {
this.textureSize = textureSize; this.textureSize = textureSize;
@ -152,7 +174,7 @@ public class GeyserCustomItemData implements CustomItemData {
if (this.icon == null) { if (this.icon == null) {
this.icon = this.name; this.icon = this.name;
} }
return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand, this.textureSize, this.renderOffsets); return new GeyserCustomItemData(this.name, this.customItemOptions, this.displayName, this.icon, this.allowOffhand, this.displayHandheld, this.textureSize, this.renderOffsets);
} }
} }
} }

Datei anzeigen

@ -32,12 +32,18 @@ import java.util.OptionalInt;
public record GeyserCustomItemOptions(TriState unbreakable, public record GeyserCustomItemOptions(TriState unbreakable,
OptionalInt customModelData, OptionalInt customModelData,
OptionalInt damagePredicate) implements CustomItemOptions { OptionalInt damagePredicate,
boolean defaultItem) implements CustomItemOptions {
public GeyserCustomItemOptions(TriState unbreakable, OptionalInt customModelData, OptionalInt damagePredicate) {
this(unbreakable, customModelData, damagePredicate, false);
}
public static class CustomItemOptionsBuilder implements CustomItemOptions.Builder { public static class CustomItemOptionsBuilder implements CustomItemOptions.Builder {
private TriState unbreakable = TriState.NOT_SET; private TriState unbreakable = TriState.NOT_SET;
private OptionalInt customModelData = OptionalInt.empty(); private OptionalInt customModelData = OptionalInt.empty();
private OptionalInt damagePredicate = OptionalInt.empty(); private OptionalInt damagePredicate = OptionalInt.empty();
private boolean defaultItem = false;
@Override @Override
public Builder unbreakable(boolean unbreakable) { public Builder unbreakable(boolean unbreakable) {
@ -61,9 +67,15 @@ public record GeyserCustomItemOptions(TriState unbreakable,
return this; return this;
} }
@Override
public Builder defaultItem(boolean defaultItem) {
this.defaultItem = defaultItem;
return this;
}
@Override @Override
public CustomItemOptions build() { public CustomItemOptions build() {
return new GeyserCustomItemOptions(unbreakable, customModelData, damagePredicate); return new GeyserCustomItemOptions(this.unbreakable, this.customModelData, this.damagePredicate, this.defaultItem);
} }
} }
} }

Datei anzeigen

@ -57,7 +57,7 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
public GeyserNonVanillaCustomItemData(NonVanillaCustomItemDataBuilder builder) { public GeyserNonVanillaCustomItemData(NonVanillaCustomItemDataBuilder builder) {
super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand, super(builder.name, builder.customItemOptions, builder.displayName, builder.icon, builder.allowOffhand,
builder.textureSize, builder.renderOffsets); builder.displayHandheld, builder.textureSize, builder.renderOffsets);
this.identifier = builder.identifier; this.identifier = builder.identifier;
this.javaId = builder.javaId; this.javaId = builder.javaId;
@ -140,11 +140,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
return isHat; return isHat;
} }
@Override
public boolean isTool() {
return isTool;
}
public static class NonVanillaCustomItemDataBuilder extends GeyserCustomItemData.CustomItemDataBuilder implements NonVanillaCustomItemData.Builder { public static class NonVanillaCustomItemDataBuilder extends GeyserCustomItemData.CustomItemDataBuilder implements NonVanillaCustomItemData.Builder {
private String identifier = null; private String identifier = null;
private int javaId = -1; private int javaId = -1;
@ -185,6 +180,11 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
return (NonVanillaCustomItemData.Builder) super.allowOffhand(allowOffhand); return (NonVanillaCustomItemData.Builder) super.allowOffhand(allowOffhand);
} }
@Override
public NonVanillaCustomItemData.Builder displayHandheld(boolean displayHandheld) {
return (NonVanillaCustomItemData.Builder) super.displayHandheld(displayHandheld);
}
@Override @Override
public NonVanillaCustomItemData.Builder displayName(@NonNull String displayName) { public NonVanillaCustomItemData.Builder displayName(@NonNull String displayName) {
return (NonVanillaCustomItemData.Builder) super.displayName(displayName); return (NonVanillaCustomItemData.Builder) super.displayName(displayName);
@ -283,12 +283,6 @@ public final class GeyserNonVanillaCustomItemData extends GeyserCustomItemData i
return this; return this;
} }
@Override
public NonVanillaCustomItemData.Builder tool(boolean isTool) {
this.tool = isTool;
return this;
}
@Override @Override
public NonVanillaCustomItemData build() { public NonVanillaCustomItemData build() {
if (identifier == null || javaId == -1) { if (identifier == null || javaId == -1) {

Datei anzeigen

@ -77,6 +77,11 @@ public class MappingsReader_v1 extends MappingsReader {
customItemOptions.unbreakable(unbreakable.asBoolean()); customItemOptions.unbreakable(unbreakable.asBoolean());
} }
JsonNode defaultItem = node.get("default");
if (defaultItem != null && defaultItem.isBoolean()) {
customItemOptions.defaultItem(defaultItem.asBoolean());
}
return customItemOptions.build(); return customItemOptions.build();
} }
@ -86,13 +91,13 @@ public class MappingsReader_v1 extends MappingsReader {
throw new InvalidCustomMappingsFileException("Invalid item mappings entry"); throw new InvalidCustomMappingsFileException("Invalid item mappings entry");
} }
String name = node.get("name").asText(); JsonNode name = node.get("name");
if (name == null || name.isEmpty()) { if (name == null || !name.isTextual() || name.asText().isEmpty()) {
throw new InvalidCustomMappingsFileException("An item entry has no name"); throw new InvalidCustomMappingsFileException("An item entry has no name");
} }
CustomItemData.Builder customItemData = CustomItemData.builder() CustomItemData.Builder customItemData = CustomItemData.builder()
.name(name) .name(name.asText())
.customItemOptions(this.readItemCustomItemOptions(node)); .customItemOptions(this.readItemCustomItemOptions(node));
//The next entries are optional //The next entries are optional
@ -108,6 +113,10 @@ public class MappingsReader_v1 extends MappingsReader {
customItemData.allowOffhand(node.get("allow_offhand").asBoolean()); customItemData.allowOffhand(node.get("allow_offhand").asBoolean());
} }
if (node.has("display_handheld")) {
customItemData.displayHandheld(node.get("display_handheld").asBoolean());
}
if (node.has("texture_size")) { if (node.has("texture_size")) {
customItemData.textureSize(node.get("texture_size").asInt()); customItemData.textureSize(node.get("texture_size").asInt());
} }

Datei anzeigen

@ -153,7 +153,7 @@ public class CustomItemRegistryPopulator {
.build(); .build();
NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId, NbtMapBuilder builder = createComponentNbt(customItemData, customItemData.identifier(), customItemId,
customItemData.creativeCategory(), customItemData.creativeGroup(), customItemData.isHat(), customItemData.isTool()); customItemData.creativeCategory(), customItemData.creativeGroup(), customItemData.isHat(), customItemData.displayHandheld());
ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build()); ComponentItemData componentItemData = new ComponentItemData(customIdentifier, builder.build());
return new NonVanillaItemRegistration(componentItemData, item, customItemMapping); return new NonVanillaItemRegistration(componentItemData, item, customItemMapping);
@ -168,7 +168,7 @@ public class CustomItemRegistryPopulator {
NbtMapBuilder itemProperties = NbtMap.builder(); NbtMapBuilder itemProperties = NbtMap.builder();
NbtMapBuilder componentBuilder = NbtMap.builder(); NbtMapBuilder componentBuilder = NbtMap.builder();
setupBasicItemInfo(mapping.getMaxDamage(), mapping.getStackSize(), mapping.getToolType() != null, customItemData, itemProperties, componentBuilder); setupBasicItemInfo(mapping.getMaxDamage(), mapping.getStackSize(), mapping.getToolType() != null || customItemData.displayHandheld(), customItemData, itemProperties, componentBuilder);
boolean canDestroyInCreative = true; boolean canDestroyInCreative = true;
if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here. if (mapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here.
@ -217,7 +217,7 @@ public class CustomItemRegistryPopulator {
private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName, private static NbtMapBuilder createComponentNbt(NonVanillaCustomItemData customItemData, String customItemName,
int customItemId, OptionalInt creativeCategory, int customItemId, OptionalInt creativeCategory,
String creativeGroup, boolean isHat, boolean isTool) { String creativeGroup, boolean isHat, boolean displayHandheld) {
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.putString("name", customItemName) builder.putString("name", customItemName)
.putInt("id", customItemId); .putInt("id", customItemId);
@ -225,7 +225,7 @@ public class CustomItemRegistryPopulator {
NbtMapBuilder itemProperties = NbtMap.builder(); NbtMapBuilder itemProperties = NbtMap.builder();
NbtMapBuilder componentBuilder = NbtMap.builder(); NbtMapBuilder componentBuilder = NbtMap.builder();
setupBasicItemInfo(customItemData.maxDamage(), customItemData.stackSize(), isTool, customItemData, itemProperties, componentBuilder); setupBasicItemInfo(customItemData.maxDamage(), customItemData.stackSize(), displayHandheld, customItemData, itemProperties, componentBuilder);
boolean canDestroyInCreative = true; boolean canDestroyInCreative = true;
if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here. if (customItemData.toolType() != null) { // This is not using the isTool boolean because it is not just a render type here.
@ -253,14 +253,14 @@ public class CustomItemRegistryPopulator {
return builder; return builder;
} }
private static void setupBasicItemInfo(int maxDamage, int stackSize, boolean isTool, CustomItemData customItemData, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) { private static void setupBasicItemInfo(int maxDamage, int stackSize, boolean displayHandheld, CustomItemData customItemData, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) {
itemProperties.putCompound("minecraft:icon", NbtMap.builder() itemProperties.putCompound("minecraft:icon", NbtMap.builder()
.putString("texture", customItemData.icon()) .putString("texture", customItemData.icon())
.build()); .build());
componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", customItemData.displayName()).build()); componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", customItemData.displayName()).build());
itemProperties.putBoolean("allow_off_hand", customItemData.allowOffhand()); itemProperties.putBoolean("allow_off_hand", customItemData.allowOffhand());
itemProperties.putBoolean("hand_equipped", isTool); itemProperties.putBoolean("hand_equipped", displayHandheld);
itemProperties.putInt("max_stack_size", stackSize); itemProperties.putInt("max_stack_size", stackSize);
// Ignore durability if the item's predicate requires that it be unbreakable // Ignore durability if the item's predicate requires that it be unbreakable
if (maxDamage > 0 && customItemData.customItemOptions().unbreakable() != TriState.TRUE) { if (maxDamage > 0 && customItemData.customItemOptions().unbreakable() != TriState.TRUE) {

Datei anzeigen

@ -93,6 +93,10 @@ public final class CustomItemTranslator {
continue; continue;
} }
if (options.defaultItem()) {
return null;
}
return mappingTypes.value(); return mappingTypes.value();
} }