LibCards: If dropping cards over multiple valid stacks, pick the closest

Previously, dropping a card that overlapped multiple stacks that could
accept it, would always choose the stack that came first in the stacks
list, usually the leftmost one. This would feel very odd if the card
was only slightly overlapping the left stack, and 90% over the right
one. So now, we keep looking for closer stacks even once we've found a
valid one.

There may be an option that feels even better, based on the position of
the card being dragged and the card on top of the stack we're dropping
onto, but this already fixes the issue and feels very nice. :^)
This commit is contained in:
Sam Atkins 2022-09-28 17:43:23 +01:00 committed by Sam Atkins
parent a4c1ee905f
commit ef8b1e25aa
Notes: sideshowbarker 2024-07-17 06:05:39 +09:00

View File

@ -56,20 +56,25 @@ RefPtr<CardStack> CardGame::find_stack_to_drop_on(CardStack::MovementRule moveme
{
auto bounds_to_check = moving_cards_bounds();
// FIXME: This currently returns only the first stack we overlap,
// but what we want is the stack we overlap the most.
RefPtr<CardStack> closest_stack;
float closest_distance = FLT_MAX;
for (auto const& stack : stacks()) {
if (stack.is_focused())
continue;
if (stack.bounding_box().intersects(bounds_to_check)) {
if (stack.is_allowed_to_push(moving_cards().at(0), moving_cards().size(), movement_rule)) {
return stack;
if (stack.bounding_box().intersects(bounds_to_check)
&& stack.is_allowed_to_push(moving_cards().at(0), moving_cards().size(), movement_rule)) {
auto distance = bounds_to_check.center().distance_from(stack.bounding_box().center());
if (distance < closest_distance) {
closest_stack = stack;
closest_distance = distance;
}
}
}
return nullptr;
return closest_stack;
}
void CardGame::drop_cards_on_stack(Cards::CardStack& stack, CardStack::MovementRule movement_rule)