diff --git a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java index dff87f16d..0f496c68b 100644 --- a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java @@ -1,10 +1,15 @@ package net.minestom.server.item.metadata; import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.registry.Registries; +import net.minestom.server.utils.NBTUtils; import net.minestom.server.utils.item.ItemStackUtils; +import net.minestom.server.utils.validate.Check; import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTList; +import org.jglrxavpok.hephaistos.nbt.NBTTypes; -// TODO complete https://minecraft.gamepedia.com/Player.dat_format#Crossbows public class CrossbowMeta implements ItemMeta { private boolean triple; @@ -12,18 +17,71 @@ public class CrossbowMeta implements ItemMeta { private boolean charged; + /** + * Set the projectile of this crossbow + * + * @param projectile the projectile of the crossbow + */ public void setProjectile(ItemStack projectile) { - this.projectile1 = projectile1; + Check.argCondition(!ItemStackUtils.isVisible(projectile), "the projectile of your crossbow isn't visible (null or air)"); + this.projectile1 = projectile; this.triple = false; } + /** + * Set the triple projectiles of this crossbow + * + * @param projectile1 the projectile 1 + * @param projectile2 the projectile 2 + * @param projectile3 the projectile 3 + */ public void setProjectiles(ItemStack projectile1, ItemStack projectile2, ItemStack projectile3) { + Check.argCondition(!ItemStackUtils.isVisible(projectile1), "the projectile1 of your crossbow isn't visible (null or air)"); + Check.argCondition(!ItemStackUtils.isVisible(projectile2), "the projectile2 of your crossbow isn't visible (null or air)"); + Check.argCondition(!ItemStackUtils.isVisible(projectile3), "the projectile3 of your crossbow isn't visible (null or air)"); + this.projectile1 = projectile1; this.projectile2 = projectile2; this.projectile3 = projectile3; this.triple = true; } + /** + * Get if this crossbow is charged with 3 projectiles + * + * @return true if this crossbow is charged with 3 projectiles, false otherwise + */ + public boolean isTriple() { + return triple; + } + + /** + * Get the first projectile + * + * @return the first projectile, null if not present + */ + public ItemStack getProjectile1() { + return projectile1; + } + + /** + * Get the second projectile + * + * @return the second projectile, null if not present + */ + public ItemStack getProjectile2() { + return projectile2; + } + + /** + * Get the third projectile + * + * @return the third projectile, null if not present + */ + public ItemStack getProjectile3() { + return projectile3; + } + @Override public boolean hasNbt() { return ItemStackUtils.isVisible(projectile1); @@ -50,12 +108,56 @@ public class CrossbowMeta implements ItemMeta { @Override public void read(NBTCompound compound) { - // TODO + if (compound.containsKey("ChargedProjectiles")) { + final NBTList projectilesList = compound.getList("ChargedProjectiles"); + int index = 0; + for (NBTCompound projectileCompound : projectilesList) { + final byte count = projectileCompound.getByte("Count"); + final String id = projectileCompound.getString("id"); + final Material material = Registries.getMaterial(id); + + final NBTCompound tagsCompound = projectileCompound.getCompound("tag"); + + ItemStack itemStack = new ItemStack(material, count); + NBTUtils.loadDataIntoItem(itemStack, tagsCompound); + + index++; + + if (index == 1) { + projectile1 = itemStack; + } else if (index == 2) { + projectile2 = itemStack; + } else if (index == 3) { + projectile3 = itemStack; + } + + } + } + + if (compound.containsKey("Charged")) { + this.charged = compound.getByte("Charged") == 1; + } } @Override public void write(NBTCompound compound) { - // TODO + if (projectile1 != null || projectile2 != null || projectile3 != null) { + NBTList chargedProjectiles = new NBTList<>(NBTTypes.TAG_Compound); + if (projectile1 != null) { + chargedProjectiles.add(getItemCompound(projectile1)); + } + if (projectile2 != null) { + chargedProjectiles.add(getItemCompound(projectile2)); + } + if (projectile3 != null) { + chargedProjectiles.add(getItemCompound(projectile3)); + } + compound.set("ChargedProjectiles", chargedProjectiles); + } + + if (charged) { + compound.setByte("Charged", (byte) (charged ? 1 : 0)); + } } @Override @@ -70,4 +172,14 @@ public class CrossbowMeta implements ItemMeta { return crossbowMeta; } + + private NBTCompound getItemCompound(ItemStack itemStack) { + NBTCompound compound = new NBTCompound(); + + compound.setByte("Count", itemStack.getAmount()); + compound.setString("id", itemStack.getMaterial().getName()); + NBTUtils.saveDataIntoNBT(itemStack, compound); + + return compound; + } } diff --git a/src/main/java/net/minestom/server/utils/item/ItemStackUtils.java b/src/main/java/net/minestom/server/utils/item/ItemStackUtils.java index 07928c31f..896e94ccd 100644 --- a/src/main/java/net/minestom/server/utils/item/ItemStackUtils.java +++ b/src/main/java/net/minestom/server/utils/item/ItemStackUtils.java @@ -22,7 +22,7 @@ public class ItemStackUtils { * @return true if the item is visible, false otherwise */ public static boolean isVisible(ItemStack itemStack) { - return itemStack == null || itemStack.isAir(); + return itemStack != null && !itemStack.isAir(); } }