using UnityEngine;
using System.Collections;
using Unity.Cinemachine;
using Data.CardSystem;
using Pixelplacement;
using Core;
using UI;
namespace Interactions
{
///
/// Special pickup that plays a fancy sequence when collected:
/// - Follower picks up normally
/// - Pauses follower movement
/// - Zooms camera in
/// - Grows/pulses the booster pack
/// - Animates to backpack icon
/// - Gives player a booster pack
/// - Restores camera and resumes movement
///
public class BoosterPackPickup : Pickup
{
[Header("Booster Pack Sequence")]
[SerializeField] private GameObject glowVisualPrefab;
[SerializeField] private CinemachineCamera zoomCamera;
[SerializeField] private int boosterPackCount = 1;
[Header("Sequence Timing")]
[SerializeField] private float cameraBlendWait = 0.3f;
[SerializeField] private float growDuration = 0.25f;
[SerializeField] private float pulseDuration = 0.3f;
[SerializeField] private int pulseCount = 3;
[SerializeField] private float disappearDuration = 0.5f;
[Header("Animation Settings")]
[SerializeField] private float growScale = 1.5f;
[SerializeField] private float pulseScale = 1.2f;
private GameObject glowInstance;
private bool sequencePlaying;
protected override bool DoInteraction()
{
// Let the normal pickup flow happen first
bool success = base.DoInteraction();
// If pickup was successful and we're not already playing the sequence, start it
// IMPORTANT: We start the coroutine on the FollowerController, not on this object,
// because this object gets disabled immediately after pickup
if (success && !sequencePlaying)
{
var follower = FollowerController.FindInstance();
if (follower != null)
{
follower.StartCoroutine(BoosterSequence(follower));
}
else
{
Logging.Warning("[BoosterPackPickup] No follower found, cannot start sequence");
}
}
return success;
}
private IEnumerator BoosterSequence(FollowerController follower)
{
sequencePlaying = true;
// IMPORTANT: Disable all children on the original pickup GameObject
// This prevents glow effects and other child objects from appearing in Pulver's hand
foreach (Transform child in transform)
{
child.gameObject.SetActive(false);
}
// Wait one frame to ensure pickup is fully processed
yield return null;
// Verify follower still exists (safety check)
if (follower == null)
{
Logging.Warning("[BoosterPackPickup] Follower destroyed during sequence, aborting");
sequencePlaying = false;
yield break;
}
Transform heldItemTransform = follower.GetHeldItemTransform();
if (heldItemTransform == null)
{
Logging.Warning("[BoosterPackPickup] No held item transform found, skipping sequence");
sequencePlaying = false;
yield break;
}
// Cache original transform state to restore later
Vector3 originalPosition = heldItemTransform.localPosition;
Vector3 originalScale = heldItemTransform.localScale;
// 1. Pause follower movement
follower.PauseMovement();
// 2. Activate zoom camera if assigned
if (zoomCamera != null)
{
// Unparent the camera from the booster pack (if it's parented)
zoomCamera.transform.SetParent(null);
// Position camera at follower's location
zoomCamera.transform.position = new Vector3(
follower.transform.position.x,
follower.transform.position.y,
zoomCamera.transform.position.z
);
// Make the blend instant by setting a custom blend hint
var brain = Camera.main?.GetComponent();
CinemachineBlendDefinition originalBlend = default;
if (brain != null)
{
originalBlend = brain.DefaultBlend;
brain.DefaultBlend = new CinemachineBlendDefinition(CinemachineBlendDefinition.Styles.EaseInOut, 1);
}
zoomCamera.Priority = 20;
zoomCamera.gameObject.SetActive(true);
// Wait a frame for the cut to take effect
yield return null;
// Restore original blend settings
if (brain != null)
{
brain.DefaultBlend = originalBlend;
}
}
// 3. Grow animation (no glow during this)
Tween.LocalScale(heldItemTransform, originalScale * growScale, growDuration, 0f, Tween.EaseOutBack);
yield return new WaitForSeconds(growDuration);
// 4. Instantiate and pulse glow
if (glowVisualPrefab != null)
{
glowInstance = Instantiate(glowVisualPrefab, heldItemTransform);
glowInstance.transform.localPosition = Vector3.zero;
glowInstance.transform.localScale = Vector3.one;
for (int i = 0; i < pulseCount; i++)
{
Tween.LocalScale(glowInstance.transform, Vector3.one * pulseScale, pulseDuration, 0f, Tween.EaseIn);
yield return new WaitForSeconds(pulseDuration);
Tween.LocalScale(glowInstance.transform, Vector3.one, pulseDuration, 0f, Tween.EaseInOut);
yield return new WaitForSeconds(pulseDuration);
}
// Delete glow before flying to button
Destroy(glowInstance);
glowInstance = null;
}
// 5. Disappear to scrapbook button (backpack icon) - straight line movement
GameObject scrabookButton = PlayerHudManager.Instance?.GetScrabookButton();
if (scrabookButton != null)
{
// Get start position in world space
Vector3 startPos = heldItemTransform.position;
// Convert UI button position to world space
RectTransform buttonRect = scrabookButton.GetComponent();
Vector3 targetWorldPos;
if (buttonRect != null)
{
// UI element - get screen position correctly
Vector3[] corners = new Vector3[4];
buttonRect.GetWorldCorners(corners);
// Get center of the button in screen space
Vector3 buttonCenter = (corners[0] + corners[2]) / 2f;
// For Screen Space Overlay, the corners are already in screen space
Canvas canvas = buttonRect.GetComponentInParent