2025-11-18 08:40:59 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using AppleHills.Data.CardSystem;
|
|
|
|
|
|
using Core;
|
|
|
|
|
|
using Data.CardSystem;
|
|
|
|
|
|
using Pixelplacement;
|
|
|
|
|
|
using UI.Core;
|
|
|
|
|
|
using UI.DragAndDrop.Core;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
using UnityEngine.Serialization;
|
|
|
|
|
|
|
|
|
|
|
|
namespace UI.CardSystem
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UI page for viewing the player's card collection in an album.
|
|
|
|
|
|
/// Manages booster pack button visibility and opening flow.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class AlbumViewPage : UIPage
|
|
|
|
|
|
{
|
|
|
|
|
|
[Header("UI References")]
|
|
|
|
|
|
[SerializeField] private CanvasGroup canvasGroup;
|
|
|
|
|
|
[SerializeField] private Button exitButton;
|
|
|
|
|
|
[SerializeField] private BookCurlPro.BookPro book;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Zone Navigation")]
|
|
|
|
|
|
[SerializeField] private Transform tabContainer; // Container holding all BookTabButton children
|
|
|
|
|
|
private BookTabButton[] _zoneTabs; // Discovered zone tab buttons
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Album Card Reveal")]
|
|
|
|
|
|
[SerializeField] private SlotContainer bottomRightSlots;
|
|
|
|
|
|
[FormerlySerializedAs("albumCardPlacementPrefab")]
|
|
|
|
|
|
[SerializeField] private GameObject cardPrefab; // New Card prefab for placement
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Card Enlarge System")]
|
|
|
|
|
|
[SerializeField] private GameObject cardEnlargedBackdrop; // Backdrop to block interactions
|
|
|
|
|
|
[SerializeField] private Transform cardEnlargedContainer; // Container for enlarged cards (sits above backdrop)
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Booster Pack UI")]
|
|
|
|
|
|
[SerializeField] private GameObject[] boosterPackButtons;
|
|
|
|
|
|
[SerializeField] private BoosterOpeningPage boosterOpeningPage;
|
|
|
|
|
|
|
|
|
|
|
|
private Input.InputMode _previousInputMode;
|
|
|
|
|
|
|
|
|
|
|
|
// Controllers: Lazy-initialized services (auto-created on first use)
|
|
|
|
|
|
private CornerCardManager _cornerCardManager;
|
|
|
|
|
|
private CornerCardManager CornerCards => _cornerCardManager ??= new CornerCardManager(
|
|
|
|
|
|
bottomRightSlots,
|
|
|
|
|
|
cardPrefab,
|
|
|
|
|
|
this
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
private AlbumNavigationService _navigationService;
|
|
|
|
|
|
private AlbumNavigationService Navigation => _navigationService ??= new AlbumNavigationService(
|
|
|
|
|
|
book,
|
|
|
|
|
|
_zoneTabs
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
private CardEnlargeController _enlargeController;
|
|
|
|
|
|
private CardEnlargeController Enlarge => _enlargeController ??= new CardEnlargeController(
|
|
|
|
|
|
cardEnlargedBackdrop,
|
|
|
|
|
|
cardEnlargedContainer
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Query method: Check if the book is currently flipping to a page.
|
|
|
|
|
|
/// Used by card states to know if they should wait before placing.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsPageFlipping => Navigation.IsPageFlipping;
|
|
|
|
|
|
|
|
|
|
|
|
internal override void OnManagedStart()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Discover zone tabs from container
|
|
|
|
|
|
DiscoverZoneTabs();
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure we have a CanvasGroup for transitions
|
|
|
|
|
|
if (canvasGroup == null)
|
|
|
|
|
|
canvasGroup = GetComponent<CanvasGroup>();
|
|
|
|
|
|
if (canvasGroup == null)
|
|
|
|
|
|
canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
|
|
|
|
|
|
|
|
|
|
|
// Hide backdrop initially
|
|
|
|
|
|
if (cardEnlargedBackdrop != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
cardEnlargedBackdrop.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set up exit button
|
|
|
|
|
|
if (exitButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
exitButton.onClick.AddListener(OnExitButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set up booster pack button listeners
|
|
|
|
|
|
SetupBoosterButtonListeners();
|
|
|
|
|
|
|
|
|
|
|
|
// Subscribe to book page flip events
|
|
|
|
|
|
if (book != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
book.OnFlip.AddListener(OnPageFlipped);
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Subscribed to book.OnFlip event");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Warning("[AlbumViewPage] Book reference is null, cannot subscribe to OnFlip event!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Subscribe to CardSystemManager events (managers are guaranteed to be initialized)
|
|
|
|
|
|
if (CardSystemManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
CardSystemManager.Instance.OnBoosterCountChanged += OnBoosterCountChanged;
|
|
|
|
|
|
// NOTE: OnPendingCardAdded is subscribed in TransitionIn, not here
|
|
|
|
|
|
// This prevents spawning cards when page is not active
|
|
|
|
|
|
|
|
|
|
|
|
// Update initial button visibility
|
|
|
|
|
|
int initialCount = CardSystemManager.Instance.GetBoosterPackCount();
|
|
|
|
|
|
UpdateBoosterButtons(initialCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UI pages should start disabled
|
|
|
|
|
|
gameObject.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Discover all BookTabButton components from the tab container
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void DiscoverZoneTabs()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (tabContainer == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("[AlbumViewPage] Tab container is not assigned! Cannot discover zone tabs.");
|
|
|
|
|
|
_zoneTabs = new BookTabButton[0];
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get all BookTabButton components from children
|
|
|
|
|
|
_zoneTabs = tabContainer.GetComponentsInChildren<BookTabButton>(includeInactive: false);
|
|
|
|
|
|
|
|
|
|
|
|
if (_zoneTabs == null || _zoneTabs.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Warning($"[AlbumViewPage] No BookTabButton components found in tab container '{tabContainer.name}'!");
|
|
|
|
|
|
_zoneTabs = new BookTabButton[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug($"[AlbumViewPage] Discovered {_zoneTabs.Length} zone tabs from container '{tabContainer.name}'");
|
|
|
|
|
|
foreach (var tab in _zoneTabs)
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug($" - Tab: {tab.name}, Zone: {tab.Zone}, TargetPage: {tab.TargetPage}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SetupBoosterButtonListeners()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boosterPackButtons == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < boosterPackButtons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boosterPackButtons[i] == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Button button = boosterPackButtons[i].GetComponent<Button>();
|
|
|
|
|
|
if (button != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
button.onClick.AddListener(OnBoosterButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal override void OnManagedDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Unsubscribe from book events
|
|
|
|
|
|
if (book != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
book.OnFlip.RemoveListener(OnPageFlipped);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Unsubscribe from CardSystemManager
|
|
|
|
|
|
if (CardSystemManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
CardSystemManager.Instance.OnBoosterCountChanged -= OnBoosterCountChanged;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clean up exit button
|
|
|
|
|
|
if (exitButton != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
exitButton.onClick.RemoveListener(OnExitButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clean up booster button listeners
|
|
|
|
|
|
if (boosterPackButtons != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var buttonObj in boosterPackButtons)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (buttonObj == null) continue;
|
|
|
|
|
|
|
|
|
|
|
|
Button button = buttonObj.GetComponent<Button>();
|
|
|
|
|
|
if (button != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
button.onClick.RemoveListener(OnBoosterButtonClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clean up pending corner cards
|
|
|
|
|
|
CleanupPendingCornerCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnExitButtonClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (book != null && book.CurrentPaper != 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Not on page 0, flip to page 0 first
|
|
|
|
|
|
BookCurlPro.AutoFlip autoFlip = book.GetComponent<BookCurlPro.AutoFlip>();
|
|
|
|
|
|
if (autoFlip == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
autoFlip = book.gameObject.AddComponent<BookCurlPro.AutoFlip>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
autoFlip.enabled = true;
|
|
|
|
|
|
autoFlip.StartFlipping(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Already on page 0 or no book reference, exit
|
|
|
|
|
|
// Restore input mode before popping
|
|
|
|
|
|
if (Input.InputManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Input.InputManager.Instance.SetInputMode(_previousInputMode);
|
|
|
|
|
|
Logging.Debug($"[AlbumViewPage] Restored input mode to {_previousInputMode} on exit");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (UIPageController.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
UIPageController.Instance.PopPage();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnBoosterCountChanged(int newCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
UpdateBoosterButtons(newCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateBoosterButtons(int boosterCount)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boosterPackButtons == null || boosterPackButtons.Length == 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
int visibleCount = Mathf.Min(boosterCount, boosterPackButtons.Length);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < boosterPackButtons.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boosterPackButtons[i] != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
boosterPackButtons[i].SetActive(i < visibleCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnBoosterButtonClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boosterOpeningPage != null && UIPageController.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Pass current booster count to the opening page
|
|
|
|
|
|
int boosterCount = CardSystemManager.Instance?.GetBoosterPackCount() ?? 0;
|
|
|
|
|
|
boosterOpeningPage.SetAvailableBoosterCount(boosterCount);
|
|
|
|
|
|
|
|
|
|
|
|
UIPageController.Instance.PushPage(boosterOpeningPage);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void TransitionIn()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Only store and switch input mode if this is the first time entering
|
|
|
|
|
|
if (Input.InputManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Store the current input mode before switching
|
|
|
|
|
|
_previousInputMode = Input.InputMode.GameAndUI;
|
|
|
|
|
|
Input.InputManager.Instance.SetInputMode(Input.InputMode.UI);
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Switched to UI-only input mode on first entry");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Only spawn pending cards if we're already on an album page (not the menu)
|
|
|
|
|
|
if (IsInAlbumProper())
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Opening directly to album page - spawning cards immediately");
|
|
|
|
|
|
SpawnPendingCornerCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Opening to menu page - cards will spawn when entering album");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
base.TransitionIn();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void TransitionOut()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clean up active pending cards to prevent duplicates on next opening
|
|
|
|
|
|
CleanupPendingCornerCards();
|
|
|
|
|
|
|
|
|
|
|
|
// Don't restore input mode here - only restore when actually exiting (in OnExitButtonClicked)
|
|
|
|
|
|
base.TransitionOut();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void DoTransitionIn(System.Action onComplete)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Simple fade in animation
|
|
|
|
|
|
if (canvasGroup != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
canvasGroup.alpha = 0f;
|
|
|
|
|
|
Tween.Value(0f, 1f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete, obeyTimescale: false);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fallback if no CanvasGroup
|
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void DoTransitionOut(System.Action onComplete)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clean up any enlarged card state before closing
|
|
|
|
|
|
CleanupEnlargedCardState();
|
|
|
|
|
|
|
|
|
|
|
|
// Simple fade out animation
|
|
|
|
|
|
if (canvasGroup != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Tween.Value(canvasGroup.alpha, 0f, (value) => canvasGroup.alpha = value, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete, obeyTimescale: false);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fallback if no CanvasGroup
|
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Clean up enlarged card state when closing the album
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void CleanupEnlargedCardState()
|
|
|
|
|
|
{
|
|
|
|
|
|
Enlarge.CleanupEnlargedState();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Check if we're currently viewing the album proper (not the menu page)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private bool IsInAlbumProper()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Navigation.IsInAlbumProper();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called when book page flips - show/hide pending cards based on whether we're in the album proper
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnPageFlipped()
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isInAlbum = IsInAlbumProper();
|
|
|
|
|
|
if (isInAlbum && CornerCards.PendingCards.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Entering album proper and no cards spawned yet - spawn them with animation
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Entering album proper - spawning pending cards with animation");
|
|
|
|
|
|
SpawnPendingCornerCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!isInAlbum && CornerCards.PendingCards.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Returning to menu page - cleanup cards
|
|
|
|
|
|
Logging.Debug("[AlbumViewPage] Returning to menu page - cleaning up pending cards");
|
|
|
|
|
|
CleanupPendingCornerCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Logging.Debug($"[AlbumViewPage] Page flipped but no card state change needed (already in correct state)");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Card Enlarge System (Album Slots)
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Subscribe to a placed card's enlarged state events to manage backdrop and reparenting.
|
|
|
|
|
|
/// Called by AlbumCardSlot when it spawns an owned card in a slot.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void RegisterCardInAlbum(StateMachine.Card card)
|
|
|
|
|
|
{
|
|
|
|
|
|
Enlarge.RegisterCard(card);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UnregisterCardInAlbum(StateMachine.Card card)
|
|
|
|
|
|
{
|
|
|
|
|
|
Enlarge.UnregisterCard(card);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Find a slot by its SlotIndex property
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private DraggableSlot FindSlotByIndex(int slotIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (bottomRightSlots == null)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var slot in bottomRightSlots.Slots)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (slot.SlotIndex == slotIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
return slot;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SpawnPendingCornerCards()
|
|
|
|
|
|
{
|
|
|
|
|
|
CornerCards.SpawnCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CleanupPendingCornerCards()
|
|
|
|
|
|
{
|
|
|
|
|
|
CornerCards.CleanupAllCards();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Query Methods for Card States (Data Providers)
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Query method: Get card data for a pending slot.
|
|
|
|
|
|
/// Called by PendingFaceDownState when drag starts.
|
|
|
|
|
|
/// IMPORTANT: This removes the card from pending list immediately, then rebuilds corner.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public CardData GetCardForPendingSlot()
|
|
|
|
|
|
{
|
|
|
|
|
|
return CornerCards.GetSmartSelection();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Query method: Get target slot for a card.
|
|
|
|
|
|
/// Called by PendingFaceDownState to find where card should go.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public AlbumCardSlot GetTargetSlotForCard(CardData cardData)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardData == null) return null;
|
|
|
|
|
|
|
|
|
|
|
|
var allSlots = FindObjectsByType<AlbumCardSlot>(FindObjectsSortMode.None);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var slot in allSlots)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (slot.TargetCardDefinition != null &&
|
|
|
|
|
|
slot.TargetCardDefinition.Id == cardData.DefinitionId)
|
|
|
|
|
|
{
|
|
|
|
|
|
return slot;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Service method: Navigate to the page for a specific card.
|
|
|
|
|
|
/// Called by PendingFaceDownState to flip book to correct zone page.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void NavigateToCardPage(CardData cardData, System.Action onComplete)
|
|
|
|
|
|
{
|
|
|
|
|
|
Navigation.NavigateToCardPage(cardData, onComplete);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Notify that a card has been placed (for cleanup).
|
|
|
|
|
|
/// Called by PlacedInSlotState after placement is complete.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void NotifyCardPlaced(StateMachine.Card card)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Delegate to corner card manager for tracking removal
|
|
|
|
|
|
CornerCards.NotifyCardPlaced(card);
|
|
|
|
|
|
|
|
|
|
|
|
// Register for enlarge/shrink functionality
|
|
|
|
|
|
RegisterCardInAlbum(card);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Helper Methods
|
|
|
|
|
|
|
|
|
|
|
|
public List<string> GetDefinitionsOnCurrentPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Navigation.GetDefinitionsOnCurrentPage();
|
|
|
|
|
|
}
|
2025-11-19 23:06:04 +01:00
|
|
|
|
|
2025-11-18 08:40:59 +00:00
|
|
|
|
#endregion
|
2025-11-19 23:06:04 +01:00
|
|
|
|
|
|
|
|
|
|
public void FlipPageRightFeedback()
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioManager.Instance.LoadAndPlayUIAudio("random_paper_pickup",false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void FlipPageLeftFeedback()
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioManager.Instance.LoadAndPlayUIAudio("random_paper_putdown", false);
|
|
|
|
|
|
}
|
2025-11-18 08:40:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|