202 lines
6.0 KiB
Markdown
202 lines
6.0 KiB
Markdown
|
|
# Album Slot Migration - Complete ✅
|
||
|
|
|
||
|
|
## Migration Date
|
||
|
|
November 16, 2025
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
Successfully migrated album card states from direct `IPointerClickHandler` to centralized click routing via `ICardClickHandler`, ensuring consistency with booster opening flow.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Changes Made
|
||
|
|
|
||
|
|
### 1. CardPlacedInSlotState.cs
|
||
|
|
**Changed:**
|
||
|
|
- ✅ Removed `IPointerClickHandler` interface
|
||
|
|
- ✅ Removed `UnityEngine.EventSystems` using directive
|
||
|
|
- ✅ Added `ICardClickHandler` interface
|
||
|
|
- ✅ Renamed `OnPointerClick(PointerEventData)` → `OnCardClicked(CardContext)`
|
||
|
|
- ✅ Updated method signature to use context parameter
|
||
|
|
|
||
|
|
**Result:**
|
||
|
|
- State now uses centralized click routing from CardContext
|
||
|
|
- Consistent with booster opening states
|
||
|
|
- Click gating via `context.IsClickable` now works
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2. CardAlbumEnlargedState.cs
|
||
|
|
**Changed:**
|
||
|
|
- ✅ Removed `IPointerClickHandler` interface
|
||
|
|
- ✅ Removed `UnityEngine.EventSystems` using directive
|
||
|
|
- ✅ Added `ICardClickHandler` interface
|
||
|
|
- ✅ Renamed `OnPointerClick(PointerEventData)` → `OnCardClicked(CardContext)`
|
||
|
|
- ✅ Updated method signature to use context parameter
|
||
|
|
- ✅ Added fallback for when animator is null (transitions to PlacedInSlotState immediately)
|
||
|
|
|
||
|
|
**Result:**
|
||
|
|
- State now uses centralized click routing from CardContext
|
||
|
|
- Consistent with booster opening states
|
||
|
|
- More robust error handling
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3. AlbumCardSlot.cs
|
||
|
|
**Changed:**
|
||
|
|
- ✅ Added `AlbumViewPage.RegisterCardInAlbum(card)` call in `SpawnCard()` method
|
||
|
|
- ✅ Finds AlbumViewPage via `FindFirstObjectByType<AlbumViewPage>()`
|
||
|
|
- ✅ Subscribes card's AlbumEnlargedState events to page backdrop/reparenting handlers
|
||
|
|
|
||
|
|
**Result:**
|
||
|
|
- Cards spawned in slots now properly register with page
|
||
|
|
- Backdrop shows when card is enlarged
|
||
|
|
- Card reparents to enlarged container correctly
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Slot Behavior Verification
|
||
|
|
|
||
|
|
### ✅ Slot Keeps Reference to Assigned Card
|
||
|
|
```csharp
|
||
|
|
private StateMachine.Card _placedCard;
|
||
|
|
```
|
||
|
|
- Reference stored when card is spawned or placed
|
||
|
|
- Accessible via `GetPlacedCard()`
|
||
|
|
|
||
|
|
### ✅ Auto-Spawn Owned Cards
|
||
|
|
**Flow:**
|
||
|
|
1. `OnEnable()` → `CheckAndSpawnOwnedCard()`
|
||
|
|
2. Queries CardSystemManager for owned card (highest rarity)
|
||
|
|
3. If owned → `SpawnCard(cardData)`
|
||
|
|
4. Card spawned with `card.SetupForAlbumSlot(cardData, this)` → starts in `PlacedInSlotState`
|
||
|
|
5. Card sized to match slot dimensions
|
||
|
|
6. Card registered with AlbumViewPage
|
||
|
|
|
||
|
|
### ✅ In Slot → Clickable → Enlarge
|
||
|
|
**Flow:**
|
||
|
|
1. Card in `PlacedInSlotState`
|
||
|
|
2. User clicks → CardContext routes click to state via `ICardClickHandler`
|
||
|
|
3. `PlacedInSlotState.OnCardClicked()` → transitions to `AlbumEnlargedState`
|
||
|
|
4. AlbumEnlargedState fires `OnEnlargeRequested` event
|
||
|
|
5. AlbumViewPage shows backdrop, reparents card to top layer
|
||
|
|
6. Card animates to enlarged scale
|
||
|
|
|
||
|
|
### ✅ Enlarged → Clickable → Dismiss
|
||
|
|
**Flow:**
|
||
|
|
1. Card in `AlbumEnlargedState`
|
||
|
|
2. User clicks → CardContext routes click to state via `ICardClickHandler`
|
||
|
|
3. `AlbumEnlargedState.OnCardClicked()` fires `OnShrinkRequested` event
|
||
|
|
4. AlbumViewPage hides backdrop
|
||
|
|
5. Card shrinks with animation
|
||
|
|
6. On complete → transitions back to `PlacedInSlotState`
|
||
|
|
7. Card reparents back to slot
|
||
|
|
|
||
|
|
### ✅ No Card = No Preview
|
||
|
|
**Current Behavior:**
|
||
|
|
- If player doesn't own card, `ownedCard` remains null
|
||
|
|
- `SpawnCard()` never called
|
||
|
|
- Slot remains empty
|
||
|
|
- No visuals shown
|
||
|
|
|
||
|
|
**Future:** Slot itself clickable for silhouette preview (to be implemented)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Architecture Benefits
|
||
|
|
|
||
|
|
### Unified Click Routing
|
||
|
|
**Before:**
|
||
|
|
- Booster states: `ICardClickHandler` (centralized)
|
||
|
|
- Album states: `IPointerClickHandler` (direct)
|
||
|
|
- **Problem:** Two different click systems, confusing
|
||
|
|
|
||
|
|
**After:**
|
||
|
|
- All states: `ICardClickHandler` (centralized)
|
||
|
|
- Single source of truth for click handling
|
||
|
|
- Consistent gating via `context.IsClickable`
|
||
|
|
|
||
|
|
### Click Flow
|
||
|
|
```
|
||
|
|
User clicks card →
|
||
|
|
CardDisplay.OnPointerClick →
|
||
|
|
CardContext.HandleCardDisplayClicked (checks IsClickable) →
|
||
|
|
Finds current state's ICardClickHandler →
|
||
|
|
State.OnCardClicked(context) →
|
||
|
|
State logic executes
|
||
|
|
```
|
||
|
|
|
||
|
|
### Benefits
|
||
|
|
- ✅ Consistent across all card states
|
||
|
|
- ✅ Centralized gating (IsClickable)
|
||
|
|
- ✅ Easy to debug (one routing path)
|
||
|
|
- ✅ Easy to extend (add state, implement ICardClickHandler)
|
||
|
|
- ✅ No more `IPointerClickHandler` scattered across states
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Testing Checklist
|
||
|
|
|
||
|
|
### Album View Flow
|
||
|
|
- [ ] Album page opens correctly
|
||
|
|
- [ ] Owned cards appear in album slots automatically
|
||
|
|
- [ ] Cards sized correctly to slot dimensions
|
||
|
|
- [ ] Clicking card in slot enlarges it
|
||
|
|
- [ ] Backdrop appears when card enlarged
|
||
|
|
- [ ] Card displays correctly while enlarged
|
||
|
|
- [ ] Clicking enlarged card dismisses it
|
||
|
|
- [ ] Card returns to slot correctly
|
||
|
|
- [ ] Empty slots remain empty (no preview)
|
||
|
|
- [ ] Multiple cards can be enlarged/dismissed sequentially
|
||
|
|
|
||
|
|
### Edge Cases
|
||
|
|
- [ ] Card spawned when entering album (not during booster)
|
||
|
|
- [ ] Multiple rarities of same card (highest shown)
|
||
|
|
- [ ] Very first time opening album (no owned cards)
|
||
|
|
- [ ] Rapid clicking doesn't break states
|
||
|
|
- [ ] Page close during enlarge (cleanup handled)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Future: Empty Slot Preview
|
||
|
|
|
||
|
|
When implementing "click empty slot to see silhouette":
|
||
|
|
|
||
|
|
1. Make AlbumCardSlot implement `IPointerClickHandler` for empty state
|
||
|
|
2. Add check in `OnPointerClick()`:
|
||
|
|
```csharp
|
||
|
|
if (!_isOccupiedPermanently && _placedCard == null)
|
||
|
|
{
|
||
|
|
ShowSilhouettePreview();
|
||
|
|
}
|
||
|
|
```
|
||
|
|
3. Create preview state or use temporary visual
|
||
|
|
4. Show card back / silhouette / "???" indicator
|
||
|
|
5. Click to dismiss preview
|
||
|
|
|
||
|
|
**Note:** This won't conflict with card click routing since card won't exist when slot is empty.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Files Modified
|
||
|
|
|
||
|
|
- `CardPlacedInSlotState.cs` - Uses ICardClickHandler
|
||
|
|
- `CardAlbumEnlargedState.cs` - Uses ICardClickHandler
|
||
|
|
- `AlbumCardSlot.cs` - Registers cards with AlbumViewPage
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## No Breaking Changes
|
||
|
|
|
||
|
|
- ✅ Existing Card.cs API unchanged
|
||
|
|
- ✅ AlbumViewPage event system unchanged
|
||
|
|
- ✅ Slot validation logic unchanged
|
||
|
|
- ✅ Drag-and-drop from pending cards still works
|
||
|
|
- ✅ All existing states still work
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Migration Complete!** Album slots now use unified click routing and all requirements verified. 🎉
|
||
|
|
|