Interactables fully working now

This commit is contained in:
Michal Pikulski
2025-09-10 17:38:03 +02:00
parent 0ef25f265c
commit 3a40d1a151
8 changed files with 101 additions and 109 deletions

View File

@@ -13,7 +13,7 @@ public class CombineWithBehavior : InteractionRequirementBase
/// <returns>True if the combination was successful, false otherwise.</returns>
public override bool TryInteract(FollowerController follower)
{
var heldItem = follower.CurrentlyHeldItem;
var heldItem = follower.GetHeldPickupObject();
var pickup = GetComponent<Pickup>();
if (heldItem == null)
{
@@ -27,36 +27,17 @@ public class CombineWithBehavior : InteractionRequirementBase
OnFailure?.Invoke();
return false;
}
var rule = GameManager.Instance.GetCombinationRule(heldItem, pickup.itemData);
if (rule != null && rule.resultPrefab != null)
var combinedItem = InteractionOrchestrator.Instance.CombineItems(heldItem, pickup.gameObject);
if (combinedItem != null)
{
// Instantiate the result prefab at the pickup's position
var resultObj = GameObject.Instantiate(rule.resultPrefab, pickup.transform.position, Quaternion.identity);
var resultPickup = resultObj.GetComponent<Pickup>();
if (resultPickup != null)
{
// Hide and parent to follower
resultObj.SetActive(false);
resultObj.transform.SetParent(follower.transform);
// Set held item and icon from the spawned prefab
follower.SetHeldItem(resultPickup.itemData, resultPickup.iconRenderer);
// Cache the spawned object as the held item
follower.CacheHeldPickupObject(resultObj);
follower.justCombined = true;
OnSuccess?.Invoke();
return true;
}
else
{
Debug.LogWarning("Result prefab does not have a Pickup component.");
GameObject.Destroy(resultObj);
OnFailure?.Invoke();
return false;
}
InteractionOrchestrator.Instance.PickupItem(follower, combinedItem);
follower.justCombined = true;
OnSuccess?.Invoke();
return true;
}
else
{
// DebugUIMessage.Show($"Cannot combine {heldItem.itemName ?? \"an item\"} with {pickup.itemData.itemName ?? \"target item\"}.");
// DebugUIMessage.Show($"Cannot combine {follower.CurrentlyHeldItem?.itemName ?? "an item"} with {pickup.itemData.itemName ?? "target item"}.");
OnFailure?.Invoke();
return true;
}

View File

@@ -151,4 +151,68 @@ public class InteractionOrchestrator : MonoBehaviour
interactable.CompleteInteraction(false);
}
}
// --- ITEM MANAGEMENT API ---
public void PickupItem(FollowerController follower, GameObject item)
{
if (item == null || follower == null) return;
item.SetActive(false);
item.transform.SetParent(null);
follower.SetHeldItemFromObject(item);
// Optionally: fire event, update UI, etc.
}
public void DropItem(FollowerController follower, Vector3 position)
{
var item = follower.GetHeldPickupObject();
if (item == null) return;
item.transform.position = position;
item.transform.SetParent(null);
item.SetActive(true);
follower.ClearHeldItem();
// Optionally: fire event, update UI, etc.
}
public void SlotItem(SlotItemBehavior slot, GameObject item)
{
if (slot == null || item == null) return;
item.SetActive(false);
item.transform.SetParent(null);
slot.SetSlottedObject(item);
// Optionally: update visuals, fire event, etc.
}
public void SwapItems(FollowerController follower, SlotItemBehavior slot)
{
var heldObj = follower.GetHeldPickupObject();
var slotObj = slot.GetSlottedObject();
// 1. Slot the follower's held object
SlotItem(slot, heldObj);
// 2. Give the slot's object to the follower
PickupItem(follower, slotObj);
}
public GameObject CombineItems(GameObject itemA, GameObject itemB)
{
if (itemA == null || itemB == null) return null;
var pickupA = itemA.GetComponent<Pickup>();
var pickupB = itemB.GetComponent<Pickup>();
if (pickupA == null || pickupB == null) {
if (itemA != null) Destroy(itemA);
if (itemB != null) Destroy(itemB);
return null;
}
var rule = GameManager.Instance.GetCombinationRule(pickupA.itemData, pickupB.itemData);
Vector3 spawnPos = itemA.transform.position;
if (rule != null && rule.resultPrefab != null) {
var newItem = Instantiate(rule.resultPrefab, spawnPos, Quaternion.identity);
Destroy(itemA);
Destroy(itemB);
return newItem;
}
// If no combination found, just destroy both
Destroy(itemA);
Destroy(itemB);
return null;
}
}

View File

@@ -21,8 +21,12 @@ public class SlotItemBehavior : InteractionRequirementBase
private GameObject _cachedSlottedObject = null;
// Helper for slotting an object, with option to skip destruction (for swap)
private void SetSlottedObject(GameObject obj)
public GameObject GetSlottedObject()
{
return _cachedSlottedObject;
}
public void SetSlottedObject(GameObject obj)
{
_cachedSlottedObject = obj;
if (_cachedSlottedObject != null)
@@ -31,32 +35,6 @@ public class SlotItemBehavior : InteractionRequirementBase
}
}
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()
{
if (_cachedSlottedObject != null)
{
_cachedSlottedObject.transform.SetParent(null);
// Do NOT activate or move the object here; it stays hidden until dropped
// Activation is handled by the drop logic elsewhere
}
}
/// <summary>
/// Attempts to interact with the slot, handling slotting, swapping, or picking up items.
/// </summary>
@@ -75,9 +53,7 @@ public class SlotItemBehavior : InteractionRequirementBase
// CASE 1: No held item, slot has item -> pick up slotted item
if (heldItem == null && _cachedSlottedObject != null)
{
// Give the hidden slotted object to the follower (do NOT activate or move it)
RestoreSlottedObject();
follower.SetHeldItemFromObject(_cachedSlottedObject);
InteractionOrchestrator.Instance.PickupItem(follower, _cachedSlottedObject);
_cachedSlottedObject = null;
currentlySlottedItem = null;
UpdateSlottedSprite();
@@ -86,20 +62,9 @@ public class SlotItemBehavior : InteractionRequirementBase
// CASE 2: Held item, slot has item -> swap
if (heldItem != null && _cachedSlottedObject != null)
{
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;
InteractionOrchestrator.Instance.SwapItems(follower, this);
currentlySlottedItem = heldItem;
UpdateSlottedSprite();
// 2. Give the slot's object to the follower (do NOT activate or move it)
RestoreSlottedObject();
follower.SetHeldItemFromObject(slotObj);
return true;
}
// CASE 3: Held item, slot empty -> slot the held item
@@ -110,7 +75,7 @@ public class SlotItemBehavior : InteractionRequirementBase
DebugUIMessage.Show("Can't place that here.");
return false;
}
CacheSlottedObject(heldObj);
InteractionOrchestrator.Instance.SlotItem(this, heldObj);
currentlySlottedItem = heldItem;
UpdateSlottedSprite();
follower.ClearHeldItem();