diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java index f9d2cd4e2..85d2ff180 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20_5to1_20_3/rewriter/BlockItemPacketRewriter1_20_5.java @@ -445,9 +445,16 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter ); + register(StructuredDataKey.CAN_PLACE_ON, (data, tag) -> convertBlockPredicates(tag, data, "CanPlaceOn", HIDE_CAN_PLACE_ON)); + register(StructuredDataKey.CAN_BREAK, (data, tag) -> convertBlockPredicates(tag, data, "CanDestroy", HIDE_CAN_DESTROY)); //TODO - // StructuredDataKey.CAN_PLACE_ON - // StructuredDataKey.CAN_BREAK // StructuredDataKey TRIM // StructuredDataKey BLOCK_STATE // StructuredDataKey CONTAINER // StructuredDataKey INTANGIBLE_PROJECTILE } + private static void convertBlockPredicates(final CompoundTag tag, final AdventureModePredicate data, final String key, final int hideFlag) { + final ListTag predicatedListTag = new ListTag<>(StringTag.class); + for (final BlockPredicate predicate : data.predicates()) { + final HolderSet holders = predicate.predicates(); + if (holders == null) { + // Can't do (nicely) + continue; + } + + if (holders.isLeft()) { + final String identifier = holders.left(); + predicatedListTag.add(serializeBlockPredicate(predicate, identifier)); + } else { + for (final int id : holders.right()) { + final int oldId = Protocol1_20_5To1_20_3.MAPPINGS.getOldItemId(id); + final String identifier = Protocol1_20_5To1_20_3.MAPPINGS.itemName(oldId); + predicatedListTag.add(serializeBlockPredicate(predicate, identifier)); + } + } + } + + tag.put(key, predicatedListTag); + if (!data.showInTooltip()) { + putHideFlag(tag, hideFlag); + } + } + + private static StringTag serializeBlockPredicate(final BlockPredicate predicate, final String identifier) { + final StringBuilder builder = new StringBuilder(identifier); + if (predicate.propertyMatchers() != null) { + for (final StatePropertyMatcher matcher : predicate.propertyMatchers()) { + // I'm not sure if ranged values were possible in 1.20.4 (if so, there's no trace of how) + if (matcher.matcher().isLeft()) { + builder.append(matcher.name()).append('='); + builder.append(matcher.matcher().left()); + } + } + } + if (predicate.tag() != null) { + builder.append(predicate.tag()); + } + return new StringTag(builder.toString()); + } + private static CompoundTag getBlockEntityTag(final CompoundTag tag) { CompoundTag subTag = tag.getCompoundTag("BlockEntityTag"); if (subTag == null) {