149 lines
4.9 KiB
C#
149 lines
4.9 KiB
C#
using System;
|
|
using AppleHills.Data.CardSystem;
|
|
using Core.SaveLoad;
|
|
using UnityEngine;
|
|
|
|
namespace UI.CardSystem.StateMachine
|
|
{
|
|
/// <summary>
|
|
/// Shared context for card states.
|
|
/// Provides access to common components and data that states need.
|
|
/// </summary>
|
|
public class CardContext : MonoBehaviour
|
|
{
|
|
[Header("Core Components")]
|
|
[SerializeField] private CardDisplay cardDisplay;
|
|
[SerializeField] private CardAnimator cardAnimator;
|
|
private AppleMachine stateMachine;
|
|
|
|
[Header("Card Data")]
|
|
private CardData cardData;
|
|
|
|
// Public accessors
|
|
public CardDisplay CardDisplay => cardDisplay;
|
|
public CardAnimator Animator => cardAnimator;
|
|
public AppleMachine StateMachine => stateMachine;
|
|
public Transform RootTransform => transform;
|
|
public CardData CardData => cardData;
|
|
|
|
// Runtime state
|
|
public bool IsClickable { get; set; } = true;
|
|
public bool SuppressRevealBadges { get; set; } = false; // Set by states to suppress NEW/REPEAT badges in revealed state
|
|
|
|
// Original transform data (captured on spawn for shrink animations)
|
|
public Vector3 OriginalScale { get; private set; }
|
|
public Vector3 OriginalPosition { get; private set; }
|
|
public Quaternion OriginalRotation { get; private set; }
|
|
|
|
// Single event for reveal flow completion
|
|
public event Action<CardContext> OnRevealFlowComplete;
|
|
|
|
// Generic drag event - fired when drag starts, consumers decide how to handle based on current state
|
|
public event Action<CardContext> OnDragStarted;
|
|
|
|
// Generic drag end event - fired when drag ends, consumers decide how to handle based on current state
|
|
public event Action<CardContext> OnDragEnded;
|
|
|
|
private bool _hasCompletedReveal = false;
|
|
public bool HasCompletedReveal => _hasCompletedReveal;
|
|
|
|
// Helper method for states to signal completion
|
|
public void NotifyRevealComplete()
|
|
{
|
|
if (!_hasCompletedReveal)
|
|
{
|
|
_hasCompletedReveal = true;
|
|
OnRevealFlowComplete?.Invoke(this);
|
|
}
|
|
}
|
|
|
|
// Helper method for states/card to signal drag started
|
|
public void NotifyDragStarted()
|
|
{
|
|
OnDragStarted?.Invoke(this);
|
|
}
|
|
|
|
// Helper method for states/card to signal drag ended
|
|
public void NotifyDragEnded()
|
|
{
|
|
OnDragEnded?.Invoke(this);
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
// Auto-find components if not assigned
|
|
if (cardDisplay == null)
|
|
cardDisplay = GetComponentInChildren<CardDisplay>();
|
|
|
|
if (cardAnimator == null)
|
|
cardAnimator = GetComponent<CardAnimator>();
|
|
|
|
if (stateMachine == null)
|
|
stateMachine = GetComponentInChildren<AppleMachine>();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
// Subscribe to CardDisplay click and route to active state
|
|
if (cardDisplay != null)
|
|
{
|
|
cardDisplay.OnCardClicked += HandleCardDisplayClicked;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (cardDisplay != null)
|
|
{
|
|
cardDisplay.OnCardClicked -= HandleCardDisplayClicked;
|
|
}
|
|
}
|
|
|
|
private void HandleCardDisplayClicked(CardDisplay _)
|
|
{
|
|
// Gate by clickability
|
|
if (!IsClickable) return;
|
|
if (stateMachine == null || stateMachine.currentState == null) return;
|
|
|
|
var handler = stateMachine.currentState.GetComponent<ICardClickHandler>();
|
|
if (handler != null)
|
|
{
|
|
handler.OnCardClicked(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup the card with data
|
|
/// </summary>
|
|
public void SetupCard(CardData data)
|
|
{
|
|
cardData = data;
|
|
_hasCompletedReveal = false; // Reset completion flag
|
|
|
|
// Capture original transform for shrink animations.
|
|
// If current scale is ~0 (pop-in staging), default to Vector3.one.
|
|
var currentScale = transform.localScale;
|
|
if (currentScale.x < 0.01f && currentScale.y < 0.01f && currentScale.z < 0.01f)
|
|
{
|
|
OriginalScale = Vector3.one;
|
|
}
|
|
else
|
|
{
|
|
OriginalScale = currentScale;
|
|
}
|
|
OriginalPosition = transform.localPosition;
|
|
OriginalRotation = transform.localRotation;
|
|
|
|
if (cardDisplay != null)
|
|
{
|
|
cardDisplay.SetupCard(data);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the card display component
|
|
/// </summary>
|
|
public CardDisplay GetCardDisplay() => cardDisplay;
|
|
}
|
|
}
|