From e0c2c4b6552ee3d51102510291a5e0f84221c9e5 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 11 Apr 2021 00:42:09 +0200 Subject: [PATCH] Support for canPlace & canDestroy meta --- .../net/minestom/server/item/ItemMeta.java | 29 +++++++++---- .../minestom/server/item/ItemMetaBuilder.java | 27 ++++++++++++ .../listener/BlockPlacementListener.java | 4 +- .../listener/PlayerDiggingListener.java | 6 +-- .../net/minestom/server/utils/NBTUtils.java | 42 ++++++++----------- src/test/java/demo/PlayerInit.java | 8 +++- 6 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMeta.java b/src/main/java/net/minestom/server/item/ItemMeta.java index 39b282dae..e859813ad 100644 --- a/src/main/java/net/minestom/server/item/ItemMeta.java +++ b/src/main/java/net/minestom/server/item/ItemMeta.java @@ -1,6 +1,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.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.Writeable; @@ -9,10 +10,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; public class ItemMeta implements Writeable { @@ -28,6 +26,9 @@ public class ItemMeta implements Writeable { private final int customModelData; + private final Set canDestroy; + private final Set canPlaceOn; + private final NBTCompound nbt; private final ItemMetaBuilder emptyBuilder; @@ -43,6 +44,8 @@ public class ItemMeta implements Writeable { this.enchantmentMap = new HashMap<>(metaBuilder.enchantmentMap); this.attributes = new ArrayList<>(metaBuilder.attributes); this.customModelData = metaBuilder.customModelData; + this.canDestroy = new HashSet<>(metaBuilder.canDestroy); + this.canPlaceOn = new HashSet<>(metaBuilder.canPlaceOn); this.nbt = metaBuilder.nbt; this.emptyBuilder = metaBuilder.getSupplier().get(); @@ -77,17 +80,17 @@ public class ItemMeta implements Writeable { @Contract(pure = true) public @NotNull List<@NotNull Component> getLore() { - return lore; + return Collections.unmodifiableList(lore); } @Contract(pure = true) public @NotNull Map getEnchantmentMap() { - return enchantmentMap; + return Collections.unmodifiableMap(enchantmentMap); } @Contract(pure = true) - public @NotNull List getAttributes() { - return attributes; + public @NotNull List<@NotNull ItemAttribute> getAttributes() { + return Collections.unmodifiableList(attributes); } @Contract(pure = true) @@ -95,6 +98,16 @@ public class ItemMeta implements Writeable { return customModelData; } + @Contract(pure = true) + public @NotNull Set<@NotNull Block> getCanDestroy() { + return Collections.unmodifiableSet(canDestroy); + } + + @Contract(pure = true) + public @NotNull Set<@NotNull Block> getCanPlaceOn() { + return Collections.unmodifiableSet(canPlaceOn); + } + public T getOrDefault(@NotNull ItemTag tag, @Nullable T defaultValue) { var key = tag.getKey(); if (nbt.containsKey(key)) { diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index b70d99b5c..09a5c4c91 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -3,6 +3,7 @@ package net.minestom.server.item; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minestom.server.adventure.AdventureSerializer; +import net.minestom.server.instance.block.Block; import net.minestom.server.item.attribute.ItemAttribute; import net.minestom.server.utils.NBTUtils; import net.minestom.server.utils.Utils; @@ -27,6 +28,8 @@ public abstract class ItemMetaBuilder { protected Map enchantmentMap = new HashMap<>(); protected List attributes = new ArrayList<>(); protected int customModelData; + protected Set canDestroy = new HashSet<>(); + protected Set canPlaceOn = new HashSet<>(); @Contract("_ -> this") public @NotNull ItemMetaBuilder damage(int damage) { @@ -146,6 +149,30 @@ public abstract class ItemMetaBuilder { return this; } + @Contract("_ -> this") + public @NotNull ItemMetaBuilder canPlaceOn(@NotNull Set<@NotNull Block> blocks) { + this.canPlaceOn = blocks; + handleCollection(canPlaceOn, "CanPlaceOn", nbt, () -> { + NBTList list = new NBTList<>(NBTTypes.TAG_String); + canPlaceOn.forEach(block -> list.add(new NBTString(block.getName()))); + nbt.set("CanPlaceOn", list); + return list; + }); + return this; + } + + @Contract("_ -> this") + public @NotNull ItemMetaBuilder canDestroy(@NotNull Set<@NotNull Block> blocks) { + this.canDestroy = blocks; + handleCollection(canDestroy, "CanDestroy", nbt, () -> { + NBTList list = new NBTList<>(NBTTypes.TAG_String); + canDestroy.forEach(block -> list.add(new NBTString(block.getName()))); + nbt.set("CanDestroy", list); + return list; + }); + return this; + } + public @NotNull ItemMetaBuilder set(@NotNull ItemTag tag, @Nullable T value) { if (value != null) { tag.write(nbt, value); diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index f6eb3bfc3..413d34a6d 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -86,8 +86,8 @@ public class BlockPlacementListener { canPlaceBlock = false; //Spectators can't place blocks } else if (player.getGameMode() == GameMode.ADVENTURE) { //Check if the block can placed on the block - // FIXME: canPlaceOn - canPlaceBlock = true;//usedItem.canPlaceOn(instance.getBlock(blockPosition).getName()); + Block placeBlock = instance.getBlock(blockPosition); + canPlaceBlock = usedItem.getMeta().getCanPlaceOn().contains(placeBlock); } } diff --git a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java index 1d39f8513..8ed5da8e3 100644 --- a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java @@ -47,12 +47,12 @@ public class PlayerDiggingListener { } else if (player.getGameMode() == GameMode.ADVENTURE) { //Check if the item can break the block with the current item ItemStack itemInMainHand = player.getItemInMainHand(); - // FIXME: canDestroy - /*if (!itemInMainHand.canDestroy(instance.getBlock(blockPosition).getName())) { + Block destroyedBlock = instance.getBlock(blockPosition); + if (!itemInMainHand.getMeta().getCanDestroy().contains(destroyedBlock)) { sendAcknowledgePacket(player, blockPosition, blockStateId, ClientPlayerDiggingPacket.Status.STARTED_DIGGING, false); return; - }*/ + } } final boolean instantBreak = player.isCreative() || diff --git a/src/main/java/net/minestom/server/utils/NBTUtils.java b/src/main/java/net/minestom/server/utils/NBTUtils.java index 87b25e519..4fe49d468 100644 --- a/src/main/java/net/minestom/server/utils/NBTUtils.java +++ b/src/main/java/net/minestom/server/utils/NBTUtils.java @@ -7,6 +7,7 @@ import net.kyori.adventure.util.Codec; import net.minestom.server.MinecraftServer; import net.minestom.server.attribute.Attribute; import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.instance.block.Block; import net.minestom.server.inventory.Inventory; import net.minestom.server.item.Enchantment; import net.minestom.server.item.ItemMetaBuilder; @@ -25,10 +26,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; // for lack of a better name public final class NBTUtils { @@ -236,34 +234,30 @@ public final class NBTUtils { // Meta specific fields metaBuilder.read(nbt); - // Ownership + // CanPlaceOn { - // FIXME: custom data - /*if (nbt.containsKey(ItemStack.OWNERSHIP_DATA_KEY)) { - final String identifierString = nbt.getString(ItemStack.OWNERSHIP_DATA_KEY); - final UUID identifier = UUID.fromString(identifierString); - final Data data = ItemStack.DATA_OWNERSHIP.getOwnObject(identifier); - if (data != null) { - item.setData(data); - } - }*/ - } - - //CanPlaceOn - // FIXME: PlaceOn/CanDestroy - /*{ if (nbt.containsKey("CanPlaceOn")) { NBTList canPlaceOn = nbt.getList("CanPlaceOn"); - canPlaceOn.forEach(x -> item.getCanPlaceOn().add(x.getValue())); + Set blocks = new HashSet<>(); + for (NBTString blockNamespace : canPlaceOn) { + Block block = Registries.getBlock(blockNamespace.getValue()); + blocks.add(block); + } + metaBuilder.canPlaceOn(blocks); } } - //CanDestroy + // CanDestroy { if (nbt.containsKey("CanDestroy")) { - NBTList canPlaceOn = nbt.getList("CanDestroy"); - canPlaceOn.forEach(x -> item.getCanDestroy().add(x.getValue())); + NBTList canDestroy = nbt.getList("CanDestroy"); + Set blocks = new HashSet<>(); + for (NBTString blockNamespace : canDestroy) { + Block block = Registries.getBlock(blockNamespace.getValue()); + blocks.add(block); + } + metaBuilder.canDestroy(blocks); } - }*/ + } } public static void loadEnchantments(NBTList enchantments, EnchantmentSetter setter) { diff --git a/src/test/java/demo/PlayerInit.java b/src/test/java/demo/PlayerInit.java index ec77a6fee..72ae68559 100644 --- a/src/test/java/demo/PlayerInit.java +++ b/src/test/java/demo/PlayerInit.java @@ -39,6 +39,7 @@ import net.minestom.server.world.DimensionType; import java.util.Collection; import java.util.Collections; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -229,12 +230,17 @@ public class PlayerInit { PlayerInventory inventory = player.getInventory(); ItemStack itemStack = ItemStack.builder(Material.STONE) .amount(64) + .meta(itemMetaBuilder -> + itemMetaBuilder.canPlaceOn(Set.of(Block.STONE)) + .canDestroy(Set.of(Block.DIAMOND_ORE))) .store(store -> { store.set("key", 5, Integer::sum); }) .build(); - itemStack = itemStack.withStore(storeBuilder -> storeBuilder.set("key2", 25, Integer::sum)); + System.out.println(itemStack.getMeta().toSNBT()); + + //itemStack = itemStack.withStore(storeBuilder -> storeBuilder.set("key2", 25, Integer::sum)); inventory.addItemStack(itemStack);