Fix for breaking blocks of mismatching properties in adventure mode (#1242)

This commit is contained in:
Konstantin Shandurenko 2022-07-17 21:08:04 +03:00 committed by GitHub
parent 366f08f7f9
commit 284da06578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 12 deletions

View File

@ -3,6 +3,7 @@ package net.minestom.server.item;
import net.kyori.adventure.text.Component;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.attribute.ItemAttribute;
import net.minestom.server.registry.ProtocolObject;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagReadable;
import net.minestom.server.tag.Taggable;
@ -18,6 +19,7 @@ import java.util.function.Consumer;
public sealed interface ItemMeta extends TagReadable, Writeable
permits ItemMetaImpl {
@Override
<T> @UnknownNullability T getTag(@NotNull Tag<T> tag);
@ -69,15 +71,25 @@ public sealed interface ItemMeta extends TagReadable, Writeable
}
@Contract(pure = true)
default @NotNull Set<@NotNull Block> getCanDestroy() {
default @NotNull Set<@NotNull String> getCanDestroy() {
return Set.copyOf(getTag(ItemTags.CAN_DESTROY));
}
@Contract(pure = true)
default @NotNull Set<@NotNull Block> getCanPlaceOn() {
default boolean canDestroy(@NotNull Block block) {
return getCanDestroy().contains(block.name());
}
@Contract(pure = true)
default @NotNull Set<@NotNull String> getCanPlaceOn() {
return Set.copyOf(getTag(ItemTags.CAN_PLACE_ON));
}
@Contract(pure = true)
default boolean canPlaceOn(@NotNull Block block) {
return getCanPlaceOn().contains(block.name());
}
sealed interface Builder extends Taggable
permits ItemMetaImpl.Builder, ItemMetaView.Builder {
@NotNull ItemMeta build();
@ -153,7 +165,7 @@ public sealed interface ItemMeta extends TagReadable, Writeable
@Contract("_ -> this")
default @NotNull Builder canPlaceOn(@NotNull Set<@NotNull Block> blocks) {
return set(ItemTags.CAN_PLACE_ON, blocks.stream().map(block -> Block.fromNamespaceId(block.name())).toList());
return set(ItemTags.CAN_PLACE_ON, blocks.stream().map(ProtocolObject::name).toList());
}
@Contract("_ -> this")
@ -163,7 +175,7 @@ public sealed interface ItemMeta extends TagReadable, Writeable
@Contract("_ -> this")
default @NotNull Builder canDestroy(@NotNull Set<@NotNull Block> blocks) {
return set(ItemTags.CAN_DESTROY, blocks.stream().map(block -> Block.fromNamespaceId(block.name())).toList());
return set(ItemTags.CAN_DESTROY, blocks.stream().map(ProtocolObject::name).toList());
}
@Contract("_ -> this")

View File

@ -30,6 +30,6 @@ final class ItemTags {
return List.copyOf(entries);
}).defaultValue(Map.of());
static final Tag<List<ItemAttribute>> ATTRIBUTES = Tag.Structure("AttributeModifiers", ATTRIBUTE_SERIALIZER).list().defaultValue(List.of());
static final Tag<List<Block>> CAN_PLACE_ON = Tag.String("CanPlaceOn").map(Block::fromNamespaceId, ProtocolObject::name).list().defaultValue(List.of());
static final Tag<List<Block>> CAN_DESTROY = Tag.String("CanDestroy").map(Block::fromNamespaceId, ProtocolObject::name).list().defaultValue(List.of());
static final Tag<List<String>> CAN_PLACE_ON = Tag.String("CanPlaceOn").list().defaultValue(List.of());
static final Tag<List<String>> CAN_DESTROY = Tag.String("CanDestroy").list().defaultValue(List.of());
}

View File

@ -79,7 +79,7 @@ public class BlockPlacementListener {
canPlaceBlock = false; // Spectators can't place blocks
} else if (player.getGameMode() == GameMode.ADVENTURE) {
//Check if the block can be placed on the block
canPlaceBlock = usedItem.meta().getCanPlaceOn().contains(Block.fromNamespaceId(interactedBlock.namespace()));
canPlaceBlock = usedItem.meta().canPlaceOn(interactedBlock);
}
// Get the newly placed block position

View File

@ -99,7 +99,7 @@ public final class PlayerDiggingListener {
} else if (player.getGameMode() == GameMode.ADVENTURE) {
// Check if the item can break the block with the current item
final ItemStack itemInMainHand = player.getItemInMainHand();
if (!itemInMainHand.meta().getCanDestroy().contains(block)) {
if (!itemInMainHand.meta().canDestroy(block)) {
return true;
}
}

View File

@ -13,7 +13,8 @@ public class ItemBlockTest {
var item = ItemStack.builder(Material.STONE)
.meta(builder -> builder.canPlaceOn(Block.STONE))
.build();
assertTrue(item.meta().getCanPlaceOn().contains(Block.STONE));
assertTrue(item.meta().getCanPlaceOn().contains(Block.STONE.name()));
assertTrue(item.meta().canPlaceOn(Block.STONE));
}
@Test
@ -31,7 +32,9 @@ public class ItemBlockTest {
var item = ItemStack.builder(Material.STONE)
.meta(builder -> builder.canPlaceOn(Block.SANDSTONE_STAIRS.withProperty("facing", "south")))
.build();
assertTrue(item.meta().getCanPlaceOn().contains(Block.SANDSTONE_STAIRS));
assertTrue(item.meta().getCanPlaceOn().contains(Block.SANDSTONE_STAIRS.name()));
assertTrue(item.meta().getCanPlaceOn().contains(Block.SANDSTONE_STAIRS.withProperty("facing", "south").name()));
assertTrue(item.meta().canPlaceOn(Block.SANDSTONE_STAIRS.withProperty("facing", "south")));
}
@Test
@ -39,7 +42,8 @@ public class ItemBlockTest {
var item = ItemStack.builder(Material.STONE)
.meta(builder -> builder.canDestroy(Block.STONE))
.build();
assertTrue(item.meta().getCanDestroy().contains(Block.STONE));
assertTrue(item.meta().getCanDestroy().contains(Block.STONE.name()));
assertTrue(item.meta().canDestroy(Block.STONE));
}
@Test
@ -57,6 +61,8 @@ public class ItemBlockTest {
var item = ItemStack.builder(Material.STONE)
.meta(builder -> builder.canDestroy(Block.SANDSTONE_STAIRS.withProperty("facing", "south")))
.build();
assertTrue(item.meta().getCanDestroy().contains(Block.SANDSTONE_STAIRS));
assertTrue(item.meta().getCanDestroy().contains(Block.SANDSTONE_STAIRS.name()));
assertTrue(item.meta().getCanDestroy().contains(Block.SANDSTONE_STAIRS.withProperty("facing", "south").name()));
assertTrue(item.meta().canDestroy(Block.SANDSTONE_STAIRS.withProperty("facing", "south")));
}
}