Fix slot items to fully work with the stashing prefab flow

This commit is contained in:
Michal Pikulski
2025-09-08 16:13:13 +02:00
committed by Michal Pikulski
parent a8d398e097
commit 5804b170d0
7 changed files with 278 additions and 35 deletions

View File

@@ -19,6 +19,45 @@ public class SlotItemBehavior : InteractionRequirementBase
/// </summary>
public SpriteRenderer slottedItemRenderer;
private GameObject _cachedSlottedObject = null;
// Helper for slotting an object, with option to skip destruction (for swap)
private void SetSlottedObject(GameObject obj)
{
_cachedSlottedObject = obj;
if (_cachedSlottedObject != null)
{
_cachedSlottedObject.SetActive(false);
}
}
private void RemoveSlottedObject()
{
if (_cachedSlottedObject != null)
{
Destroy(_cachedSlottedObject);
_cachedSlottedObject = null;
}
}
private void CacheSlottedObject(GameObject obj)
{
// Only destroy if not swapping
RemoveSlottedObject();
SetSlottedObject(obj);
}
private void RestoreSlottedObject(Vector3 position)
{
if (_cachedSlottedObject != null)
{
_cachedSlottedObject.transform.position = position;
_cachedSlottedObject.transform.SetParent(null);
_cachedSlottedObject.SetActive(true);
_cachedSlottedObject = null;
}
}
/// <summary>
/// Attempts to interact with the slot, handling slotting, swapping, or picking up items.
/// </summary>
@@ -27,6 +66,7 @@ public class SlotItemBehavior : InteractionRequirementBase
public override bool TryInteract(FollowerController follower)
{
var heldItem = follower.CurrentlyHeldItem;
var heldObj = follower.GetHeldPickupObject();
var pickup = GetComponent<Pickup>();
var slotItem = pickup != null ? pickup.itemData : null;
var config = GameManager.Instance.GetSlotItemConfig(slotItem);
@@ -34,33 +74,44 @@ public class SlotItemBehavior : InteractionRequirementBase
var forbidden = config?.forbiddenItems ?? new List<PickupItemData>();
// CASE 1: No held item, slot has item -> pick up slotted item
if (heldItem == null && currentlySlottedItem != null)
if (heldItem == null && _cachedSlottedObject != null)
{
follower.SetHeldItem(currentlySlottedItem);
follower.SetHeldItemFromObject(_cachedSlottedObject);
RemoveSlottedObject();
currentlySlottedItem = null;
UpdateSlottedSprite();
return true;
}
// CASE 2: Held item, slot has item -> swap
if (heldItem != null && currentlySlottedItem != null)
if (heldItem != null && _cachedSlottedObject != null)
{
var temp = currentlySlottedItem;
currentlySlottedItem = heldItem;
var followerHeldObj = heldObj;
var followerHeldItem = heldItem;
var slotObj = _cachedSlottedObject;
var slotItemData = currentlySlottedItem;
// 1. Slot the follower's held object (do NOT destroy the old one)
SetSlottedObject(followerHeldObj);
currentlySlottedItem = followerHeldItem;
UpdateSlottedSprite();
follower.SetHeldItem(temp);
// 2. Give the slot's object to the follower
follower.SetHeldItemFromObject(slotObj);
return true;
}
// CASE 3: Held item, slot empty -> slot the held item
if (heldItem != null && currentlySlottedItem == null)
if (heldItem != null && _cachedSlottedObject == null)
{
if (forbidden.Contains(heldItem))
{
DebugUIMessage.Show("Can't place that here.");
return false;
}
CacheSlottedObject(heldObj);
currentlySlottedItem = heldItem;
UpdateSlottedSprite();
follower.SetHeldItem(null);
follower.ClearHeldItem();
if (allowed.Contains(heldItem))
{
OnSuccess?.Invoke();
@@ -74,7 +125,7 @@ public class SlotItemBehavior : InteractionRequirementBase
}
}
// CASE 4: No held item, slot empty -> show warning
if (heldItem == null && currentlySlottedItem == null)
if (heldItem == null && _cachedSlottedObject == null)
{
DebugUIMessage.Show("This requires an item.");
return false;
@@ -110,4 +161,9 @@ public class SlotItemBehavior : InteractionRequirementBase
slottedItemRenderer.sprite = null;
}
}
void Update()
{
Debug.Log($"[SlotItemBehavior] _cachedSlottedObject: {_cachedSlottedObject} (GameObject name: {(_cachedSlottedObject != null ? _cachedSlottedObject.name : "null")})", this);
}
}