[Player][Interaction][Assets] Add placeholder assets for some more sprites. Move all to External/Placeholder. Add list of assets with attributions. Pulver combines items now

This commit is contained in:
Michal Pikulski
2025-09-04 13:08:14 +02:00
parent 496ef10b8b
commit da5d2f2545
60 changed files with 3245 additions and 15 deletions

View File

@@ -0,0 +1,40 @@
using UnityEngine;
[RequireComponent(typeof(Pickup))]
public class CombineWithBehavior : InteractionRequirementBase
{
public override bool TryInteract(FollowerController follower)
{
var heldItem = follower.currentlyHeldItem;
var pickup = GetComponent<Pickup>();
if (heldItem == null)
{
DebugUIMessage.Show("You need an item to combine.");
OnFailure?.Invoke();
return false;
}
if (pickup == null || pickup.itemData == null)
{
DebugUIMessage.Show("Target item is missing or invalid.");
OnFailure?.Invoke();
return false;
}
var rule = GameManager.Instance.GetCombinationRule(heldItem, pickup.itemData);
if (rule != null && rule.result != null)
{
// Remove both items and add result to follower's inventory
follower.SetHeldItem(rule.result);
follower.justCombined = true;
OnSuccess?.Invoke();
return true;
}
else
{
string heldName = heldItem.itemName ?? "an item";
string targetName = pickup.itemData.itemName ?? "target item";
DebugUIMessage.Show($"Cannot combine {heldName} with {targetName}.");
OnFailure?.Invoke();
return false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 21401a3b30134380bb205964d9e5c67d
timeCreated: 1756981777

View File

@@ -39,6 +39,10 @@ public class FollowerController : MonoBehaviour
public event FollowerPickupHandler OnPickupReturned;
private Coroutine pickupCoroutine;
private bool lastInteractionSuccess = true;
public bool justCombined = false;
void Awake()
{
aiPath = GetComponent<AIPath>();
@@ -242,6 +246,11 @@ public class FollowerController : MonoBehaviour
}
}
public void SetInteractionResult(bool success)
{
lastInteractionSuccess = success;
}
private System.Collections.IEnumerator PickupSequence(Vector2 itemPosition, Transform playerTransform)
{
isManualFollowing = false;
@@ -258,8 +267,8 @@ public class FollowerController : MonoBehaviour
yield return null;
}
OnPickupArrived?.Invoke();
// Swap held item if necessary, then set held item and destroy pickup
if (heldObjectRenderer != null)
// Only perform pickup/swap logic if interaction succeeded
if (lastInteractionSuccess && heldObjectRenderer != null)
{
Collider2D[] hits = Physics2D.OverlapCircleAll(itemPosition, 0.2f);
foreach (var hit in hits)
@@ -267,6 +276,13 @@ public class FollowerController : MonoBehaviour
var pickup = hit.GetComponent<Pickup>();
if (pickup != null)
{
if (justCombined)
{
// Combination: just destroy the pickup, don't spawn anything
GameObject.Destroy(pickup.gameObject);
justCombined = false;
break;
}
// Swap logic: if holding an item, drop it here
if (currentlyHeldItem != null)
{

View File

@@ -44,5 +44,18 @@ public class GameManager : MonoBehaviour
public float FollowerSpeedMultiplier => gameSettings != null ? gameSettings.followerSpeedMultiplier : 1.2f;
public float HeldIconDisplayHeight => gameSettings != null ? gameSettings.heldIconDisplayHeight : 2.0f;
public GameObject BasePickupPrefab => gameSettings != null ? gameSettings.basePickupPrefab : null;
public GameSettings.CombinationRule GetCombinationRule(PickupItemData item1, PickupItemData item2)
{
if (gameSettings == null || gameSettings.combinationRules == null) return null;
foreach (var rule in gameSettings.combinationRules)
{
if ((rule.itemA == item1 && rule.itemB == item2) || (rule.itemA == item2 && rule.itemB == item1))
{
return rule;
}
}
return null;
}
// Add more accessors as needed
}

View File

@@ -28,6 +28,16 @@ public class GameSettings : ScriptableObject
[Header("Default Prefabs")]
public GameObject basePickupPrefab;
[System.Serializable]
public class CombinationRule {
public PickupItemData itemA;
public PickupItemData itemB;
public PickupItemData result;
}
[Header("Combination Rules")]
public System.Collections.Generic.List<CombinationRule> combinationRules;
// Singleton pattern
private static GameSettings _instance;
public static GameSettings Instance {

View File

@@ -29,4 +29,30 @@ public class Interactable : MonoBehaviour, ITouchInputConsumer
{
// Optionally handle drag/move here
}
// Called when the follower arrives at this interactable
public bool OnFollowerArrived(FollowerController follower)
{
var requirements = GetComponents<InteractionRequirementBase>();
if (requirements.Length == 0)
{
// No requirements: allow default pickup
return true;
}
bool anySuccess = false;
foreach (var req in requirements)
{
if (req.TryInteract(follower))
{
anySuccess = true;
break;
}
}
if (!anySuccess)
{
Debug.Log($"[Interactable] No interaction requirements succeeded for {gameObject.name}");
// Optionally trigger a default failure event or feedback here
}
return anySuccess;
}
}

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using UnityEngine.Events;
public abstract class InteractionRequirementBase : MonoBehaviour
{
[Header("Events")]
public UnityEvent OnSuccess;
public UnityEvent OnFailure;
public abstract bool TryInteract(FollowerController follower);
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f2b7dc7a0fd74f3387095faa9f9dbb32
timeCreated: 1756981728

View File

@@ -112,6 +112,12 @@ public class Pickup : MonoBehaviour
void OnFollowerArrived()
{
followerController.OnPickupArrived -= OnFollowerArrived;
bool interactionSuccess = true;
if (interactable != null)
{
interactionSuccess = interactable.OnFollowerArrived(followerController);
}
followerController.SetInteractionResult(interactionSuccess);
}
void OnFollowerReturned()
{

View File

@@ -0,0 +1,33 @@
using UnityEngine;
[RequireComponent(typeof(Interactable))]
public class RequiresItemBehavior : InteractionRequirementBase
{
[Header("Required Item")]
public PickupItemData requiredItem;
public override bool TryInteract(FollowerController follower)
{
var heldItem = follower.currentlyHeldItem;
if (heldItem == requiredItem)
{
OnSuccess?.Invoke();
return true;
}
else
{
string requiredName = requiredItem != null ? requiredItem.itemName : "required item";
if (heldItem == null)
{
DebugUIMessage.Show($"You need {requiredName} to interact.");
}
else
{
string heldName = heldItem.itemName ?? "an item";
DebugUIMessage.Show($"You need {requiredName}, but you are holding {heldName}.");
}
OnFailure?.Invoke();
return false;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 31103d67032c44a9b95ec014babe2c62
timeCreated: 1756981777