Adds the ability to drag and reorder cards. Card order is preserved
between rounds and is synchronized between both players (each player can
see the other player drag around and reorder their cards).
To make this possible I had to rewrite the card layout algorithm to be
stateless (e0a46fefaf), there wasn't
really a way around that since I needed a way to calculate a layout
position based on a card's index. Should hopefully be a lot easier to
read now though.
Some noteworthy stuff:
- I didn't really know what the best place to store the card order is,
so I put it on `RankedPlayCardWithPlaylistItem` since that one will stay
the same instance per round.
- To prevent the opponent's cards from dragged into the middle of the
playfield, only the x axis of the drag gets synchronized for the
`OpponentHandOfCards` with a fixed y value.
- I adjusted the replay recorder/player parameters a little. With the
drag events happening every frame the replay recorder record new frames
every 25ms and end up dropping half the replay frames per flush
interval, so I increased the sample interval to 50ms so the buffer size
matches the sample rate exactly (50ms -> 20 samples per flush every
1000ms).
I also increased the buffer size in the replay player a bit so slight
fluctuations in latency won't make it start to drop frames.
https://github.com/user-attachments/assets/b810cb85-db02-4edf-a63e-bfc96cf59665https://github.com/user-attachments/assets/4d2f884d-fcce-4948-9659-fbb314634cb8
---------
Co-authored-by: Dean Herbert <pe@ppy.sh>