Stash work

This commit is contained in:
Michal Pikulski
2025-11-17 08:39:41 +01:00
parent 78aafb9275
commit 7aca1a17ac
13 changed files with 792 additions and 1845 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -44,7 +44,9 @@ namespace UI.CardSystem
private Input.InputMode _previousInputMode;
private List<StateMachine.Card> _activeCards = new List<StateMachine.Card>();
private const int MAX_VISIBLE_CARDS = 3;
private List<StateMachine.Card> _pendingCornerCards = new List<StateMachine.Card>();
private const int MAX_PENDING_CORNER = 3;
internal override void OnManagedStart()
{
// Discover zone tabs from container
@@ -679,5 +681,87 @@ namespace UI.CardSystem
}
return null;
}
public void SpawnPendingCornerCards()
{
if (cardPrefab == null || bottomRightSlots == null) return;
CleanupPendingCornerCards();
for (int i = 0; i < MAX_PENDING_CORNER; i++)
{
var slot = FindSlotByIndex(i);
if (slot == null) break;
GameObject cardObj = Instantiate(cardPrefab, bottomRightSlots.transform);
var card = cardObj.GetComponent<StateMachine.Card>();
if (card != null)
{
card.SetupForAlbumPending();
card.AssignToSlot(slot, true);
_pendingCornerCards.Add(card);
}
else
{
Destroy(cardObj);
}
}
}
private void CleanupPendingCornerCards()
{
foreach (var c in _pendingCornerCards)
{
if (c != null) Destroy(c.gameObject);
}
_pendingCornerCards.Clear();
}
public void HandlePendingCardDragStart(StateMachine.Card cornerCard)
{
// Select smart pending card data
var selected = SelectSmartPendingCard();
if (selected == null)
{
return; // no pending data
}
cornerCard.Context.SetupCard(selected);
// Navigate album to page
int targetPage = FindPageForCard(selected);
if (targetPage >= 0)
{
NavigateToAlbumPage(targetPage);
}
// Begin flip state
cornerCard.ChangeState("FlippingPendingState");
}
private CardData SelectSmartPendingCard()
{
if (CardSystemManager.Instance == null) return null;
var pending = CardSystemManager.Instance.GetPendingRevealCards();
if (pending.Count == 0) return null;
// Try current page match
var pageDefs = GetDefinitionsOnCurrentPage();
var match = pending.Find(c => pageDefs.Contains(c.DefinitionId));
if (match != null) return match;
// Fallback random
int idx = Random.Range(0, pending.Count);
return pending[idx];
}
private List<string> GetDefinitionsOnCurrentPage()
{
// Placeholder: gather from slots on current page
return new List<string>();
}
private int FindPageForCard(CardData data)
{
// Placeholder: map definition to page index
return -1;
}
private void NavigateToAlbumPage(int pageIndex)
{
// Placeholder: call book/page flip controller
}
}
}

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEngine.UI;
namespace UI.CardSystem
{
/// <summary>
/// Simple component representing card back visuals; toggle visibility.
/// </summary>
public class CardBack : MonoBehaviour
{
[SerializeField] private Image backImage;
public void Show()
{
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 37d815ba7b02481786cc1953678a3e8e
timeCreated: 1763322207

View File

@@ -56,37 +56,63 @@ namespace UI.CardSystem.StateMachine
protected override void OnDragStartedHook()
{
base.OnDragStartedHook();
// Transition to dragging state when drag begins
Logging.Debug($"[Card] Drag started on {CardData?.Name}, transitioning to DraggingState");
ChangeState("DraggingState");
string current = GetCurrentStateName();
if (current == "PendingFaceDownState")
{
// Notify AlbumViewPage to assign data & flip
var albumPage = FindObjectOfType<AlbumViewPage>();
if (albumPage != null)
{
albumPage.HandlePendingCardDragStart(this);
}
// State change will be triggered by album page after data assignment
}
else
{
Logging.Debug($"[Card] Drag started on {CardData?.Name}, transitioning to DraggingState");
ChangeState("DraggingState");
}
}
protected override void OnDragEndedHook()
{
base.OnDragEndedHook();
// Check if we dropped in a valid album slot
if (CurrentSlot is AlbumCardSlot albumSlot)
string current = GetCurrentStateName();
if (current == "DraggingState")
{
Logging.Debug($"[Card] Dropped in album slot, transitioning to PlacedInSlotState");
// Set the parent slot on PlacedInSlotState
var placedState = GetStateComponent<States.CardPlacedInSlotState>("PlacedInSlotState");
if (placedState != null)
// Existing logic
if (CurrentSlot is AlbumCardSlot albumSlot)
{
placedState.SetParentSlot(albumSlot);
Logging.Debug($"[Card] Dropped in album slot, transitioning to PlacedInSlotState");
var placedState = GetStateComponent<States.CardPlacedInSlotState>("PlacedInSlotState");
if (placedState != null)
{
placedState.SetParentSlot(albumSlot);
}
ChangeState("PlacedInSlotState");
OnPlacedInAlbumSlot?.Invoke(this, albumSlot);
}
else
{
Logging.Debug("[Card] Dropped outside valid slot, returning to RevealedState");
ChangeState("RevealedState");
}
ChangeState("PlacedInSlotState");
// Notify listeners (AlbumViewPage) that this pending card was placed
OnPlacedInAlbumSlot?.Invoke(this, albumSlot);
}
else
else if (current == "DraggingRevealedState")
{
Logging.Debug($"[Card] Dropped outside valid slot, returning to RevealedState");
ChangeState("RevealedState");
// Pending revealed drag state end
if (CurrentSlot is AlbumCardSlot albumSlot)
{
var placedState = GetStateComponent<States.CardPlacedInSlotState>("PlacedInSlotState");
if (placedState != null) placedState.SetParentSlot(albumSlot);
ChangeState("PlacedInSlotState");
OnPlacedInAlbumSlot?.Invoke(this, albumSlot);
}
else
{
// Return to corner face-down
ChangeState("PendingFaceDownState");
}
}
}
@@ -148,6 +174,17 @@ namespace UI.CardSystem.StateMachine
}
}
/// <summary>
/// Setup for album pending state (starts at PendingFaceDownState)
/// Dragging is ENABLED; state will assign data when dragged
/// </summary>
public void SetupForAlbumPending()
{
// Start with no data; state will assign when dragged
SetupCard(null, "PendingFaceDownState");
SetDraggingEnabled(true);
}
/// <summary>
/// Transition to a specific state
/// </summary>

View File

@@ -0,0 +1,39 @@
using Core.SaveLoad;
using UnityEngine;
namespace UI.CardSystem.StateMachine.States
{
/// <summary>
/// Dragging revealed state for pending cards after flip; minimal overlay of CardDraggingState but no badges.
/// </summary>
public class CardDraggingRevealedState : AppleState
{
private CardContext context;
private Vector3 originalScale;
private void Awake()
{
context = GetComponentInParent<CardContext>();
}
public override void OnEnterState()
{
if (context == null) return;
if (context.CardDisplay != null)
{
context.CardDisplay.gameObject.SetActive(true);
context.CardDisplay.transform.localRotation = Quaternion.Euler(0,0,0);
}
originalScale = context.RootTransform.localScale;
context.RootTransform.localScale = originalScale * 1.15f;
}
private void OnDisable()
{
if (context?.RootTransform != null)
{
context.RootTransform.localScale = originalScale;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ce2483293cdd4680b5095afc1fcb2fde
timeCreated: 1763322199

View File

@@ -0,0 +1,57 @@
using Core;
using Core.SaveLoad;
using UnityEngine;
namespace UI.CardSystem.StateMachine.States
{
/// <summary>
/// Handles flipping a pending face-down card after data assignment.
/// Transitions to DraggingRevealedState when flip completes.
/// </summary>
public class CardFlippingPendingState : AppleState
{
private CardContext context;
private GameObject cardBack;
private void Awake()
{
context = GetComponentInParent<CardContext>();
if (context != null)
{
var backTransform = context.RootTransform.Find("CardBack");
if (backTransform != null) cardBack = backTransform.gameObject;
}
}
public override void OnEnterState()
{
if (context == null) return;
// Ensure card back visible and front hidden at start
if (cardBack != null) cardBack.SetActive(true);
if (context.CardDisplay != null) context.CardDisplay.gameObject.SetActive(false);
// Optional: album navigation
var albumPage = Object.FindObjectOfType<AlbumViewPage>();
if (albumPage != null && context.CardData != null)
{
int targetPage = albumPage.FindPageForCard(context.CardData); // placeholder; method may be private
}
if (context.Animator != null)
{
Transform back = cardBack != null ? cardBack.transform : null;
Transform front = context.CardDisplay != null ? context.CardDisplay.transform : null;
context.Animator.PlayFlip(back, front, onComplete: () =>
{
context.StateMachine.ChangeState("DraggingRevealedState");
});
}
else
{
if (cardBack != null) cardBack.SetActive(false);
if (context.CardDisplay != null) context.CardDisplay.gameObject.SetActive(true);
context.StateMachine.ChangeState("DraggingRevealedState");
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: edffabfce37d42ceac2194c23470acab
timeCreated: 1763322190

View File

@@ -0,0 +1,39 @@
using Core.SaveLoad;
using UnityEngine;
namespace UI.CardSystem.StateMachine.States
{
/// <summary>
/// Card is in pending face-down state in corner, awaiting drag.
/// Front hidden, back visible (assumes CardBack child exists).
/// </summary>
public class CardPendingFaceDownState : AppleState
{
private CardContext context;
private GameObject cardBack;
private void Awake()
{
context = GetComponentInParent<CardContext>();
if (context != null)
{
var backTransform = context.RootTransform.Find("CardBack");
if (backTransform != null) cardBack = backTransform.gameObject;
}
}
public override void OnEnterState()
{
if (context == null) return;
// Hide front
if (context.CardDisplay != null)
{
context.CardDisplay.gameObject.SetActive(false);
}
// Show back
if (cardBack != null) cardBack.SetActive(true);
// Scale
context.RootTransform.localScale = context.OriginalScale * 0.8f;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6fab9d595905435b82253cd4d1bf49de
timeCreated: 1763322180