- **Refactored Card Placement Flow** - Separated card presentation from orchestration logic - Extracted `CornerCardManager` for pending card lifecycle (spawn, shuffle, rebuild) - Extracted `AlbumNavigationService` for book page navigation and zone mapping - Extracted `CardEnlargeController` for backdrop management and card reparenting - Implemented controller pattern (non-MonoBehaviour) for complex logic - Cards now unparent from slots before rebuild to prevent premature destruction - **Improved Corner Card Display** - Fixed cards spawning on top of each other during rebuild - Implemented shuffle-to-front logic (remaining cards occupy slots 0→1→2) - Added smart card selection (prioritizes cards matching current album page) - Pending cards now removed from queue immediately on drag start - Corner cards rebuild after each placement with proper slot reassignment - **Enhanced Album Card Viewing** - Added dramatic scale increase when viewing cards from album slots - Implemented shrink animation when dismissing enlarged cards - Cards transition: `PlacedInSlotState` → `AlbumEnlargedState` → `PlacedInSlotState` - Backdrop shows/hides with card enlarge/shrink cycle - Cards reparent to enlarged container while viewing, return to slot after - **State Machine Improvements** - Added `CardStateNames` constants for type-safe state transitions - Implemented `ICardClickHandler` and `ICardStateDragHandler` interfaces - State transitions now use cached property indices - `BoosterCardContext` separated from `CardContext` for single responsibility - **Code Cleanup** - Identified unused `SlotContainerHelper.cs` (superseded by `CornerCardManager`) - Identified unused `BoosterPackDraggable.canOpenOnDrop` field - Identified unused `AlbumViewPage._previousInputMode` (hardcoded value) - Identified unused `Card.OnPlacedInAlbumSlot` event (no subscribers) Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com> Co-authored-by: Michal Pikulski <michal@foolhardyhorizons.com> Reviewed-on: #59
218 lines
8.3 KiB
C#
218 lines
8.3 KiB
C#
using Core.SaveLoad;
|
|
using UnityEngine;
|
|
using AppleHills.Core.Settings;
|
|
using Core;
|
|
using AppleHills.Data.CardSystem;
|
|
|
|
namespace UI.CardSystem.StateMachine.States
|
|
{
|
|
/// <summary>
|
|
/// Enlarged state for REPEAT cards - shows progress bar toward next rarity upgrade.
|
|
/// Uses ProgressBarController to animate progress filling.
|
|
/// Auto-upgrades card when threshold is reached.
|
|
/// </summary>
|
|
public class CardEnlargedRepeatState : AppleState, ICardClickHandler
|
|
{
|
|
[Header("State-Owned Visuals")]
|
|
[SerializeField] private ProgressBarController progressBar;
|
|
|
|
private CardContext _context;
|
|
private ICardSystemSettings _settings;
|
|
private bool _waitingForTap = false;
|
|
|
|
private void Awake()
|
|
{
|
|
_context = GetComponentInParent<CardContext>();
|
|
_settings = GameManager.GetSettingsObject<ICardSystemSettings>();
|
|
}
|
|
|
|
public override void OnEnterState()
|
|
{
|
|
// Ensure card front is visible and facing camera
|
|
if (_context.CardDisplay != null)
|
|
{
|
|
_context.CardDisplay.gameObject.SetActive(true);
|
|
_context.CardDisplay.transform.localRotation = Quaternion.Euler(0, 0, 0);
|
|
}
|
|
|
|
_waitingForTap = false;
|
|
|
|
// Query current collection state for this card
|
|
bool isNew = Data.CardSystem.CardSystemManager.Instance.IsCardNew(_context.CardData, out CardData existingCard);
|
|
int currentOwnedCount = (existingCard != null) ? existingCard.CopiesOwned : 0;
|
|
|
|
// Show progress bar
|
|
if (progressBar != null)
|
|
{
|
|
progressBar.gameObject.SetActive(true);
|
|
|
|
int currentCount = currentOwnedCount + 1; // +1 because we just got this card
|
|
int maxCount = _settings.CardsToUpgrade;
|
|
|
|
progressBar.ShowProgress(currentCount, maxCount, OnProgressComplete);
|
|
}
|
|
else
|
|
{
|
|
Logging.Warning("[CardEnlargedRepeatState] ProgressBar component not assigned!");
|
|
OnProgressComplete();
|
|
}
|
|
|
|
// Enlarge the card
|
|
if (_context.Animator != null)
|
|
{
|
|
_context.Animator.PlayEnlarge(_settings.NewCardEnlargedScale);
|
|
}
|
|
}
|
|
|
|
private void OnProgressComplete()
|
|
{
|
|
// Query current state again to determine if upgrade is triggered
|
|
Data.CardSystem.CardSystemManager.Instance.IsCardNew(_context.CardData, out CardData existingCard);
|
|
int currentOwnedCount = (existingCard != null) ? existingCard.CopiesOwned : 0;
|
|
int countWithThisCard = currentOwnedCount + 1;
|
|
|
|
bool willUpgrade = (_context.CardData.Rarity < AppleHills.Data.CardSystem.CardRarity.Legendary) &&
|
|
(countWithThisCard >= _settings.CardsToUpgrade);
|
|
|
|
if (willUpgrade)
|
|
{
|
|
Logging.Debug($"[CardEnlargedRepeatState] Card will trigger upgrade! ({countWithThisCard}/{_settings.CardsToUpgrade})");
|
|
TriggerUpgrade();
|
|
}
|
|
else
|
|
{
|
|
// No upgrade - just wait for tap to dismiss
|
|
Logging.Debug($"[CardEnlargedRepeatState] Progress shown ({countWithThisCard}/{_settings.CardsToUpgrade}), waiting for tap to dismiss");
|
|
_waitingForTap = true;
|
|
}
|
|
}
|
|
|
|
private void TriggerUpgrade()
|
|
{
|
|
CardData cardData = _context.CardData;
|
|
CardRarity oldRarity = cardData.Rarity;
|
|
CardRarity newRarity = oldRarity + 1;
|
|
|
|
Logging.Debug($"[CardEnlargedRepeatState] Upgrading card from {oldRarity} to {newRarity}");
|
|
|
|
var inventory = Data.CardSystem.CardSystemManager.Instance.GetCardInventory();
|
|
|
|
// Remove lower rarity card counts (set to 1 per new rule instead of zeroing out)
|
|
CardRarity clearRarity = cardData.Rarity;
|
|
while (clearRarity < newRarity)
|
|
{
|
|
var lower = inventory.GetCard(cardData.DefinitionId, clearRarity);
|
|
if (lower != null) lower.CopiesOwned = 1; // changed from 0 to 1
|
|
clearRarity += 1;
|
|
}
|
|
|
|
// Check if higher rarity already exists BEFORE adding
|
|
CardData existingHigher = inventory.GetCard(cardData.DefinitionId, newRarity);
|
|
bool higherExists = existingHigher != null;
|
|
|
|
if (higherExists)
|
|
{
|
|
// Increment existing higher rarity copies
|
|
existingHigher.CopiesOwned += 1;
|
|
|
|
// Update our displayed card to new rarity
|
|
cardData.Rarity = newRarity;
|
|
cardData.CopiesOwned = existingHigher.CopiesOwned; // reflect correct count
|
|
|
|
if (_context.CardDisplay != null)
|
|
{
|
|
_context.CardDisplay.SetupCard(cardData);
|
|
}
|
|
|
|
// For repeat-at-higher-rarity: show a brief progress update at higher rarity while enlarged
|
|
int ownedAtHigher = existingHigher.CopiesOwned;
|
|
if (progressBar != null)
|
|
{
|
|
progressBar.ShowProgress(ownedAtHigher, _settings.CardsToUpgrade, () =>
|
|
{
|
|
// After showing higher-rarity progress, wait for tap to dismiss
|
|
_waitingForTap = true;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
_waitingForTap = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Create upgraded card as new rarity
|
|
CardData upgradedCard = new CardData(cardData);
|
|
upgradedCard.Rarity = newRarity;
|
|
upgradedCard.CopiesOwned = 1;
|
|
|
|
// Add to inventory
|
|
inventory.AddCard(upgradedCard);
|
|
|
|
// Update current display card to new rarity
|
|
cardData.Rarity = newRarity;
|
|
cardData.CopiesOwned = upgradedCard.CopiesOwned;
|
|
|
|
if (_context.CardDisplay != null)
|
|
{
|
|
_context.CardDisplay.SetupCard(cardData);
|
|
}
|
|
|
|
// Branch based on whether legendary or not
|
|
if (newRarity == CardRarity.Legendary)
|
|
{
|
|
// Show special enlarged legendary presentation, await click to shrink to revealed
|
|
_context.StateMachine.ChangeState(CardStateNames.EnlargedLegendaryRepeat);
|
|
}
|
|
else
|
|
{
|
|
// Treat as NEW at higher rarity (enlarged with NEW visuals handled there)
|
|
_context.StateMachine.ChangeState(CardStateNames.EnlargedNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TransitionToNewCardView()
|
|
{
|
|
// Hide progress bar before transitioning
|
|
if (progressBar != null)
|
|
{
|
|
progressBar.gameObject.SetActive(false);
|
|
}
|
|
|
|
// Transition to EnlargedNewState (card is already enlarged, will show NEW badge)
|
|
// State will query fresh collection data to determine if truly new
|
|
_context.StateMachine.ChangeState(CardStateNames.EnlargedNew);
|
|
}
|
|
|
|
public void OnCardClicked(CardContext context)
|
|
{
|
|
if (!_waitingForTap)
|
|
return;
|
|
|
|
|
|
// Tap to dismiss - shrink back to original scale and transition to revealed state
|
|
if (context.Animator != null)
|
|
{
|
|
context.Animator.PlayShrink(context.OriginalScale, onComplete: () =>
|
|
{
|
|
context.StateMachine.ChangeState(CardStateNames.Revealed);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
context.StateMachine.ChangeState("RevealedState");
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
// Hide progress bar when leaving state
|
|
if (progressBar != null)
|
|
{
|
|
progressBar.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
}
|