diff --git a/core/src/ContainerMenu.cpp b/core/src/ContainerMenu.cpp index 620df81..3601d9c 100644 --- a/core/src/ContainerMenu.cpp +++ b/core/src/ContainerMenu.cpp @@ -468,3 +468,76 @@ void ContainerMenu::bindContainer(Container& container) { syncFromContainer(); } +void ContainerMenu::syncFromContainer() { + if (bound == nullptr) return; + for (MenuSlot& menuSlot : slots) { + if (menuSlot.backingIndex < 0) continue; + menuSlot.cell.stack = fromItemSlot(bound->slot(menuSlot.backingIndex)); + } + refreshResult(); +} + +void ContainerMenu::syncToContainer() { + if (bound == nullptr) return; + for (const MenuSlot& menuSlot : slots) { + if (menuSlot.backingIndex < 0) continue; + bound->setSlot(menuSlot.backingIndex, toItemSlot(menuSlot.cell.stack)); + } +} + +void ContainerMenu::unbind() { + syncToContainer(); + for (MenuSlot& menuSlot : slots) menuSlot.backingIndex = -1; + bound = nullptr; +} + +CraftingView ContainerMenu::crafting() { return CraftingView(*this); } + +const MetaStack& ContainerMenu::resultStack() const { + if (menuLayout.resultSlot < 0) return emptyStack(); + return stackAt(menuLayout.resultSlot); +} + +void ContainerMenu::refreshResult() { + if (menuLayout.resultSlot < 0) return; + CraftingView view(*this); + view.refresh(); +} + +NbtTag ContainerMenu::toNbt() const { + NbtTag tag = NbtTag::makeCompound(); + tag.put("Kind", NbtTag::makeShort(static_cast(menuKind))); + tag.put("Creative", NbtTag::makeByte(creative ? 1 : 0)); + NbtTag list = NbtTag::makeList(NbtType::Compound); + for (const MenuSlot& menuSlot : slots) list.listAppend(stackToNbt(menuSlot.cell.stack)); + tag.put("Slots", list); + return tag; +} + +bool ContainerMenu::fromNbt(const NbtTag& tag) { + if (tag.kind() != NbtType::Compound) return false; + const NbtTag* kindTag = tag.find("Kind"); + if (kindTag == nullptr || kindTag->kind() != NbtType::Short) return false; + int32_t rawKind = kindTag->asInt(); + if (rawKind < 0 || rawKind >= static_cast(MenuKind::Count)) return false; + + const NbtTag* list = tag.find("Slots"); + if (list == nullptr || list->kind() != NbtType::List) return false; + + menuKind = static_cast(rawKind); + buildSlots(); + bound = nullptr; + + const NbtTag* creativeTag = tag.find("Creative"); + creative = creativeTag != nullptr && creativeTag->kind() == NbtType::Byte && + creativeTag->asByte() != 0; + + const NbtList& rows = list->asList(); + if (static_cast(rows.size()) != slotCount()) return false; + for (int i = 0; i < slotCount(); ++i) { + if (!stackFromNbt(rows[static_cast(i)], slot(i).cell.stack)) return false; + } + return true; +} + +} // namespace vf