Implement metadata checking into the NBT path of block.properties parsing (#2267)

This commit is contained in:
gorbit99 authored and GitHub committed 2026-10-17 18:39:12 -07:00
1 parent 482dece0f7
commit 69019b9a62
4 files changed
+21 -8

No files matched your search

@@ -488,7 +488,7 @@ public abstract class AngelicaChunkBuilderMeshingTask extends ChunkBuilderTask<C
if (te != null) {
final NBTTagCompound teNbt = new NBTTagCompound();
te.writeToNBT(teNbt);
teBlockId = teMap.resolve(block, teNbt);
teBlockId = teMap.resolve(block, teNbt, metadata);
} else {
teBlockId = -1;
}
@@ -103,7 +103,7 @@ public class BlockMaterialMapping {
nbtEntries.forEach((intId, entries) -> {
for (BlockEntry entry : entries) {
if (entry.hasNbtProperties()) {
map.addCondition(entry.id(), entry.nbtProperties(), intId);
map.addCondition(entry.id(), entry.nbtProperties(), intId, entry.metas());
}
}
});
@@ -121,7 +121,7 @@ public class BlockMaterialMapping {
return;
}
teMap.addCondition(block, entry.nbtProperties(), intId);
teMap.addCondition(block, entry.nbtProperties(), intId, entry.metas());
}
/**
@@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Maps objects with specific NBT properties to shader IDs. Generic over the
@@ -34,7 +35,9 @@ public class NbtConditionalIdMap<K> {
boolean isExistenceOnly() { return expectedValue == null; }
}
record NbtCondition(PropertyMatcher[] matchers, int shaderId) {}
record NbtCondition(PropertyMatcher[] matchers, Set<Integer> metas, int shaderId) {
boolean isMetaMatch() { return metas != null && !metas.isEmpty(); }
}
private final Map<K, List<NbtCondition>> conditionsByKey;
@@ -47,7 +50,7 @@ public class NbtConditionalIdMap<K> {
* registries at registration time. Single-quoted values are kept as literals.
* Dot notation paths are pre-split here so we prevent allocations.
*/
public void addCondition(K key, Map<String, PropertiesTokenizer.NbtValue> nbtProperties, int shaderId) {
public void addCondition(K key, Map<String, PropertiesTokenizer.NbtValue> nbtProperties, int shaderId, Set<Integer> metas) {
final PropertyMatcher[] matchers = new PropertyMatcher[nbtProperties.size()];
int i = 0;
@@ -88,7 +91,7 @@ public class NbtConditionalIdMap<K> {
}
conditionsByKey.computeIfAbsent(key, k -> new ArrayList<>())
.add(new NbtCondition(matchers, shaderId));
.add(new NbtCondition(matchers, metas, shaderId));
}
public boolean hasConditions(K key) {
@@ -102,13 +105,16 @@ public class NbtConditionalIdMap<K> {
/**
* Resolves the shader ID by matching the provided NBT data.
*/
public int resolve(K key, NBTTagCompound nbt) {
public int resolve(K key, NBTTagCompound nbt, Integer meta) {
final List<NbtCondition> conditions = conditionsByKey.get(key);
if (conditions == null) {
return -1;
}
for (NbtCondition condition : conditions) {
if (meta != null && condition.isMetaMatch() && !condition.metas.contains(meta)) {
continue;
}
if (matchesNbt(nbt, condition.matchers())) {
return condition.shaderId;
}
@@ -117,6 +123,13 @@ public class NbtConditionalIdMap<K> {
return -1;
}
/**
* Resolves the shader ID by matching the provided NBT data.
*/
public int resolve(K key, NBTTagCompound nbt) {
return resolve(key, nbt, null);
}
private static boolean matchesNbt(NBTTagCompound nbt, PropertyMatcher[] matchers) {
for (PropertyMatcher matcher : matchers) {
if (matcher.isPathMatch()) {
@@ -75,7 +75,7 @@ class EntityIdHelperTest {
for (int id : new int[] { 41, 42 }) {
settings.setEntityIds(key -> name.equals(key) ? 17 : -1);
final NbtConditionalIdMap<NamespacedId> nbt = new NbtConditionalIdMap<>();
nbt.addCondition(name, Collections.singletonMap("Data.Variant", new NbtValue("original", true)), id);
nbt.addCondition(name, Collections.singletonMap("Data.Variant", new NbtValue("original", true)), id, null);
settings.setEntityNbtMap(nbt);
assertEquals(id, identity.resolve(), "resolve the captured variant against the current pack");
assertEquals(17, EntityIdHelper.getEntityId(entity), "the live entity has changed variants");