165 lines
6.4 KiB
C#
165 lines
6.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace Interactions
|
|
{
|
|
/// <summary>
|
|
/// Interaction requirement that allows slotting, swapping, or picking up items in a slot.
|
|
/// </summary>
|
|
[RequireComponent(typeof(Interactable))]
|
|
public class ItemSlot : Pickup
|
|
{
|
|
public UnityEvent onItemSlotted;
|
|
public UnityEvent onItemSlotRemoved;
|
|
public UnityEvent onCorrectItemSlotted;
|
|
public UnityEvent onIncorrectItemSlotted;
|
|
public UnityEvent onForbiddenItemSlotted;
|
|
private PickupItemData _currentlySlottedItemData;
|
|
public SpriteRenderer slottedItemRenderer;
|
|
private GameObject _currentlySlottedItemObject = null;
|
|
|
|
public GameObject GetSlottedObject()
|
|
{
|
|
return _currentlySlottedItemObject;
|
|
}
|
|
|
|
public void SetSlottedObject(GameObject obj)
|
|
{
|
|
_currentlySlottedItemObject = obj;
|
|
if (_currentlySlottedItemObject != null)
|
|
{
|
|
_currentlySlottedItemObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
protected override void OnCharacterArrived()
|
|
{
|
|
var heldItemData = FollowerController.CurrentlyHeldItemData;
|
|
var heldItemObj = FollowerController.GetHeldPickupObject();
|
|
var config = GameManager.Instance.GetSlotItemConfig(itemData);
|
|
var forbidden = config?.forbiddenItems ?? new List<PickupItemData>();
|
|
|
|
// Held item, slot empty -> try to slot item
|
|
if (heldItemData != null && _currentlySlottedItemObject == null)
|
|
{
|
|
// First check for forbidden items at the very start so we don't continue unnecessarily
|
|
if (forbidden.Contains(heldItemData))
|
|
{
|
|
DebugUIMessage.Show("Can't place that here.", Color.red);
|
|
onForbiddenItemSlotted?.Invoke();
|
|
Interactable.BroadcastInteractionComplete(false);
|
|
return;
|
|
}
|
|
|
|
SlotItem(heldItemObj, heldItemData, true);
|
|
return;
|
|
}
|
|
|
|
// Either pickup or swap items
|
|
if ((heldItemData == null && _currentlySlottedItemObject != null)
|
|
|| (heldItemData != null && _currentlySlottedItemObject != null))
|
|
{
|
|
FollowerController.TryPickupItem(_currentlySlottedItemObject, _currentlySlottedItemData, false);
|
|
onItemSlotRemoved?.Invoke();
|
|
SlotItem(heldItemObj, heldItemData, _currentlySlottedItemObject == null);
|
|
return;
|
|
}
|
|
|
|
// No held item, slot empty -> show warning
|
|
if (heldItemData == null && _currentlySlottedItemObject == null)
|
|
{
|
|
DebugUIMessage.Show("This requires an item.", Color.red);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the sprite and scale for the currently slotted item.
|
|
/// </summary>
|
|
private void UpdateSlottedSprite()
|
|
{
|
|
if (slottedItemRenderer != null && _currentlySlottedItemData != null && _currentlySlottedItemData.mapSprite != null)
|
|
{
|
|
slottedItemRenderer.sprite = _currentlySlottedItemData.mapSprite;
|
|
// Scale sprite to desired height, preserve aspect ratio, compensate for parent scale
|
|
float desiredHeight = GameManager.Instance.HeldIconDisplayHeight;
|
|
var sprite = _currentlySlottedItemData.mapSprite;
|
|
float spriteHeight = sprite.bounds.size.y;
|
|
float spriteWidth = sprite.bounds.size.x;
|
|
Vector3 parentScale = slottedItemRenderer.transform.parent != null
|
|
? slottedItemRenderer.transform.parent.localScale
|
|
: Vector3.one;
|
|
if (spriteHeight > 0f)
|
|
{
|
|
float uniformScale = desiredHeight / spriteHeight;
|
|
float scale = uniformScale / Mathf.Max(parentScale.x, parentScale.y);
|
|
slottedItemRenderer.transform.localScale = new Vector3(scale, scale, 1f);
|
|
}
|
|
}
|
|
else if (slottedItemRenderer != null)
|
|
{
|
|
slottedItemRenderer.sprite = null;
|
|
}
|
|
}
|
|
|
|
public void SlotItem(GameObject itemToSlot, PickupItemData itemToSlotData, bool clearFollowerHeldItem = true)
|
|
{
|
|
if (itemToSlot == null)
|
|
{
|
|
_currentlySlottedItemObject = null;
|
|
_currentlySlottedItemData = null;
|
|
}
|
|
else
|
|
{
|
|
itemToSlot.SetActive(false);
|
|
itemToSlot.transform.SetParent(null);
|
|
SetSlottedObject(itemToSlot);
|
|
_currentlySlottedItemData = itemToSlotData;
|
|
}
|
|
if (clearFollowerHeldItem)
|
|
{
|
|
FollowerController.ClearHeldItem();
|
|
}
|
|
UpdateSlottedSprite();
|
|
|
|
// Once an item is slotted, we know it is not forbidden, so we can skip that check, but now check if it was
|
|
// the correct item we're looking for
|
|
var config = GameManager.Instance.GetSlotItemConfig(itemData);
|
|
var allowed = config?.allowedItems ?? new List<PickupItemData>();
|
|
if (allowed.Contains(itemToSlotData))
|
|
{
|
|
if (itemToSlot != null)
|
|
{
|
|
DebugUIMessage.Show("You correctly slotted " + itemToSlotData.itemName + " into: " + itemData.itemName, Color.green);
|
|
onCorrectItemSlotted?.Invoke();
|
|
}
|
|
|
|
Interactable.BroadcastInteractionComplete(true);
|
|
}
|
|
else
|
|
{
|
|
|
|
if (itemToSlot != null)
|
|
{
|
|
DebugUIMessage.Show("I'm not sure this works.", Color.yellow);
|
|
onIncorrectItemSlotted?.Invoke();
|
|
}
|
|
Interactable.BroadcastInteractionComplete(false);
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_currentlySlottedItemObject != null)
|
|
{
|
|
Debug.Log($"[ItemSlot] Slotted item: {_currentlySlottedItemObject.name}");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("[ItemSlot] No item slotted.");
|
|
}
|
|
}
|
|
}
|
|
}
|