mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-27 06:03:01 +02:00
Added ItemMeta + MapDataPacket
This commit is contained in:
parent
f75c3870a3
commit
f8453b4906
@ -26,7 +26,9 @@ import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.InventoryType;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.item.metadata.MapMeta;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.packet.server.play.MapDataPacket;
|
||||
import net.minestom.server.ping.ResponseDataConsumer;
|
||||
import net.minestom.server.timer.TaskRunnable;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
@ -36,6 +38,7 @@ import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -53,7 +56,6 @@ public class PlayerInit {
|
||||
instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD);
|
||||
instanceContainer.enableAutoChunkLoad(true);
|
||||
instanceContainer.setChunkGenerator(noiseTestGenerator);
|
||||
instanceContainer.setTimeRate(150);
|
||||
|
||||
netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.NETHER);
|
||||
netherTest.enableAutoChunkLoad(true);
|
||||
@ -238,16 +240,45 @@ public class PlayerInit {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
player.teleport(new Position(0, 41f, 0));
|
||||
|
||||
player.setHeldItemSlot((byte) 5);
|
||||
//player.setHeldItemSlot((byte) 5);
|
||||
|
||||
player.setGlowing(true);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
/*for (int i = 0; i < 9; i++) {
|
||||
player.getInventory().setItemStack(i, new ItemStack(Material.STONE, (byte) 127));
|
||||
}*/
|
||||
|
||||
ItemStack map = new ItemStack(Material.FILLED_MAP, (byte) 1);
|
||||
MapMeta mapMeta = (MapMeta) map.getItemMeta();
|
||||
mapMeta.setMapId(1);
|
||||
player.getInventory().setItemStack(0, map);
|
||||
|
||||
{
|
||||
// Map test
|
||||
MapDataPacket mapDataPacket = new MapDataPacket();
|
||||
mapDataPacket.mapId = 1;
|
||||
mapDataPacket.scale = 1;
|
||||
mapDataPacket.trackingPosition = false;
|
||||
mapDataPacket.locked = false;
|
||||
mapDataPacket.icons = null;
|
||||
mapDataPacket.columns = (byte) 127;
|
||||
mapDataPacket.rows = (byte) 127;
|
||||
mapDataPacket.x = 0;
|
||||
mapDataPacket.z = 0;
|
||||
|
||||
final byte[] data = new byte[127 * 127];
|
||||
Arrays.fill(data, (byte) 10);
|
||||
|
||||
mapDataPacket.data = data;
|
||||
|
||||
player.getPlayerConnection().sendPacket(mapDataPacket);
|
||||
|
||||
}
|
||||
|
||||
|
||||
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
||||
item.setDisplayName(ColoredText.of("Item name"));
|
||||
item.setDamage(5);
|
||||
//item.getLore().add(ColoredText.of(ChatColor.RED + "a lore line " + ChatColor.BLACK + " BLACK"));
|
||||
//item.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
//item.setEnchantment(Enchantment.SHARPNESS, (short) 50);
|
||||
|
@ -1837,16 +1837,16 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* null if there is no item to update the state
|
||||
*/
|
||||
public ItemUpdateStateEvent callItemUpdateStateEvent(boolean allowFood) {
|
||||
Material mainHandMat = Material.fromId(getItemInMainHand().getMaterialId());
|
||||
Material offHandMat = Material.fromId(getItemInOffHand().getMaterialId());
|
||||
boolean isOffhand = offHandMat.hasState();
|
||||
final Material mainHandMat = getItemInMainHand().getMaterial();
|
||||
final Material offHandMat = getItemInOffHand().getMaterial();
|
||||
final boolean isOffhand = offHandMat.hasState();
|
||||
|
||||
ItemStack updatedItem = isOffhand ? getItemInOffHand() :
|
||||
final ItemStack updatedItem = isOffhand ? getItemInOffHand() :
|
||||
mainHandMat.hasState() ? getItemInMainHand() : null;
|
||||
if (updatedItem == null) // No item with state, cancel
|
||||
return null;
|
||||
|
||||
boolean isFood = updatedItem.getMaterial().isFood();
|
||||
final boolean isFood = updatedItem.getMaterial().isFood();
|
||||
|
||||
if (isFood && !allowFood)
|
||||
return null;
|
||||
@ -1921,8 +1921,8 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* based on which one is the lowest
|
||||
*/
|
||||
public int getChunkRange() {
|
||||
int serverRange = MinecraftServer.CHUNK_VIEW_DISTANCE;
|
||||
int playerRange = getSettings().viewDistance;
|
||||
final int serverRange = MinecraftServer.CHUNK_VIEW_DISTANCE;
|
||||
final int playerRange = getSettings().viewDistance;
|
||||
if (playerRange == 0) {
|
||||
return serverRange; // Didn't receive settings packet yet (is the case on login)
|
||||
} else {
|
||||
|
@ -5,8 +5,10 @@ import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.DataContainer;
|
||||
import net.minestom.server.item.attribute.ItemAttribute;
|
||||
import net.minestom.server.item.metadata.ItemMeta;
|
||||
import net.minestom.server.item.metadata.MapMeta;
|
||||
import net.minestom.server.item.metadata.PotionMeta;
|
||||
import net.minestom.server.item.rule.VanillaStackingRule;
|
||||
import net.minestom.server.potion.PotionType;
|
||||
import net.minestom.server.registry.Registries;
|
||||
import net.minestom.server.utils.NBTUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
@ -18,17 +20,27 @@ public class ItemStack implements DataContainer {
|
||||
|
||||
private static final StackingRule DEFAULT_STACKING_RULE = new VanillaStackingRule(127);
|
||||
|
||||
public static ItemStack getAirItem() {
|
||||
return new ItemStack((short) 0, (byte) 0);
|
||||
}
|
||||
private Material material;
|
||||
|
||||
private static StackingRule defaultStackingRule;
|
||||
|
||||
private short materialId;
|
||||
private ItemMeta itemMeta;
|
||||
|
||||
private byte amount;
|
||||
private int damage;
|
||||
|
||||
public ItemStack(Material material, byte amount, int damage) {
|
||||
this.material = material;
|
||||
this.amount = amount;
|
||||
this.damage = damage;
|
||||
this.lore = new ArrayList<>();
|
||||
|
||||
this.enchantmentMap = new HashMap<>();
|
||||
this.storedEnchantmentMap = new HashMap<>();
|
||||
this.attributes = new ArrayList<>();
|
||||
|
||||
this.itemMeta = findMeta();
|
||||
}
|
||||
|
||||
private ColoredText displayName;
|
||||
private boolean unbreakable;
|
||||
private ArrayList<ColoredText> lore;
|
||||
@ -36,7 +48,6 @@ public class ItemStack implements DataContainer {
|
||||
private Map<Enchantment, Short> enchantmentMap;
|
||||
private Map<Enchantment, Short> storedEnchantmentMap;
|
||||
private List<ItemAttribute> attributes;
|
||||
private Set<PotionType> potionTypes;
|
||||
|
||||
private int hideFlag;
|
||||
private int customModelData;
|
||||
@ -53,24 +64,12 @@ public class ItemStack implements DataContainer {
|
||||
this.stackingRule = defaultStackingRule;
|
||||
}
|
||||
|
||||
public ItemStack(short materialId, byte amount, int damage) {
|
||||
this.materialId = materialId;
|
||||
this.amount = amount;
|
||||
this.damage = damage;
|
||||
this.lore = new ArrayList<>();
|
||||
|
||||
this.enchantmentMap = new HashMap<>();
|
||||
this.storedEnchantmentMap = new HashMap<>();
|
||||
this.attributes = new ArrayList<>();
|
||||
this.potionTypes = new HashSet<>();
|
||||
}
|
||||
|
||||
public ItemStack(short materialId, byte amount) {
|
||||
this(materialId, amount, (short) 0);
|
||||
}
|
||||
|
||||
public ItemStack(Material material, byte amount) {
|
||||
this(material.getId(), amount);
|
||||
this(material, amount, (short) 0);
|
||||
}
|
||||
|
||||
public static ItemStack getAirItem() {
|
||||
return new ItemStack(Material.AIR, (byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,13 +92,28 @@ public class ItemStack implements DataContainer {
|
||||
ItemStack.defaultStackingRule = defaultStackingRule;
|
||||
}
|
||||
|
||||
public static ItemStack fromNBT(NBTCompound nbt) {
|
||||
if (!nbt.containsKey("id") || !nbt.containsKey("Count"))
|
||||
throw new IllegalArgumentException("Invalid item NBT, must at least contain 'id' and 'Count' tags");
|
||||
final Material material = Registries.getMaterial(nbt.getString("id"));
|
||||
final byte count = nbt.getByte("Count");
|
||||
|
||||
ItemStack s = new ItemStack(material, count);
|
||||
|
||||
NBTCompound tag = nbt.getCompound("tag");
|
||||
if (tag != null) {
|
||||
NBTUtils.loadDataIntoItem(s, tag);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the item is air
|
||||
*
|
||||
* @return true if the material is air, false otherwise
|
||||
*/
|
||||
public boolean isAir() {
|
||||
return materialId == Material.AIR.getId();
|
||||
return material == Material.AIR;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,15 +133,18 @@ public class ItemStack implements DataContainer {
|
||||
final boolean dataCheck = (data == null && itemData == null) ||
|
||||
(data != null && itemData != null && data.equals(itemData));
|
||||
|
||||
return itemStack.getMaterialId() == materialId &&
|
||||
final boolean sameMeta = (itemStack.itemMeta == null && itemMeta == null) ||
|
||||
(itemStack.itemMeta != null && itemMeta != null && (itemStack.itemMeta.isSimilar(itemMeta)));
|
||||
|
||||
return itemStack.getMaterial() == material &&
|
||||
displayNameCheck &&
|
||||
itemStack.isUnbreakable() == unbreakable &&
|
||||
itemStack.getDamage() == damage &&
|
||||
itemStack.enchantmentMap.equals(enchantmentMap) &&
|
||||
itemStack.storedEnchantmentMap.equals(storedEnchantmentMap) &&
|
||||
itemStack.attributes.equals(attributes) &&
|
||||
itemStack.potionTypes.equals(potionTypes) &&
|
||||
itemStack.hideFlag == hideFlag &&
|
||||
sameMeta &&
|
||||
dataCheck;
|
||||
}
|
||||
}
|
||||
@ -165,21 +182,14 @@ public class ItemStack implements DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item internal material id
|
||||
* Get the special meta object for this item
|
||||
* <p>
|
||||
* Can be null if not any
|
||||
*
|
||||
* @return the item material id
|
||||
* @return the item meta
|
||||
*/
|
||||
public short getMaterialId() {
|
||||
return materialId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item material
|
||||
*
|
||||
* @return the item material
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
return Material.fromId(getMaterialId());
|
||||
public ItemMeta getItemMeta() {
|
||||
return itemMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,33 +360,6 @@ public class ItemStack implements DataContainer {
|
||||
this.attributes.remove(itemAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item potion types
|
||||
*
|
||||
* @return an unmodifiable {@link Set} containing the item potion types
|
||||
*/
|
||||
public Set<PotionType> getPotionTypes() {
|
||||
return Collections.unmodifiableSet(potionTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a potion type to the item
|
||||
*
|
||||
* @param potionType the potion type to add
|
||||
*/
|
||||
public void addPotionType(PotionType potionType) {
|
||||
this.potionTypes.add(potionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a potion type to the item
|
||||
*
|
||||
* @param potionType the potion type to remove
|
||||
*/
|
||||
public void removePotionType(PotionType potionType) {
|
||||
this.potionTypes.remove(potionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item hide flag
|
||||
*
|
||||
@ -481,16 +464,25 @@ public class ItemStack implements DataContainer {
|
||||
this.unbreakable = unbreakable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item material
|
||||
*
|
||||
* @return the item material
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the item has any nbt tag
|
||||
*
|
||||
* @return true if the item has nbt tag, false otherwise
|
||||
*/
|
||||
public boolean hasNbtTag() {
|
||||
return hasDisplayName() || hasLore() || isUnbreakable() ||
|
||||
return hasDisplayName() || hasLore() || damage != 0 || isUnbreakable() ||
|
||||
!enchantmentMap.isEmpty() || !storedEnchantmentMap.isEmpty() ||
|
||||
!attributes.isEmpty() || !potionTypes.isEmpty() ||
|
||||
hideFlag != 0 || customModelData != 0;
|
||||
!attributes.isEmpty() ||
|
||||
hideFlag != 0 || customModelData != 0 || (itemMeta != null && itemMeta.hasNbt());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -499,7 +491,7 @@ public class ItemStack implements DataContainer {
|
||||
* @return a cloned item stack
|
||||
*/
|
||||
public synchronized ItemStack clone() {
|
||||
ItemStack itemStack = new ItemStack(materialId, amount, damage);
|
||||
ItemStack itemStack = new ItemStack(material, amount, damage);
|
||||
itemStack.setDisplayName(displayName);
|
||||
itemStack.setUnbreakable(unbreakable);
|
||||
itemStack.setLore(new ArrayList<>(getLore()));
|
||||
@ -508,40 +500,19 @@ public class ItemStack implements DataContainer {
|
||||
itemStack.enchantmentMap = new HashMap<>(enchantmentMap);
|
||||
itemStack.storedEnchantmentMap = new HashMap<>(storedEnchantmentMap);
|
||||
itemStack.attributes = new ArrayList<>(attributes);
|
||||
itemStack.potionTypes = new HashSet<>(potionTypes);
|
||||
|
||||
itemStack.hideFlag = hideFlag;
|
||||
itemStack.customModelData = customModelData;
|
||||
|
||||
Data data = getData();
|
||||
if (itemMeta != null)
|
||||
itemStack.itemMeta = itemMeta.clone();
|
||||
|
||||
final Data data = getData();
|
||||
if (data != null)
|
||||
itemStack.setData(data.clone());
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the item into a readable Json object
|
||||
* <p>
|
||||
* Mainly used to show an item in a message hover
|
||||
*
|
||||
* @return a {@link JsonObject} containing the item data
|
||||
*/
|
||||
public synchronized JsonObject toJsonObject() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("id", getMaterialId());
|
||||
object.addProperty("Damage", getDamage());
|
||||
object.addProperty("Count", getAmount());
|
||||
|
||||
if (hasDisplayName() || hasLore()) {
|
||||
JsonObject tagObject = new JsonObject();
|
||||
if (hasDisplayName()) {
|
||||
tagObject.addProperty("display", getDisplayName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Data getData() {
|
||||
return data;
|
||||
@ -594,30 +565,53 @@ public class ItemStack implements DataContainer {
|
||||
return (byte) (1 << hideFlag.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the item into a readable Json object
|
||||
* <p>
|
||||
* Mainly used to show an item in a message hover
|
||||
*
|
||||
* @return a {@link JsonObject} containing the item data
|
||||
*/
|
||||
public synchronized JsonObject toJsonObject() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("id", material.getId());
|
||||
object.addProperty("Damage", getDamage());
|
||||
object.addProperty("Count", getAmount());
|
||||
|
||||
if (hasDisplayName() || hasLore()) {
|
||||
JsonObject tagObject = new JsonObject();
|
||||
if (hasDisplayName()) {
|
||||
tagObject.addProperty("display", getDisplayName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the item meta based on the material type
|
||||
*
|
||||
* @return the item meta
|
||||
*/
|
||||
private ItemMeta findMeta() {
|
||||
if (material == Material.POTION)
|
||||
return new PotionMeta();
|
||||
|
||||
if (material == Material.FILLED_MAP)
|
||||
return new MapMeta();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public NBTCompound toNBT() {
|
||||
NBTCompound compound = new NBTCompound()
|
||||
.setByte("Count", amount)
|
||||
.setString("id", Material.fromId(materialId).getName());
|
||||
if(hasNbtTag()) {
|
||||
.setString("id", material.getName());
|
||||
if (hasNbtTag()) {
|
||||
NBTCompound additionalTag = new NBTCompound();
|
||||
NBTUtils.saveDataIntoNBT(this, additionalTag);
|
||||
compound.set("tag", additionalTag);
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static ItemStack fromNBT(NBTCompound nbt) {
|
||||
if(!nbt.containsKey("id") || !nbt.containsKey("Count"))
|
||||
throw new IllegalArgumentException("Invalid item NBT, must at least contain 'id' and 'Count' tags");
|
||||
short materialID = Registries.getMaterial(nbt.getString("id")).getId();
|
||||
byte count = nbt.getByte("Count");
|
||||
|
||||
ItemStack s = new ItemStack(materialID, count);
|
||||
|
||||
NBTCompound tag = nbt.getCompound("tag");
|
||||
if(tag != null) {
|
||||
NBTUtils.loadDataIntoItem(s, tag);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package net.minestom.server.item.metadata;
|
||||
|
||||
public abstract class ItemMeta {
|
||||
|
||||
public abstract boolean hasNbt();
|
||||
|
||||
public abstract boolean isSimilar(ItemMeta itemMeta);
|
||||
|
||||
public abstract ItemMeta clone();
|
||||
|
||||
}
|
31
src/main/java/net/minestom/server/item/metadata/MapMeta.java
Normal file
31
src/main/java/net/minestom/server/item/metadata/MapMeta.java
Normal file
@ -0,0 +1,31 @@
|
||||
package net.minestom.server.item.metadata;
|
||||
|
||||
public class MapMeta extends ItemMeta {
|
||||
|
||||
private int mapId;
|
||||
|
||||
public int getMapId() {
|
||||
return mapId;
|
||||
}
|
||||
|
||||
public void setMapId(int mapId) {
|
||||
this.mapId = mapId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbt() {
|
||||
return mapId != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimilar(ItemMeta itemMeta) {
|
||||
return itemMeta instanceof MapMeta && ((MapMeta) itemMeta).getMapId() == mapId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemMeta clone() {
|
||||
MapMeta mapMeta = new MapMeta();
|
||||
mapMeta.setMapId(mapId);
|
||||
return mapMeta;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package net.minestom.server.item.metadata;
|
||||
|
||||
import net.minestom.server.potion.PotionType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class PotionMeta extends ItemMeta {
|
||||
|
||||
private Set<PotionType> potionTypes = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Get the item potion types
|
||||
*
|
||||
* @return an unmodifiable {@link Set} containing the item potion types
|
||||
*/
|
||||
public Set<PotionType> getPotionTypes() {
|
||||
return Collections.unmodifiableSet(potionTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a potion type to the item
|
||||
*
|
||||
* @param potionType the potion type to add
|
||||
*/
|
||||
public void addPotionType(PotionType potionType) {
|
||||
this.potionTypes.add(potionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a potion type to the item
|
||||
*
|
||||
* @param potionType the potion type to remove
|
||||
*/
|
||||
public void removePotionType(PotionType potionType) {
|
||||
this.potionTypes.remove(potionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbt() {
|
||||
return !potionTypes.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimilar(ItemMeta itemMeta) {
|
||||
return itemMeta instanceof PotionMeta && ((PotionMeta) itemMeta).potionTypes.equals(potionTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemMeta clone() {
|
||||
PotionMeta potionMeta = new PotionMeta();
|
||||
potionMeta.potionTypes = new HashSet<>(potionTypes);
|
||||
|
||||
return potionMeta;
|
||||
}
|
||||
}
|
@ -28,23 +28,23 @@ import java.util.Set;
|
||||
public class BlockPlacementListener {
|
||||
|
||||
public static void listener(ClientPlayerBlockPlacementPacket packet, Player player) {
|
||||
PlayerInventory playerInventory = player.getInventory();
|
||||
Player.Hand hand = packet.hand;
|
||||
BlockFace blockFace = packet.blockFace;
|
||||
BlockPosition blockPosition = packet.blockPosition;
|
||||
final PlayerInventory playerInventory = player.getInventory();
|
||||
final Player.Hand hand = packet.hand;
|
||||
final BlockFace blockFace = packet.blockFace;
|
||||
final BlockPosition blockPosition = packet.blockPosition;
|
||||
|
||||
Instance instance = player.getInstance();
|
||||
final Instance instance = player.getInstance();
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
// Interact at block
|
||||
PlayerBlockInteractEvent playerBlockInteractEvent = new PlayerBlockInteractEvent(blockPosition, hand, blockFace);
|
||||
player.callCancellableEvent(PlayerBlockInteractEvent.class, playerBlockInteractEvent, () -> {
|
||||
CustomBlock customBlock = instance.getCustomBlock(blockPosition);
|
||||
final CustomBlock customBlock = instance.getCustomBlock(blockPosition);
|
||||
if (customBlock != null) {
|
||||
Data data = instance.getBlockData(blockPosition);
|
||||
boolean blocksItem = customBlock.onInteract(player, hand, blockPosition, data);
|
||||
if(blocksItem) {
|
||||
final Data data = instance.getBlockData(blockPosition);
|
||||
final boolean blocksItem = customBlock.onInteract(player, hand, blockPosition, data);
|
||||
if (blocksItem) {
|
||||
playerBlockInteractEvent.setBlockingItemUse(true);
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ public class BlockPlacementListener {
|
||||
|
||||
// Check if item at hand is a block
|
||||
final ItemStack usedItem = hand == Player.Hand.MAIN ? playerInventory.getItemInMainHand() : playerInventory.getItemInOffHand();
|
||||
final Material material = Material.fromId(usedItem.getMaterialId());
|
||||
final Material material = usedItem.getMaterial();
|
||||
if (material == Material.AIR) {
|
||||
return;
|
||||
}
|
||||
@ -104,7 +104,7 @@ public class BlockPlacementListener {
|
||||
player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
|
||||
if (!playerBlockPlaceEvent.isCancelled() && canPlace) {
|
||||
short customBlockId = playerBlockPlaceEvent.getCustomBlockId();
|
||||
if(customBlockId != 0) {
|
||||
if (customBlockId != 0) {
|
||||
instance.setSeparateBlocks(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockId(), playerBlockPlaceEvent.getCustomBlockId());
|
||||
} else {
|
||||
instance.setBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockId());
|
||||
|
@ -19,7 +19,7 @@ public class UseItemListener {
|
||||
PlayerUseItemEvent useItemEvent = new PlayerUseItemEvent(player, hand, itemStack);
|
||||
player.callEvent(PlayerUseItemEvent.class, useItemEvent);
|
||||
|
||||
final Material material = Material.fromId(itemStack.getMaterialId());
|
||||
final Material material = itemStack.getMaterial();
|
||||
|
||||
// Equip armor with right click
|
||||
if (material.isArmor()) {
|
||||
|
@ -0,0 +1,81 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
|
||||
public class MapDataPacket implements ServerPacket {
|
||||
|
||||
public int mapId;
|
||||
public byte scale;
|
||||
public boolean trackingPosition;
|
||||
public boolean locked;
|
||||
|
||||
public Icon[] icons;
|
||||
|
||||
public byte columns;
|
||||
public byte rows;
|
||||
public byte x;
|
||||
public byte z;
|
||||
public byte[] data;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
writer.writeVarInt(mapId);
|
||||
writer.writeByte(scale);
|
||||
writer.writeBoolean(trackingPosition);
|
||||
writer.writeBoolean(locked);
|
||||
|
||||
if (icons != null && icons.length > 0) {
|
||||
writer.writeVarInt(icons.length);
|
||||
for (Icon icon : icons) {
|
||||
icon.write(writer);
|
||||
}
|
||||
} else {
|
||||
writer.writeVarInt(0);
|
||||
}
|
||||
|
||||
writer.writeByte(columns);
|
||||
if (columns <= 0)
|
||||
return;
|
||||
|
||||
writer.writeByte(rows);
|
||||
writer.writeByte(x);
|
||||
writer.writeByte(z);
|
||||
if (data != null && data.length > 0) {
|
||||
writer.writeVarInt(data.length);
|
||||
writer.writeBytes(data);
|
||||
} else {
|
||||
writer.writeVarInt(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ServerPacketIdentifier.MAP_DATA;
|
||||
}
|
||||
|
||||
public static class Icon {
|
||||
public int type;
|
||||
public byte x, z;
|
||||
public byte direction;
|
||||
public ColoredText displayName;
|
||||
|
||||
private void write(PacketWriter writer) {
|
||||
writer.writeVarInt(type);
|
||||
writer.writeByte(x);
|
||||
writer.writeByte(z);
|
||||
writer.writeByte(direction);
|
||||
|
||||
final boolean hasDisplayName = displayName != null;
|
||||
writer.writeBoolean(hasDisplayName);
|
||||
if (hasDisplayName) {
|
||||
writer.writeSizedString(displayName.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -11,6 +11,9 @@ import net.minestom.server.item.Material;
|
||||
import net.minestom.server.item.NBTConsumer;
|
||||
import net.minestom.server.item.attribute.AttributeSlot;
|
||||
import net.minestom.server.item.attribute.ItemAttribute;
|
||||
import net.minestom.server.item.metadata.ItemMeta;
|
||||
import net.minestom.server.item.metadata.MapMeta;
|
||||
import net.minestom.server.item.metadata.PotionMeta;
|
||||
import net.minestom.server.network.packet.PacketReader;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.potion.PotionType;
|
||||
@ -80,24 +83,24 @@ public class NBTUtils {
|
||||
}
|
||||
|
||||
public static ItemStack readItemStack(PacketReader reader) {
|
||||
boolean present = reader.readBoolean();
|
||||
final boolean present = reader.readBoolean();
|
||||
|
||||
if (!present) {
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
int id = reader.readVarInt();
|
||||
final int id = reader.readVarInt();
|
||||
if (id == -1) {
|
||||
// Drop mode
|
||||
return ItemStack.getAirItem();
|
||||
}
|
||||
|
||||
byte count = reader.readByte();
|
||||
|
||||
ItemStack item = new ItemStack((short) id, count);
|
||||
final Material material = Material.fromId((short) id);
|
||||
final byte count = reader.readByte();
|
||||
ItemStack item = new ItemStack(material, count);
|
||||
|
||||
try {
|
||||
NBT itemNBT = reader.readTag();
|
||||
final NBT itemNBT = reader.readTag();
|
||||
if (itemNBT instanceof NBTCompound) { // can also be a TAG_End if no data
|
||||
NBTCompound nbt = (NBTCompound) itemNBT;
|
||||
loadDataIntoItem(item, nbt);
|
||||
@ -113,7 +116,6 @@ public class NBTUtils {
|
||||
if (nbt.containsKey("Damage")) item.setDamage(nbt.getInt("Damage"));
|
||||
if (nbt.containsKey("Unbreakable")) item.setUnbreakable(nbt.getInt("Unbreakable") == 1);
|
||||
if (nbt.containsKey("HideFlags")) item.setHideFlag(nbt.getInt("HideFlags"));
|
||||
if (nbt.containsKey("Potion")) item.addPotionType(Registries.getPotionType(nbt.getString("Potion")));
|
||||
if (nbt.containsKey("display")) {
|
||||
NBTCompound display = nbt.getCompound("display");
|
||||
if (display.containsKey("Name")) item.setDisplayName(ChatParser.toColoredText(display.getString("Name")));
|
||||
@ -165,6 +167,24 @@ public class NBTUtils {
|
||||
item.addAttribute(itemAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
// Meta specific field
|
||||
final ItemMeta itemMeta = item.getItemMeta();
|
||||
if (itemMeta == null)
|
||||
return;
|
||||
final Class metaType = itemMeta.getClass();
|
||||
if (metaType == PotionMeta.class) {
|
||||
final PotionMeta potionMeta = (PotionMeta) itemMeta;
|
||||
if (nbt.containsKey("Potion")) {
|
||||
potionMeta.addPotionType(Registries.getPotionType(nbt.getString("Potion")));
|
||||
}
|
||||
} else if (metaType == MapMeta.class) {
|
||||
final MapMeta mapMeta = (MapMeta) itemMeta;
|
||||
if (nbt.containsKey("map")) {
|
||||
mapMeta.setMapId(nbt.getInt("map"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void loadEnchantments(NBTList<NBTCompound> enchantments, EnchantmentSetter setter) {
|
||||
@ -185,7 +205,7 @@ public class NBTUtils {
|
||||
packet.writeBoolean(false);
|
||||
} else {
|
||||
packet.writeBoolean(true);
|
||||
packet.writeVarInt(itemStack.getMaterialId());
|
||||
packet.writeVarInt(itemStack.getMaterial().getId());
|
||||
packet.writeByte(itemStack.getAmount());
|
||||
|
||||
if (!itemStack.hasNbtTag()) {
|
||||
@ -217,13 +237,16 @@ public class NBTUtils {
|
||||
|
||||
// Start damage
|
||||
{
|
||||
itemNBT.setInt("Damage", itemStack.getDamage());
|
||||
final int damage = itemStack.getDamage();
|
||||
if (damage > 0) {
|
||||
itemNBT.setInt("Damage", damage);
|
||||
}
|
||||
}
|
||||
// End damage
|
||||
|
||||
// Display
|
||||
boolean hasDisplayName = itemStack.hasDisplayName();
|
||||
boolean hasLore = itemStack.hasLore();
|
||||
final boolean hasDisplayName = itemStack.hasDisplayName();
|
||||
final boolean hasLore = itemStack.hasLore();
|
||||
|
||||
if (hasDisplayName || hasLore) {
|
||||
NBTCompound displayNBT = new NBTCompound();
|
||||
@ -248,12 +271,12 @@ public class NBTUtils {
|
||||
|
||||
// Start enchantment
|
||||
{
|
||||
Map<Enchantment, Short> enchantmentMap = itemStack.getEnchantmentMap();
|
||||
final Map<Enchantment, Short> enchantmentMap = itemStack.getEnchantmentMap();
|
||||
if (!enchantmentMap.isEmpty()) {
|
||||
writeEnchant(itemNBT, "Enchantments", enchantmentMap);
|
||||
}
|
||||
|
||||
Map<Enchantment, Short> storedEnchantmentMap = itemStack.getStoredEnchantmentMap();
|
||||
final Map<Enchantment, Short> storedEnchantmentMap = itemStack.getStoredEnchantmentMap();
|
||||
if (!storedEnchantmentMap.isEmpty()) {
|
||||
writeEnchant(itemNBT, "StoredEnchantments", storedEnchantmentMap);
|
||||
}
|
||||
@ -262,12 +285,12 @@ public class NBTUtils {
|
||||
|
||||
// Start attribute
|
||||
{
|
||||
List<ItemAttribute> itemAttributes = itemStack.getAttributes();
|
||||
final List<ItemAttribute> itemAttributes = itemStack.getAttributes();
|
||||
if (!itemAttributes.isEmpty()) {
|
||||
NBTList<NBTCompound> attributesNBT = new NBTList<>(NBTTypes.TAG_Compound);
|
||||
|
||||
for (ItemAttribute itemAttribute : itemAttributes) {
|
||||
UUID uuid = itemAttribute.getUuid();
|
||||
final UUID uuid = itemAttribute.getUuid();
|
||||
|
||||
attributesNBT.add(
|
||||
new NBTCompound()
|
||||
@ -285,20 +308,9 @@ public class NBTUtils {
|
||||
}
|
||||
// End attribute
|
||||
|
||||
// Start potion
|
||||
{
|
||||
Set<PotionType> potionTypes = itemStack.getPotionTypes();
|
||||
if (!potionTypes.isEmpty()) {
|
||||
for (PotionType potionType : potionTypes) {
|
||||
itemNBT.setString("Potion", potionType.getNamespaceID());
|
||||
}
|
||||
}
|
||||
}
|
||||
// End potion
|
||||
|
||||
// Start hide flags
|
||||
{
|
||||
int hideFlag = itemStack.getHideFlag();
|
||||
final int hideFlag = itemStack.getHideFlag();
|
||||
if (hideFlag != 0) {
|
||||
itemNBT.setInt("HideFlags", hideFlag);
|
||||
}
|
||||
@ -307,11 +319,31 @@ public class NBTUtils {
|
||||
|
||||
// Start custom model data
|
||||
{
|
||||
int customModelData = itemStack.getCustomModelData();
|
||||
final int customModelData = itemStack.getCustomModelData();
|
||||
if (customModelData != 0) {
|
||||
itemNBT.setInt("CustomModelData", customModelData);
|
||||
}
|
||||
}
|
||||
|
||||
// Start custom meta
|
||||
final ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
if (itemMeta != null) {
|
||||
final Class metaType = itemMeta.getClass();
|
||||
if (metaType == PotionMeta.class) {
|
||||
final Set<PotionType> potionTypes = ((PotionMeta) itemMeta).getPotionTypes();
|
||||
if (!potionTypes.isEmpty()) {
|
||||
for (PotionType potionType : potionTypes) {
|
||||
itemNBT.setString("Potion", potionType.getNamespaceID());
|
||||
}
|
||||
}
|
||||
} else if (metaType == MapMeta.class) {
|
||||
final int mapId = ((MapMeta) itemMeta).getMapId();
|
||||
if (mapId != 0) {
|
||||
itemNBT.setInt("map", mapId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
Loading…
Reference in New Issue
Block a user