From ef8b1e25aa7ed30e71d0cae46ba5da55345fe181 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 28 Sep 2022 17:43:23 +0100 Subject: [PATCH] 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. :^) --- Userland/Libraries/LibCards/CardGame.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibCards/CardGame.cpp b/Userland/Libraries/LibCards/CardGame.cpp index 96a5d7e8b7..d2340dfef8 100644 --- a/Userland/Libraries/LibCards/CardGame.cpp +++ b/Userland/Libraries/LibCards/CardGame.cpp @@ -56,20 +56,25 @@ RefPtr 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 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)