From 7abe692adf3f1d1c8aa8419495a147bc30c4d898 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Mon, 7 Sep 2026 20:51:29 +0200 Subject: [PATCH] feat: add stackFromNbt and stackListToNbt to ItemStack --- core/src/ItemStack.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/core/src/ItemStack.cpp b/core/src/ItemStack.cpp index 7aed888..cdc65ad 100644 --- a/core/src/ItemStack.cpp +++ b/core/src/ItemStack.cpp @@ -318,3 +318,79 @@ NbtTag stackToNbt(const MetaStack& stack) { return tag; } + tag.put("Id", NbtTag::makeShort(static_cast(stack.item))); + tag.put("Count", NbtTag::makeShort(static_cast(stack.count))); + tag.put("DamageUsed", NbtTag::makeInt(stack.meta.durability.used)); + tag.put("DamageMax", NbtTag::makeInt(stack.meta.durability.max)); + tag.put("Unbreakable", NbtTag::makeByte(stack.meta.unbreakable ? 1 : 0)); + tag.put("RepairCost", NbtTag::makeInt(stack.meta.repairCost)); + if (!stack.meta.customName.empty()) { + tag.put("Name", NbtTag::makeString(stack.meta.customName)); + } + if (!stack.meta.enchants.empty()) { + NbtTag list = NbtTag::makeList(NbtType::Compound); + for (const Enchantment& entry : stack.meta.enchants.entries) { + NbtTag row = NbtTag::makeCompound(); + row.put("Kind", NbtTag::makeShort(enchantCode(entry.kind))); + row.put("Level", NbtTag::makeShort(static_cast(entry.level))); + list.listAppend(row); + } + tag.put("Enchants", list); + } + return tag; +} + +bool stackFromNbt(const NbtTag& tag, MetaStack& out) { + out = MetaStack{}; + if (tag.kind() != NbtType::Compound) return false; + + int32_t rawItem = intField(tag, "Id", NbtType::Short, 0); + if (rawItem == 0) return true; + if (!validItemId(rawItem)) return false; + + int32_t count = intField(tag, "Count", NbtType::Short, 0); + if (count <= 0) return true; + + out.item = static_cast(rawItem); + out.meta.durability.used = intField(tag, "DamageUsed", NbtType::Int, 0); + out.meta.durability.max = intField(tag, "DamageMax", NbtType::Int, 0); + out.meta.unbreakable = intField(tag, "Unbreakable", NbtType::Byte, 0) != 0; + out.meta.repairCost = intField(tag, "RepairCost", NbtType::Int, 0); + + const NbtTag* name = findTyped(tag, "Name", NbtType::String); + if (name != nullptr) out.meta.customName = name->asString(); + + const NbtTag* enchants = findTyped(tag, "Enchants", NbtType::List); + if (enchants != nullptr && enchants->listElementType() == NbtType::Compound) { + for (const NbtTag& row : enchants->asList()) { + int32_t kind = intField(row, "Kind", NbtType::Short, -1); + int32_t level = intField(row, "Level", NbtType::Short, 0); + if (!validEnchantKind(kind) || level <= 0) continue; + out.meta.enchants.entries.push_back({static_cast(kind), level}); + } + } + + out.count = std::min(count, out.maxCount()); + if (out.count <= 0) out.clear(); + return true; +} + +NbtTag stackListToNbt(const std::vector& stacks) { + NbtTag list = NbtTag::makeList(NbtType::Compound); + for (const MetaStack& stack : stacks) list.listAppend(stackToNbt(stack)); + return list; +} + +bool stackListFromNbt(const NbtTag& tag, std::vector& out) { + out.clear(); + if (tag.kind() != NbtType::List || tag.listElementType() != NbtType::Compound) return false; + out.reserve(tag.asList().size()); + for (const NbtTag& row : tag.asList()) { + MetaStack stack; + if (!stackFromNbt(row, stack)) return false; + out.push_back(stack); + } + return true; +} + +} // namespace vf