feat(vf): extend ContainerMenu
This commit is contained in:
1 parent
48c7a48278
commit
54bbbed2f6
1 file changed
+104
@@ -158,3 +158,107 @@ public:
|
||||
MetaStack& inputAt(int cell);
|
||||
const MetaStack& inputAt(int cell) const;
|
||||
|
||||
// Recomputes the result slot from the current grid. Cheap enough to call
|
||||
// after every single change, which is exactly what the menu does.
|
||||
void refresh();
|
||||
|
||||
const MetaStack& result() const;
|
||||
bool hasResult() const;
|
||||
|
||||
// How many times the current grid could be crafted before running dry.
|
||||
int maxCrafts() const;
|
||||
|
||||
// Takes the result once. Each input loses one item; a damageable ingredient
|
||||
// is not eaten but comes back one durability point worse, and a broken one
|
||||
// vanishes. Returns the crafted stack, empty when there was no recipe.
|
||||
MetaStack takeResult();
|
||||
|
||||
// Shift-clicking the result: crafts until the grid runs out or the player
|
||||
// has no room, pushing every batch into the player's sections.
|
||||
int craftAll(int limit);
|
||||
|
||||
private:
|
||||
void consumeOneRound();
|
||||
CraftGrid gridOfIds() const;
|
||||
|
||||
ContainerMenu* menu;
|
||||
};
|
||||
|
||||
class ContainerMenu {
|
||||
public:
|
||||
explicit ContainerMenu(MenuKind kind, const CraftingRegistry* registry = nullptr);
|
||||
|
||||
MenuKind kind() const { return menuKind; }
|
||||
const MenuLayout& layout() const { return menuLayout; }
|
||||
const CraftingRegistry* registry() const { return craftingRegistry; }
|
||||
|
||||
int slotCount() const { return static_cast<int>(slots.size()); }
|
||||
MenuSlot& slot(int index) { return slots[static_cast<std::size_t>(index)]; }
|
||||
const MenuSlot& slot(int index) const { return slots[static_cast<std::size_t>(index)]; }
|
||||
MetaStack& stackAt(int index) { return slot(index).cell.stack; }
|
||||
const MetaStack& stackAt(int index) const { return slot(index).cell.stack; }
|
||||
|
||||
bool validIndex(int index) const { return index >= 0 && index < slotCount(); }
|
||||
bool canPlace(int index, const MetaStack& incoming) const;
|
||||
// True when the slot's contents may leave it. Every slot allows this; the
|
||||
// asymmetry is deliberate, a result slot gives but never takes.
|
||||
bool canTake(int index) const;
|
||||
|
||||
// Puts what fits into the slot, honouring the filter and the cap.
|
||||
int insertAt(int index, MetaStack& incoming);
|
||||
MetaStack takeFrom(int index, int amount);
|
||||
|
||||
// Section walkers used by shift-click and by the double-click gather.
|
||||
std::vector<int> slotsWithRole(MenuSlot::Role role) const;
|
||||
std::vector<int> playerSectionSlots() const;
|
||||
std::vector<int> containerSectionSlots() const;
|
||||
bool isPlayerSection(int index) const;
|
||||
|
||||
// Fills matching stacks first and only then empty slots, which is the order
|
||||
// a shift-click has to follow to feel right.
|
||||
int distributeInto(const std::vector<int>& targets, MetaStack& incoming);
|
||||
|
||||
int totalOf(ItemId item) const;
|
||||
int totalItems() const;
|
||||
int usedSlots() const;
|
||||
|
||||
// Binds a world Container as the storage section. The menu copies the
|
||||
// container in, and syncToContainer writes it back. ItemSlot has no room
|
||||
// for enchantments or names, so anything richer than durability survives
|
||||
// only inside the menu (or through stackListToNbt).
|
||||
void bindContainer(Container& container);
|
||||
void syncFromContainer();
|
||||
void syncToContainer();
|
||||
bool hasContainer() const { return bound != nullptr; }
|
||||
void unbind();
|
||||
|
||||
// Creative mode is the one thing allowed to conjure items: a middle click
|
||||
// clones a stack instead of doing nothing.
|
||||
void setCreativeMode(bool enabled) { creative = enabled; }
|
||||
bool creativeMode() const { return creative; }
|
||||
|
||||
bool hasCrafting() const { return menuLayout.hasCrafting() && craftingRegistry != nullptr; }
|
||||
// A two-pointer handle, cheap to hand out by value and never stale.
|
||||
CraftingView crafting();
|
||||
const MetaStack& resultStack() const;
|
||||
|
||||
// Called by CraftingView and by every slot action that touched a craft
|
||||
// input, so the result slot is never stale.
|
||||
void refreshResult();
|
||||
|
||||
// Persists every slot losslessly, unlike the Container projection.
|
||||
NbtTag toNbt() const;
|
||||
bool fromNbt(const NbtTag& tag);
|
||||
|
||||
private:
|
||||
void buildSlots();
|
||||
|
||||
MenuKind menuKind;
|
||||
MenuLayout menuLayout;
|
||||
const CraftingRegistry* craftingRegistry = nullptr;
|
||||
std::vector<MenuSlot> slots;
|
||||
Container* bound = nullptr;
|
||||
bool creative = false;
|
||||
};
|
||||
|
||||
} // namespace vf
|
||||
Reference in new issue
Block a user