feat: add dragAdd and dragEnd to SlotAction
This commit is contained in:
1 parent
dbf9f81545
commit
fea440d31f
1 file changed
+160
@@ -303,3 +303,163 @@ SlotActionResult dragStart(ContainerMenu& menu, CursorStack& cursor, DragState&
|
||||
return out;
|
||||
}
|
||||
|
||||
SlotActionResult dragAdd(ContainerMenu& menu, CursorStack& cursor, DragState& drag,
|
||||
const SlotAction& action, bool rightButton) {
|
||||
SlotActionResult out;
|
||||
if (!drag.active || drag.rightButton != rightButton) return out;
|
||||
int index = action.slotIndex;
|
||||
if (!menu.validIndex(index) || drag.alreadyPainted(index)) return out;
|
||||
if (!menu.canPlace(index, cursor.held)) return out;
|
||||
const MetaStack& existing = menu.stackAt(index);
|
||||
if (!existing.empty() && !stacksMergeable(existing, cursor.held)) return out;
|
||||
drag.paintedSlots.push_back(index);
|
||||
out.applied = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
SlotActionResult dragEnd(ContainerMenu& menu, CursorStack& cursor, DragState& drag,
|
||||
bool rightButton) {
|
||||
SlotActionResult out;
|
||||
if (!drag.active || drag.rightButton != rightButton) return out;
|
||||
|
||||
int painted = static_cast<int>(drag.paintedSlots.size());
|
||||
if (painted == 0 || cursor.empty()) {
|
||||
drag.reset();
|
||||
out.applied = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
int share = rightButton ? 1 : drag.payload.count / painted;
|
||||
if (share > 0) {
|
||||
for (int index : drag.paintedSlots) {
|
||||
if (cursor.empty()) break;
|
||||
MetaStack portion = splitOff(cursor.held, share);
|
||||
int moved = putIntoSlot(menu, index, portion);
|
||||
out.moved += moved;
|
||||
if (!portion.empty()) transferAll(portion, cursor.held);
|
||||
}
|
||||
}
|
||||
|
||||
drag.reset();
|
||||
out.cursorChanged = out.moved > 0;
|
||||
out.applied = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
SlotActionResult dropAction(ContainerMenu& menu, CursorStack& cursor, const SlotAction& action,
|
||||
bool wholeStack) {
|
||||
SlotActionResult out;
|
||||
|
||||
if (!cursor.empty()) {
|
||||
if (menu.validIndex(action.slotIndex)) return out;
|
||||
MetaStack thrown = wholeStack ? splitOff(cursor.held, cursor.held.count)
|
||||
: splitOff(cursor.held, 1);
|
||||
out.noteDrop(thrown);
|
||||
out.cursorChanged = true;
|
||||
out.applied = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
if (!menu.validIndex(action.slotIndex)) return out;
|
||||
int index = action.slotIndex;
|
||||
if (menu.stackAt(index).empty()) return out;
|
||||
int amount = wholeStack ? menu.stackAt(index).count : 1;
|
||||
// A result slot always hands over a whole craft: there is no such thing as
|
||||
// crafting one third of a recipe, so Q on a result drops the whole batch.
|
||||
MetaStack thrown = takeFromSlot(menu, index, amount, out);
|
||||
if (thrown.empty()) return out;
|
||||
out.noteDrop(thrown);
|
||||
out.applied = true;
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const char* clickKindName(ClickKind kind) {
|
||||
switch (kind) {
|
||||
case ClickKind::Left: return "left";
|
||||
case ClickKind::Right: return "right";
|
||||
case ClickKind::ShiftLeft: return "shiftLeft";
|
||||
case ClickKind::ShiftRight: return "shiftRight";
|
||||
case ClickKind::HotbarSwap: return "hotbarSwap";
|
||||
case ClickKind::Middle: return "middle";
|
||||
case ClickKind::Double: return "double";
|
||||
case ClickKind::DragLeftStart: return "dragLeftStart";
|
||||
case ClickKind::DragLeftAdd: return "dragLeftAdd";
|
||||
case ClickKind::DragLeftEnd: return "dragLeftEnd";
|
||||
case ClickKind::DragRightStart: return "dragRightStart";
|
||||
case ClickKind::DragRightAdd: return "dragRightAdd";
|
||||
case ClickKind::DragRightEnd: return "dragRightEnd";
|
||||
case ClickKind::DropOne: return "dropOne";
|
||||
case ClickKind::DropStack: return "dropStack";
|
||||
case ClickKind::Count: break;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void DragState::reset() {
|
||||
active = false;
|
||||
rightButton = false;
|
||||
paintedSlots.clear();
|
||||
payload.clear();
|
||||
}
|
||||
|
||||
bool DragState::alreadyPainted(int index) const {
|
||||
return std::find(paintedSlots.begin(), paintedSlots.end(), index) != paintedSlots.end();
|
||||
}
|
||||
|
||||
SlotAction clickAt(ClickKind kind, int slotIndex) {
|
||||
SlotAction action;
|
||||
action.kind = kind;
|
||||
action.slotIndex = slotIndex;
|
||||
return action;
|
||||
}
|
||||
|
||||
SlotAction hotbarSwapAt(int slotIndex, int hotbarButton) {
|
||||
SlotAction action;
|
||||
action.kind = ClickKind::HotbarSwap;
|
||||
action.slotIndex = slotIndex;
|
||||
action.hotbarButton = hotbarButton;
|
||||
return action;
|
||||
}
|
||||
|
||||
void SlotActionResult::noteDrop(const MetaStack& stack) {
|
||||
if (stack.empty()) return;
|
||||
dropped += stack.count;
|
||||
droppedStacks.push_back(stack);
|
||||
}
|
||||
|
||||
SlotActionResult applySlotAction(ContainerMenu& menu, CursorStack& cursor, DragState& drag,
|
||||
const SlotAction& action) {
|
||||
switch (action.kind) {
|
||||
case ClickKind::Left: return leftClick(menu, cursor, action);
|
||||
case ClickKind::Right: return rightClick(menu, cursor, action);
|
||||
case ClickKind::ShiftLeft:
|
||||
case ClickKind::ShiftRight: return shiftClick(menu, action);
|
||||
case ClickKind::HotbarSwap: return hotbarSwap(menu, action);
|
||||
case ClickKind::Middle: return middleClick(menu, cursor, action);
|
||||
case ClickKind::Double: return doubleClick(menu, cursor);
|
||||
case ClickKind::DragLeftStart: return dragStart(menu, cursor, drag, action, false);
|
||||
case ClickKind::DragLeftAdd: return dragAdd(menu, cursor, drag, action, false);
|
||||
case ClickKind::DragLeftEnd: return dragEnd(menu, cursor, drag, false);
|
||||
case ClickKind::DragRightStart: return dragStart(menu, cursor, drag, action, true);
|
||||
case ClickKind::DragRightAdd: return dragAdd(menu, cursor, drag, action, true);
|
||||
case ClickKind::DragRightEnd: return dragEnd(menu, cursor, drag, true);
|
||||
case ClickKind::DropOne: return dropAction(menu, cursor, action, false);
|
||||
case ClickKind::DropStack: return dropAction(menu, cursor, action, true);
|
||||
case ClickKind::Count: break;
|
||||
}
|
||||
return SlotActionResult{};
|
||||
}
|
||||
|
||||
int totalAcrossMenuAndCursor(const ContainerMenu& menu, const CursorStack& cursor, ItemId item) {
|
||||
int total = menu.totalOf(item);
|
||||
if (!cursor.empty() && cursor.held.item == item) total += cursor.held.count;
|
||||
return total;
|
||||
}
|
||||
|
||||
int totalItemsAcrossMenuAndCursor(const ContainerMenu& menu, const CursorStack& cursor) {
|
||||
return menu.totalItems() + cursor.held.count;
|
||||
}
|
||||
|
||||
} // namespace vf
|
||||
Reference in new issue
Block a user