159 lines
5.6 KiB
C#
159 lines
5.6 KiB
C#
using Input;
|
|
using UnityEngine;
|
|
using System; // added for Action<T>
|
|
using Core; // register with ItemManager
|
|
|
|
namespace Interactions
|
|
{
|
|
[RequireComponent(typeof(Interactable))]
|
|
public class Pickup : MonoBehaviour
|
|
{
|
|
public PickupItemData itemData;
|
|
public SpriteRenderer iconRenderer;
|
|
protected Interactable Interactable;
|
|
private PlayerTouchController _playerRef;
|
|
protected FollowerController FollowerController;
|
|
|
|
// Track if the item has been picked up
|
|
public bool isPickedUp { get; private set; }
|
|
|
|
// Event: invoked when the item was picked up successfully
|
|
public event Action<PickupItemData> OnItemPickedUp;
|
|
|
|
// Event: invoked when this item is successfully combined with another
|
|
public event Action<PickupItemData, PickupItemData, PickupItemData> OnItemsCombined;
|
|
|
|
/// <summary>
|
|
/// Unity Awake callback. Sets up icon, interactable, and event handlers.
|
|
/// </summary>
|
|
void Awake()
|
|
{
|
|
if (iconRenderer == null)
|
|
iconRenderer = GetComponent<SpriteRenderer>();
|
|
|
|
Interactable = GetComponent<Interactable>();
|
|
if (Interactable != null)
|
|
{
|
|
Interactable.interactionStarted.AddListener(OnInteractionStarted);
|
|
Interactable.characterArrived.AddListener(OnCharacterArrived);
|
|
}
|
|
|
|
ApplyItemData();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register with ItemManager on Start
|
|
/// </summary>
|
|
void Start()
|
|
{
|
|
ItemManager.Instance?.RegisterPickup(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unity OnDestroy callback. Cleans up event handlers.
|
|
/// </summary>
|
|
void OnDestroy()
|
|
{
|
|
if (Interactable != null)
|
|
{
|
|
Interactable.interactionStarted.RemoveListener(OnInteractionStarted);
|
|
Interactable.characterArrived.RemoveListener(OnCharacterArrived);
|
|
}
|
|
|
|
// Unregister from ItemManager
|
|
ItemManager.Instance?.UnregisterPickup(this);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
|
/// Unity OnValidate callback. Ensures icon and data are up to date in editor.
|
|
/// </summary>
|
|
void OnValidate()
|
|
{
|
|
if (iconRenderer == null)
|
|
iconRenderer = GetComponent<SpriteRenderer>();
|
|
ApplyItemData();
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Applies the item data to the pickup (icon, name, etc).
|
|
/// </summary>
|
|
public void ApplyItemData()
|
|
{
|
|
if (itemData != null)
|
|
{
|
|
if (iconRenderer != null && itemData.mapSprite != null)
|
|
{
|
|
iconRenderer.sprite = itemData.mapSprite;
|
|
}
|
|
|
|
gameObject.name = itemData.itemName;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles the start of an interaction (for feedback/UI only).
|
|
/// </summary>
|
|
private void OnInteractionStarted(PlayerTouchController playerRef, FollowerController followerRef)
|
|
{
|
|
_playerRef = playerRef;
|
|
FollowerController = followerRef;
|
|
}
|
|
|
|
protected virtual void OnCharacterArrived()
|
|
{
|
|
Debug.Log("[Pickup] OnCharacterArrived");
|
|
|
|
var combinationResult = FollowerController.TryCombineItems(this, out var combinationResultItem);
|
|
if (combinationResultItem != null)
|
|
{
|
|
Interactable.BroadcastInteractionComplete(true);
|
|
|
|
// Fire the combination event when items are successfully combined
|
|
if (combinationResult == FollowerController.CombinationResult.Successful)
|
|
{
|
|
var resultPickup = combinationResultItem.GetComponent<Pickup>();
|
|
if (resultPickup != null && resultPickup.itemData != null)
|
|
{
|
|
// Get the combined item data
|
|
var resultItemData = resultPickup.itemData;
|
|
var heldItem = FollowerController.GetHeldPickupObject();
|
|
|
|
if (heldItem != null)
|
|
{
|
|
var heldPickup = heldItem.GetComponent<Pickup>();
|
|
if (heldPickup != null && heldPickup.itemData != null)
|
|
{
|
|
// Trigger the combination event
|
|
OnItemsCombined?.Invoke(itemData, heldPickup.itemData, resultItemData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
FollowerController?.TryPickupItem(gameObject, itemData);
|
|
|
|
var step = GetComponent<PuzzleS.ObjectiveStepBehaviour>();
|
|
if (step != null && !step.IsStepUnlocked())
|
|
{
|
|
Interactable.BroadcastInteractionComplete(false);
|
|
return;
|
|
}
|
|
|
|
bool wasPickedUp = (combinationResult == FollowerController.CombinationResult.NotApplicable
|
|
|| combinationResult == FollowerController.CombinationResult.Unsuccessful);
|
|
Interactable.BroadcastInteractionComplete(wasPickedUp);
|
|
|
|
// Update pickup state and invoke event when the item was picked up successfully
|
|
if (wasPickedUp)
|
|
{
|
|
isPickedUp = true;
|
|
OnItemPickedUp?.Invoke(itemData);
|
|
}
|
|
}
|
|
}
|
|
} |