using Core;
using UI.DragAndDrop.Core;
using UnityEngine;
namespace UI.CardSystem.DragDrop
{
///
/// Booster pack specific implementation of DraggableObject.
/// Manages booster pack behavior and opening logic.
///
public class BoosterPackDraggable : DraggableObject
{
[Header("Booster Pack Settings")]
[SerializeField] private bool canOpenOnDrop = true;
[SerializeField] private bool canOpenOnDoubleClick = true;
[Header("Tap to Open")]
[SerializeField] private bool canTapToOpen = true;
[SerializeField] private int maxTapsToOpen = 3;
[SerializeField] private float tapPulseScale = 1.15f;
[SerializeField] private float tapPulseDuration = 0.2f;
// ...existing code...
public event System.Action OnBoosterOpened;
public event System.Action OnTapped; // (booster, currentTap, maxTaps)
public event System.Action OnReadyToOpen; // Final tap reached
private bool _isOpening;
private float _lastClickTime;
private int _currentTapCount;
public bool IsOpening => _isOpening;
public int CurrentTapCount => _currentTapCount;
protected override void OnPointerUpHook(bool longPress)
{
base.OnPointerUpHook(longPress);
// Handle tap-to-open logic (only when in slot and not a long press)
if (canTapToOpen && !longPress && CurrentSlot != null)
{
_currentTapCount++;
// Pulse effect on tap (scales visual up and back down)
if (Visual != null)
{
// Calculate pulse intensity based on tap progress
float tapProgress = _currentTapCount / (float)maxTapsToOpen;
float currentPulseScale = 1f + (tapPulseScale - 1f) * (0.5f + tapProgress * 0.5f); // Increases from 1.075 to 1.15
// Save the current scale before pulsing
Vector3 baseScale = Visual.transform.localScale;
Pixelplacement.Tween.Cancel(Visual.transform.GetInstanceID());
Pixelplacement.Tween.LocalScale(Visual.transform, baseScale * currentPulseScale, tapPulseDuration * 0.5f, 0f,
Pixelplacement.Tween.EaseOutBack, completeCallback: () =>
{
// Return to the base scale we had before pulsing
Pixelplacement.Tween.LocalScale(Visual.transform, baseScale, tapPulseDuration * 0.5f, 0f, Pixelplacement.Tween.EaseInBack);
});
}
OnTapped?.Invoke(this, _currentTapCount, maxTapsToOpen);
if (_currentTapCount >= maxTapsToOpen)
{
OnReadyToOpen?.Invoke(this);
}
return; // Don't process double-click if tap-to-open is active
}
// ...existing code...
if (canOpenOnDoubleClick && !longPress)
{
float timeSinceLastClick = Time.time - _lastClickTime;
if (timeSinceLastClick < 0.3f) // Double click threshold
{
TriggerOpen();
}
_lastClickTime = Time.time;
}
}
protected override void OnDragEndedHook()
{
base.OnDragEndedHook();
// Find closest slot and assign to it (replaces removed auto-slotting from base class)
SlotContainer[] containers = FindObjectsByType(FindObjectsSortMode.None);
DraggableSlot closestSlot = null;
float closestDistance = float.MaxValue;
// Get position (handle both overlay and world space canvas)
Vector3 myPosition = (RectTransform != null &&
GetComponentInParent