2024-06-03 18:26:03 +00:00
|
|
|
using System.Collections.Generic;
|
2024-06-28 15:35:10 +00:00
|
|
|
using System.Linq;
|
2024-06-03 18:26:03 +00:00
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
namespace BlueWater.Items
|
|
|
|
{
|
|
|
|
public class ItemManager : Singleton<ItemManager>
|
|
|
|
{
|
|
|
|
[SerializeField, Required]
|
2024-06-21 22:11:53 +00:00
|
|
|
private Item _defaultItemPrefab;
|
2024-06-03 18:26:03 +00:00
|
|
|
|
|
|
|
[SerializeField, Required]
|
|
|
|
private ItemDataSo _itemDataSo;
|
2024-08-22 10:39:15 +00:00
|
|
|
private Dictionary<string, ItemData> _itemDataDictionary;
|
2024-06-03 18:26:03 +00:00
|
|
|
|
|
|
|
[SerializeField, Required]
|
|
|
|
private ItemDropTableSo _itemDropTableSo;
|
2024-08-22 10:39:15 +00:00
|
|
|
private Dictionary<string, ItemDropTable> _itemDropTableDictionary;
|
2024-07-10 00:22:34 +00:00
|
|
|
|
2024-07-15 16:20:39 +00:00
|
|
|
[SerializeField, Required]
|
|
|
|
private FoodDataSo _foodDataSo;
|
2024-08-22 10:39:15 +00:00
|
|
|
private Dictionary<string, FoodData> _foodDataDictionary;
|
2024-07-15 16:20:39 +00:00
|
|
|
|
2024-07-10 00:22:34 +00:00
|
|
|
[field: SerializeField, Required]
|
|
|
|
public ItemSlotDataSo ItemSlotDataSo { get; private set; }
|
2024-06-28 15:35:10 +00:00
|
|
|
|
|
|
|
[Title("드롭 아이템 설정")]
|
|
|
|
[SerializeField]
|
|
|
|
private float _randomDropRadius = 3f;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private float _minSeparationDistance = 1.5f;
|
|
|
|
|
|
|
|
private const int MaxAttempts = 1000;
|
2024-06-03 18:26:03 +00:00
|
|
|
|
|
|
|
protected override void OnAwake()
|
|
|
|
{
|
|
|
|
base.OnAwake();
|
|
|
|
|
|
|
|
Initialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void Initialize()
|
|
|
|
{
|
2024-08-22 10:39:15 +00:00
|
|
|
_itemDataDictionary = new Dictionary<string, ItemData>(_itemDataSo.ItemDataList.Count);
|
2024-06-03 18:26:03 +00:00
|
|
|
foreach (var element in _itemDataSo.ItemDataList)
|
|
|
|
{
|
2024-07-15 16:20:39 +00:00
|
|
|
_itemDataDictionary.TryAdd(element.Idx, element);
|
2024-06-03 18:26:03 +00:00
|
|
|
}
|
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
_itemDropTableDictionary = new Dictionary<string, ItemDropTable>(_itemDropTableSo.ItemDropTables.Count);
|
2024-06-21 22:11:53 +00:00
|
|
|
foreach (var element in _itemDropTableSo.ItemDropTables)
|
2024-06-03 18:26:03 +00:00
|
|
|
{
|
2024-06-21 22:11:53 +00:00
|
|
|
_itemDropTableDictionary.TryAdd(element.CharacterData.CharacterIdx, element);
|
2024-06-03 18:26:03 +00:00
|
|
|
}
|
2024-07-15 16:20:39 +00:00
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
_foodDataDictionary = new Dictionary<string, FoodData>(_foodDataSo.FoodDatas.Count);
|
2024-07-15 16:20:39 +00:00
|
|
|
foreach (var element in _foodDataSo.FoodDatas)
|
|
|
|
{
|
|
|
|
_foodDataDictionary.TryAdd(element.Idx, element);
|
|
|
|
}
|
2024-06-03 18:26:03 +00:00
|
|
|
}
|
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
public void ItemDropRandomPosition(string idx, Vector3 dropPosition, float randomDropRadius = float.PositiveInfinity)
|
2024-06-03 18:26:03 +00:00
|
|
|
{
|
2024-06-21 22:11:53 +00:00
|
|
|
var itemDropTable = GetItemDropTableByIdx(idx);
|
|
|
|
if (itemDropTable == null) return;
|
|
|
|
|
2024-06-03 18:26:03 +00:00
|
|
|
var droppedItemList = itemDropTable.GetDroppedItemList();
|
2024-06-28 15:35:10 +00:00
|
|
|
var droppedPositions = new List<Vector3>();
|
2024-06-03 18:26:03 +00:00
|
|
|
foreach (var element in droppedItemList)
|
|
|
|
{
|
2024-06-28 15:35:10 +00:00
|
|
|
Vector3 newDropPosition;
|
|
|
|
var attempts = 0;
|
|
|
|
do
|
|
|
|
{
|
2024-06-29 15:59:31 +00:00
|
|
|
var radius = float.IsPositiveInfinity(randomDropRadius) ? _randomDropRadius : randomDropRadius;
|
2024-06-28 15:35:10 +00:00
|
|
|
attempts++;
|
2024-06-29 15:59:31 +00:00
|
|
|
var newDropPositionX = Random.Range(dropPosition.x - radius, dropPosition.x + radius);
|
|
|
|
var newDropPositionZ = Random.Range(dropPosition.z - radius, dropPosition.z + radius);
|
2024-06-28 15:35:10 +00:00
|
|
|
newDropPosition = new Vector3(newDropPositionX, dropPosition.y, newDropPositionZ);
|
|
|
|
} while (!IsDropPositionAvailable(newDropPosition, droppedPositions) && attempts < MaxAttempts);
|
2024-06-21 22:11:53 +00:00
|
|
|
|
2024-06-28 15:35:10 +00:00
|
|
|
droppedPositions.Add(newDropPosition);
|
|
|
|
|
2024-07-15 16:20:39 +00:00
|
|
|
var itemPrefab = _itemDataDictionary[element.Idx].ItemPrefab;
|
2024-06-21 22:11:53 +00:00
|
|
|
if (!itemPrefab)
|
|
|
|
{
|
|
|
|
itemPrefab = _defaultItemPrefab;
|
|
|
|
}
|
2024-07-02 18:27:56 +00:00
|
|
|
|
2024-07-02 18:48:11 +00:00
|
|
|
var instantiateItem = Instantiate(itemPrefab, dropPosition, itemPrefab.transform.rotation);
|
|
|
|
instantiateItem.Initialize(element);
|
|
|
|
|
|
|
|
var pushPower = Vector3.up * 30f + (newDropPosition - dropPosition) * 10f;
|
|
|
|
instantiateItem.AddForce(pushPower, ForceMode.Impulse);
|
2024-06-03 18:26:03 +00:00
|
|
|
}
|
|
|
|
}
|
2024-06-18 18:16:19 +00:00
|
|
|
|
2024-06-28 15:35:10 +00:00
|
|
|
private bool IsDropPositionAvailable(Vector3 position, List<Vector3> positions)
|
|
|
|
{
|
|
|
|
return positions.Any(pos => Vector3.Distance(position, pos) > _minSeparationDistance);
|
|
|
|
}
|
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
public ItemData GetItemDataByIdx(string idx)
|
2024-06-18 18:16:19 +00:00
|
|
|
{
|
2024-07-15 16:20:39 +00:00
|
|
|
if (_itemDataDictionary.TryGetValue(idx, out var itemData)) return itemData;
|
2024-06-21 22:11:53 +00:00
|
|
|
|
|
|
|
Debug.LogError($"{idx}와 일치하는 아이템이 없습니다.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
public ItemDropTable GetItemDropTableByIdx(string idx)
|
2024-06-21 22:11:53 +00:00
|
|
|
{
|
2024-08-22 10:39:15 +00:00
|
|
|
if (string.IsNullOrEmpty(idx))
|
2024-06-21 22:11:53 +00:00
|
|
|
{
|
|
|
|
Debug.Log("ItemDropTable이 비어있습니다.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_itemDropTableDictionary.TryGetValue(idx, out var itemDropTable)) return itemDropTable;
|
2024-06-18 18:16:19 +00:00
|
|
|
|
|
|
|
Debug.LogError($"{idx}와 일치하는 아이템이 없습니다.");
|
|
|
|
return null;
|
|
|
|
}
|
2024-07-15 16:20:39 +00:00
|
|
|
|
2024-08-22 10:39:15 +00:00
|
|
|
public FoodData GetFoodDataByIdx(string idx)
|
2024-07-15 16:20:39 +00:00
|
|
|
{
|
|
|
|
if (_foodDataDictionary.TryGetValue(idx, out var foodData)) return foodData;
|
|
|
|
|
|
|
|
Debug.LogError($"{idx}와 일치하는 아이템이 없습니다.");
|
|
|
|
return null;
|
|
|
|
}
|
2024-06-03 18:26:03 +00:00
|
|
|
}
|
|
|
|
}
|