Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-04 23:30:17 +01:00
Fix some regressions in custom item handling
Dieser Commit ist enthalten in:
Ursprung
f59e33d749
Commit
8bf8b22d6b
@ -51,8 +51,9 @@ final class CustomItemTranslator {
|
||||
}
|
||||
|
||||
int customModelData = nbt.get("CustomModelData") instanceof IntTag customModelDataTag ? customModelDataTag.getValue() : 0;
|
||||
int damage = nbt.get("Damage") instanceof IntTag damageTag ? damageTag.getValue() : 0;
|
||||
boolean unbreakable = !isDamaged(mapping, nbt, damage);
|
||||
boolean checkDamage = mapping.getMaxDamage() > 0;
|
||||
int damage = !checkDamage ? 0 : nbt.get("Damage") instanceof IntTag damageTag ? damageTag.getValue() : 0;
|
||||
boolean unbreakable = checkDamage && !isDamaged(nbt, damage);
|
||||
|
||||
for (ObjectIntPair<CustomItemOptions> mappingTypes : customMappings) {
|
||||
CustomItemOptions options = mappingTypes.key();
|
||||
@ -67,8 +68,21 @@ final class CustomItemTranslator {
|
||||
// The same behavior exists for Damage (in fraction form instead of whole numbers),
|
||||
// and Damaged/Unbreakable handles no damage as 0f and damaged as 1f.
|
||||
|
||||
if (unbreakable && options.unbreakable() != TriState.TRUE) {
|
||||
continue;
|
||||
if (checkDamage) {
|
||||
if (unbreakable && options.unbreakable() == TriState.FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OptionalInt damagePredicate = options.damagePredicate();
|
||||
if (damagePredicate.isPresent() && damage < damagePredicate.getAsInt()) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (options.unbreakable() != TriState.NOT_SET || options.damagePredicate().isPresent()) {
|
||||
// These will never match on this item. 1.19.2 behavior
|
||||
// Maybe move this to CustomItemRegistryPopulator since it'll be the same for every item? If so, add a test.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
OptionalInt customModelDataOption = options.customModelData();
|
||||
@ -76,11 +90,6 @@ final class CustomItemTranslator {
|
||||
continue;
|
||||
}
|
||||
|
||||
OptionalInt damagePredicate = options.damagePredicate();
|
||||
if (damagePredicate.isPresent() && damage < damagePredicate.getAsInt()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return mappingTypes.valueInt();
|
||||
}
|
||||
return -1;
|
||||
@ -88,16 +97,15 @@ final class CustomItemTranslator {
|
||||
|
||||
/* These two functions are based off their Mojmap equivalents from 1.19.2 */
|
||||
|
||||
private static boolean isDamaged(ItemMapping mapping, CompoundTag nbt, int damage) {
|
||||
return isDamagableItem(mapping, nbt) && damage > 0;
|
||||
private static boolean isDamaged(CompoundTag nbt, int damage) {
|
||||
return isDamagableItem(nbt) && damage > 0;
|
||||
}
|
||||
|
||||
private static boolean isDamagableItem(ItemMapping mapping, CompoundTag nbt) {
|
||||
if (mapping.getMaxDamage() > 0) {
|
||||
Tag unbreakableTag = nbt.get("Unbreakable");
|
||||
return unbreakableTag != null && unbreakableTag.getValue() instanceof Number number && number.byteValue() == 0;
|
||||
}
|
||||
return false;
|
||||
private static boolean isDamagableItem(CompoundTag nbt) {
|
||||
// mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function
|
||||
Tag unbreakableTag = nbt.get("Unbreakable");
|
||||
// Tag must either not be present or be set to false
|
||||
return unbreakableTag == null || !(unbreakableTag.getValue() instanceof Number number) || number.byteValue() == 0;
|
||||
}
|
||||
|
||||
private CustomItemTranslator() {
|
||||
|
@ -40,11 +40,14 @@ import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
public class CustomItemsTest {
|
||||
private ItemMapping testMappingWithDamage;
|
||||
private Object2IntMap<CompoundTag> tagToCustomItemWithDamage;
|
||||
private ItemMapping testMappingWithNoDamage;
|
||||
private Object2IntMap<CompoundTag> tagToCustomItemWithNoDamage;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@ -54,9 +57,11 @@ public class CustomItemsTest {
|
||||
CustomItemOptions d = new GeyserCustomItemOptions(TriState.TRUE, OptionalInt.empty(), OptionalInt.of(8));
|
||||
CustomItemOptions e = new GeyserCustomItemOptions(TriState.FALSE, OptionalInt.empty(), OptionalInt.of(12));
|
||||
CustomItemOptions f = new GeyserCustomItemOptions(TriState.FALSE, OptionalInt.of(8), OptionalInt.of(6));
|
||||
CustomItemOptions g = new GeyserCustomItemOptions(TriState.NOT_SET, OptionalInt.of(20), OptionalInt.empty());
|
||||
|
||||
Object2IntMap<CustomItemOptions> optionsToId = new Object2IntArrayMap<>();
|
||||
// Order here is important, hence why we're using an array map
|
||||
optionsToId.put(g, 7);
|
||||
optionsToId.put(f, 6);
|
||||
optionsToId.put(e, 5);
|
||||
optionsToId.put(d, 4);
|
||||
@ -72,38 +77,70 @@ public class CustomItemsTest {
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(a));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("CustomModelData", 3));
|
||||
tag.put(new ByteTag("Unbreakable", (byte) 1));
|
||||
addCustomModelData(20, tag);
|
||||
// Test that an unbreakable item isn't tested for Damaged if there is no damaged predicate
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(g));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
addCustomModelData(3, tag);
|
||||
setUnbreakable(true, tag);
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(a));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("Damage", 16));
|
||||
tag.put(new ByteTag("Unbreakable", (byte) 0));
|
||||
addDamage(16, tag);
|
||||
setUnbreakable(false, tag);
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(e));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("CustomModelData", 7));
|
||||
tag.put(new IntTag("Damage", 6));
|
||||
tag.put(new ByteTag("Unbreakable", (byte) 0));
|
||||
addCustomModelData(7, tag);
|
||||
addDamage(6, tag);
|
||||
setUnbreakable(false, tag);
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(c));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("CustomModelData", 8));
|
||||
tag.put(new IntTag("Damage", 6));
|
||||
tag.put(new ByteTag("Unbreakable", (byte) 1));
|
||||
addCustomModelData(9, tag);
|
||||
addDamage(6, tag);
|
||||
setUnbreakable(true, tag);
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(a));
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("CustomModelData", 9));
|
||||
tag.put(new IntTag("Damage", 6));
|
||||
tag.put(new ByteTag("Unbreakable", (byte) 0));
|
||||
addCustomModelData(9, tag);
|
||||
addDamage(6, tag);
|
||||
setUnbreakable(false, tag);
|
||||
tagToCustomItemWithDamage.put(tag, optionsToId.getInt(f));
|
||||
|
||||
List<ObjectIntPair<CustomItemOptions>> customItemOptions = optionsToId.object2IntEntrySet().stream().map(entry -> ObjectIntPair.of(entry.getKey(), entry.getIntValue())).toList();
|
||||
|
||||
testMappingWithDamage = ItemMapping.builder()
|
||||
.customItemOptions(optionsToId.object2IntEntrySet().stream().map(entry -> ObjectIntPair.of(entry.getKey(), entry.getIntValue())).toList())
|
||||
.customItemOptions(customItemOptions)
|
||||
.maxDamage(100)
|
||||
.build();
|
||||
// Later, possibly add a condition with a mapping with no damage
|
||||
|
||||
// Test differences with items with no max damage
|
||||
|
||||
tagToCustomItemWithNoDamage = new Object2IntOpenHashMap<>();
|
||||
|
||||
tag = new CompoundTag("");
|
||||
tag.put(new IntTag("CustomModelData", 2));
|
||||
// Damage predicates existing mean an item will never match if the item mapping has no max damage
|
||||
tagToCustomItemWithNoDamage.put(tag, -1);
|
||||
|
||||
testMappingWithNoDamage = ItemMapping.builder()
|
||||
.customItemOptions(customItemOptions)
|
||||
.maxDamage(0)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void addCustomModelData(int value, CompoundTag tag) {
|
||||
tag.put(new IntTag("CustomModelData", value));
|
||||
}
|
||||
|
||||
private void addDamage(int value, CompoundTag tag) {
|
||||
tag.put(new IntTag("Damage", value));
|
||||
}
|
||||
|
||||
private void setUnbreakable(boolean value, CompoundTag tag) {
|
||||
tag.put(new ByteTag("Unbreakable", (byte) (value ? 1 : 0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -112,5 +149,10 @@ public class CustomItemsTest {
|
||||
int id = CustomItemTranslator.getCustomItem(entry.getKey(), this.testMappingWithDamage);
|
||||
Assert.assertEquals(entry.getKey() + " did not produce the correct custom item", entry.getIntValue(), id);
|
||||
}
|
||||
|
||||
for (Object2IntMap.Entry<CompoundTag> entry : this.tagToCustomItemWithNoDamage.object2IntEntrySet()) {
|
||||
int id = CustomItemTranslator.getCustomItem(entry.getKey(), this.testMappingWithNoDamage);
|
||||
Assert.assertEquals(entry.getKey() + " did not produce the correct custom item", entry.getIntValue(), id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren