Support for canPlace & canDestroy meta

This commit is contained in:
TheMode 2021-04-11 00:42:09 +02:00
parent be2d1db9e0
commit e0c2c4b655
6 changed files with 78 additions and 38 deletions

View File

@ -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<Block> canDestroy;
private final Set<Block> 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<Enchantment, Short> getEnchantmentMap() {
return enchantmentMap;
return Collections.unmodifiableMap(enchantmentMap);
}
@Contract(pure = true)
public @NotNull List<ItemAttribute> 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> T getOrDefault(@NotNull ItemTag<T> tag, @Nullable T defaultValue) {
var key = tag.getKey();
if (nbt.containsKey(key)) {

View File

@ -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<Enchantment, Short> enchantmentMap = new HashMap<>();
protected List<ItemAttribute> attributes = new ArrayList<>();
protected int customModelData;
protected Set<Block> canDestroy = new HashSet<>();
protected Set<Block> 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<NBTString> 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<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
canDestroy.forEach(block -> list.add(new NBTString(block.getName())));
nbt.set("CanDestroy", list);
return list;
});
return this;
}
public <T> @NotNull ItemMetaBuilder set(@NotNull ItemTag<T> tag, @Nullable T value) {
if (value != null) {
tag.write(nbt, value);

View File

@ -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);
}
}

View File

@ -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() ||

View File

@ -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<NBTString> canPlaceOn = nbt.getList("CanPlaceOn");
canPlaceOn.forEach(x -> item.getCanPlaceOn().add(x.getValue()));
Set<Block> 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<NBTString> canPlaceOn = nbt.getList("CanDestroy");
canPlaceOn.forEach(x -> item.getCanDestroy().add(x.getValue()));
NBTList<NBTString> canDestroy = nbt.getList("CanDestroy");
Set<Block> blocks = new HashSet<>();
for (NBTString blockNamespace : canDestroy) {
Block block = Registries.getBlock(blockNamespace.getValue());
blocks.add(block);
}
metaBuilder.canDestroy(blocks);
}
}*/
}
}
public static void loadEnchantments(NBTList<NBTCompound> enchantments, EnchantmentSetter setter) {

View File

@ -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);