585 lines
18 KiB
C#
585 lines
18 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
using Unity.VisualScripting;
|
|
using System.Collections.Generic;
|
|
|
|
public class Node : MonoBehaviour
|
|
{
|
|
#region Variables or objects
|
|
[SerializeField] private GameObject nodeOccupiedView;
|
|
[SerializeField] private GameObject nodeUnoccupiedView;
|
|
[SerializeField] private Material occupiedMat;
|
|
[SerializeField] private Material unOccupiedMat;
|
|
|
|
[SerializeField] private MeshRenderer meshRenderer;
|
|
|
|
[SerializeField] private Transform[] m_NodePlacements;
|
|
[SerializeField] private int totalSlotsInNode = 12;
|
|
[SerializeField] private GameObject gameOverEmoji;
|
|
|
|
private int m_NodePlacementLength = 0;
|
|
public bool isNodeOccupied = false;
|
|
|
|
private NodePlacementData[] m_NodePlacementDatas;
|
|
private List<Vector3> neighborsHexOffsets = new List<Vector3>();
|
|
|
|
#region Dictionaries for item data collection
|
|
|
|
private Dictionary<ItemType, int> goodsSetDict = new Dictionary<ItemType, int>();
|
|
private Dictionary<ItemType, List<ItemBase>> itemBasesCollection = new Dictionary<ItemType, List<ItemBase>>();
|
|
private Dictionary<ItemType, int> cachedGoodsSet = new Dictionary<ItemType, int>();
|
|
private Dictionary<ItemType, List<ItemBase>> cachedItemBases = new Dictionary<ItemType, List<ItemBase>>();
|
|
|
|
#endregion
|
|
|
|
#region Managers
|
|
private NodeManager nodeManager;
|
|
private GoodsManager goodsManager;
|
|
private GoodsSortingManager goodsSortingManager;
|
|
private ObjectPoolManager objectPoolManager;
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Getter methods
|
|
public Dictionary<ItemType, List<ItemBase>> GetItemBasesCollection => itemBasesCollection;
|
|
|
|
public int GetItemTypeCount() => goodsSetDict.Count;
|
|
|
|
public int GetTotalSlotsInNode() => totalSlotsInNode;
|
|
|
|
public bool HasEmptySlots(out int availSlots)
|
|
{
|
|
int totalSlotsOccupied = 0;
|
|
foreach (var set in goodsSetDict)
|
|
{
|
|
totalSlotsOccupied += set.Value;
|
|
}
|
|
|
|
availSlots = totalSlotsInNode - totalSlotsOccupied;
|
|
return availSlots != 0;
|
|
}
|
|
|
|
public bool IsEmpty()
|
|
{
|
|
return !isNodeOccupied;
|
|
}
|
|
|
|
public bool HasCachedData()
|
|
{
|
|
return cachedGoodsSet.Count > 0; // TODO :: Improve the check if req while moving forward
|
|
}
|
|
|
|
public ItemType[] GetCachedKeys()
|
|
{
|
|
return cachedGoodsSet.Keys.ToArray();
|
|
}
|
|
|
|
public int GetCachedData(ItemType matchType) // TODO :: change return type and data to send back here
|
|
{
|
|
return cachedGoodsSet.ContainsKey(matchType) ? cachedGoodsSet[matchType] : 0;
|
|
}
|
|
|
|
public int GetTotalCachedSetsCount()
|
|
{
|
|
int setsCount = 0;
|
|
foreach (var data in cachedGoodsSet)
|
|
setsCount += data.Value;
|
|
|
|
return setsCount;
|
|
}
|
|
|
|
public Dictionary<ItemType, int> GetSetDict() => goodsSetDict;
|
|
|
|
public List<ItemType> GetSetKeys()
|
|
{
|
|
return goodsSetDict.Keys.ToList();
|
|
}
|
|
|
|
public int GetSetKeysCount()
|
|
{
|
|
return goodsSetDict.Keys.Count;
|
|
}
|
|
|
|
public bool HasCachedItemType(ItemType type)
|
|
{
|
|
return cachedItemBases.ContainsKey(type);
|
|
}
|
|
|
|
public List<ItemBase> GetCachedItemBase(ItemType itemType)
|
|
{
|
|
return cachedItemBases[itemType];
|
|
}
|
|
|
|
public bool GetNextKeyAfterCurrent(ItemType currentType, out ItemType itemType)
|
|
{
|
|
Debug.Log($"GetNextKeyAfterCurrent");
|
|
Debug.Log($"goodsSetDict: {goodsSetDict.Count}");
|
|
foreach (var goodSet in goodsSetDict)
|
|
{
|
|
if (goodSet.Key == currentType)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
itemType = goodSet.Key;
|
|
Debug.Log($"currentType: {currentType}, itemType: {itemType}");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
itemType = ItemType.MAX;
|
|
|
|
Debug.Log($"currentType: {currentType}, itemType: {itemType}");
|
|
return false;
|
|
}
|
|
|
|
public int GetItemBaseCount()
|
|
{
|
|
int itemBaseCount = 0;
|
|
foreach (var data in itemBasesCollection)
|
|
itemBaseCount += data.Value.Count;
|
|
|
|
return itemBaseCount;
|
|
}
|
|
|
|
public int GetTotalGoodsSetsCount()
|
|
{
|
|
int setsCount = 0;
|
|
foreach (var data in goodsSetDict)
|
|
setsCount += data.Value;
|
|
|
|
return setsCount;
|
|
}
|
|
|
|
public List<ItemType> GetKeysForItems()
|
|
{
|
|
return itemBasesCollection.Keys.ToList();
|
|
}
|
|
|
|
public int GetSetsCountForItemType(ItemType itemType)
|
|
{
|
|
return itemBasesCollection[itemType].Count;
|
|
}
|
|
|
|
public ItemBase GetItemBase(int index, ItemType itemType)
|
|
{
|
|
return itemBasesCollection[itemType][index];
|
|
}
|
|
|
|
public List<ItemBase> GetSpecificItems(ItemType itemType)
|
|
{
|
|
try
|
|
{
|
|
return itemBasesCollection[itemType];
|
|
// return itemBasesCollection.ContainsKey(itemType) ? itemBasesCollection[itemType] : new List<ItemBase>();
|
|
// return itemBasesCollection.Select(item => item).Where(item => item.ItemType == itemType).ToList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError("Caught exception: " + ex.Message);
|
|
}
|
|
|
|
return new List<ItemBase>();
|
|
}
|
|
|
|
public string GetNodePos() => $"{transform.position}";
|
|
|
|
public int GetNeighborsCount() => neighborsHexOffsets.Count;
|
|
|
|
public int GetNeighborHexOffsetLength() => neighborsHexOffsets.Count;
|
|
|
|
public Vector3 GetNeighborHexOffset(int index)
|
|
{
|
|
return neighborsHexOffsets[index];
|
|
}
|
|
|
|
public int GetGoodsSetCountForSpecificItem(ItemType itemType)
|
|
{
|
|
return goodsSetDict.ContainsKey(itemType) ? goodsSetDict[itemType] : 0;
|
|
}
|
|
|
|
public bool HasCachedDataRef(ItemType[] cachedItemKeys, out ItemType foundKey)
|
|
{
|
|
foundKey = ItemType.MAX;
|
|
foreach (ItemType item in cachedItemKeys)
|
|
{
|
|
if (HasGoodsSet(item))
|
|
{
|
|
foundKey = item;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool HasGoodsSet(ItemType itemType)
|
|
{
|
|
return goodsSetDict.ContainsKey(itemType);
|
|
}
|
|
|
|
public bool IsNodeFilled()
|
|
{
|
|
return !HasEmptySlots(out int availSlots) && goodsSetDict.Count == 1;
|
|
}
|
|
|
|
public bool IsThereDifferentKey(ItemType itemType)
|
|
{
|
|
if (goodsSetDict.Count > 0)
|
|
{
|
|
return itemType != goodsSetDict.Keys.Last();
|
|
return goodsSetDict.Keys.Contains(itemType);
|
|
}
|
|
else
|
|
{
|
|
// Debug.Log($"IsLastKey:: not last key");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public NodePlacementData RetrieveNodePlacementData(int index)
|
|
{
|
|
return m_NodePlacementDatas[index];
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void StoreCachedData(ItemType otherSetItemKey, int cacheCount)
|
|
{
|
|
// store the goods set
|
|
// store the item bases
|
|
if (!cachedGoodsSet.ContainsKey(otherSetItemKey))
|
|
cachedGoodsSet.Add(otherSetItemKey, cacheCount);
|
|
else
|
|
cachedGoodsSet[otherSetItemKey] += cacheCount;
|
|
}
|
|
|
|
public void FreeUpGoodsSet(ItemType otherSetItemKey, int cacheCount)
|
|
{
|
|
if (goodsSetDict.ContainsKey(otherSetItemKey))
|
|
{
|
|
goodsSetDict[otherSetItemKey] -= cacheCount;
|
|
}
|
|
}
|
|
|
|
public void CacheAndStoreItemBases(ItemType otherSetItemKey, int cacheCount)
|
|
{
|
|
if (!cachedItemBases.ContainsKey(otherSetItemKey))
|
|
{
|
|
cachedItemBases.Add(otherSetItemKey, new List<ItemBase>());
|
|
AddToCachedItemBases(otherSetItemKey, cacheCount);
|
|
}
|
|
else
|
|
AddToCachedItemBases(otherSetItemKey, cacheCount);
|
|
}
|
|
|
|
private void AddToCachedItemBases(ItemType otherSetItemKey, int cacheCount)
|
|
{
|
|
for (int indexI = 0; indexI < cacheCount; indexI++)
|
|
{
|
|
cachedItemBases[otherSetItemKey].Add(RemoveFromItemBasesCollection(otherSetItemKey));
|
|
}
|
|
}
|
|
|
|
public void InitNodeManager(NodeManager nodeManager)
|
|
{
|
|
this.nodeManager = nodeManager;
|
|
}
|
|
|
|
public bool CheckIfSetItemMatches(ItemType itemType, out int goodsCount)
|
|
{
|
|
Debug.Log($"JsonData: {JsonConvert.SerializeObject(goodsSetDict)}");
|
|
goodsCount = goodsSetDict.ContainsKey(itemType) ? goodsSetDict[itemType] : 0;
|
|
// Debug.Log($"Test 5: DoesNeighborHaveSimilarItem: itemType: " + itemType + ", goodsCount: " + goodsCount);
|
|
|
|
return goodsSetDict.ContainsKey(itemType);
|
|
}
|
|
|
|
public void InitItemsData()
|
|
{
|
|
goodsManager = goodsManager == null ? InterfaceManager.Instance?.GetInterfaceInstance<GoodsManager>() : goodsManager;
|
|
|
|
var itemBaseObjects = goodsManager.GoodsHandler.CurrentGoodsPlacer.GetBaseObjects();
|
|
foreach (var baseObj in itemBaseObjects)
|
|
AddToItemBasesCollection(baseObj);
|
|
|
|
// foreach (var item in itemBaseObjects)
|
|
// {
|
|
// Debug.Log($"### Test 9: item.Type: {item.ItemType}, item.Value: {item}");
|
|
// }
|
|
|
|
// foreach (var item in itemBasesCollection)
|
|
// {
|
|
// Debug.Log($"### Test 10: item.Type: {item.Key}, item.Value: {item.Value.Count}");
|
|
// }
|
|
|
|
var goodsDataSet = goodsManager.GoodsHandler.CurrentGoodsPlacer.GetGoodsDataSet();
|
|
foreach (var data in goodsDataSet)
|
|
AddItemsDataToNode(data.type, data.setCount);
|
|
|
|
}
|
|
|
|
#region NODE_DATA_UPDATION
|
|
public void AddItemsDataToNode(ItemType itemType, int itemsToAddCount)
|
|
{
|
|
// Debug.Log($"AddItemsDataToNode");
|
|
// foreach (var data in goodsSetDict)
|
|
// {
|
|
// Debug.Log($"GoodsKey: {data.Key}, GoodsCount: {data.Value}");
|
|
// }
|
|
|
|
// Debug.Log($"Before updating goods set");
|
|
// Debug.Log($"number of goods sets: {goodsSetDict.Count}");
|
|
// int itemsCount = goodsSetDict.ContainsKey(itemType) ? goodsSetDict[itemType] : 0;
|
|
// Debug.Log($"number of goods for set({itemType}): {itemsCount}");
|
|
|
|
if (!goodsSetDict.ContainsKey(itemType))
|
|
goodsSetDict.Add(itemType, itemsToAddCount);
|
|
else
|
|
goodsSetDict[itemType] += itemsToAddCount;
|
|
|
|
// Debug.Log($"After updating goods set");
|
|
// Debug.Log($"number of goods sets: {goodsSetDict.Count}");
|
|
// itemsCount = goodsSetDict.ContainsKey(itemType) ? goodsSetDict[itemType] : 0;
|
|
// Debug.Log($"number of goods for set({itemType}): {itemsCount}");
|
|
}
|
|
|
|
public void RemoveItemsDataFromNode(ItemType itemType, int itemsToRemoveCount)
|
|
{
|
|
if (goodsSetDict.ContainsKey(itemType))
|
|
{
|
|
int availCount = goodsSetDict[itemType];
|
|
if (availCount > itemsToRemoveCount)
|
|
{
|
|
availCount -= itemsToRemoveCount;
|
|
goodsSetDict[itemType] = availCount;
|
|
|
|
if (goodsSetDict[itemType] == 0)
|
|
goodsSetDict.Remove(itemType);
|
|
}
|
|
else //if (availCount == itemsToRemoveCount)
|
|
{
|
|
// TODO :: double check condition
|
|
goodsSetDict.Remove(itemType);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SortItemBases()
|
|
{
|
|
var sortedDict = itemBasesCollection.OrderByDescending(pair => pair.Value.Count).ToList();
|
|
itemBasesCollection.Clear();
|
|
goodsSetDict.Clear();
|
|
|
|
foreach (var sortedItem in sortedDict)
|
|
{
|
|
itemBasesCollection.Add(sortedItem.Key, sortedItem.Value);
|
|
goodsSetDict.Add(sortedItem.Key, sortedItem.Value.Count);
|
|
}
|
|
}
|
|
|
|
public void SortItemsData()
|
|
{
|
|
var sortedDict = goodsSetDict.OrderByDescending(pair => pair.Value);
|
|
goodsSetDict.Clear();
|
|
|
|
foreach (var data in sortedDict)
|
|
goodsSetDict.Add(data.Key, data.Value);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ITEMS_UPDATION
|
|
|
|
public void AddToItemBasesCollection(ItemBase baseObj)
|
|
{
|
|
if (!itemBasesCollection.ContainsKey(baseObj.ItemType))
|
|
itemBasesCollection.Add(baseObj.ItemType, new List<ItemBase>() { baseObj });
|
|
else
|
|
itemBasesCollection[baseObj.ItemType].Add(baseObj);
|
|
}
|
|
|
|
public ItemBase RemoveFromItemBasesCollection(ItemType itemType)
|
|
{
|
|
// if (!itemBasesCollection.ContainsKey(itemType) || itemBasesCollection[itemType].Count < 1) return null;
|
|
|
|
Debug.Log($"#### itemBasesCollection: {itemBasesCollection != null}");
|
|
Debug.Log($"ItemToRemove: {itemBasesCollection.Count}");
|
|
ItemBase itemToRemove = itemBasesCollection[itemType][0];
|
|
itemBasesCollection[itemType].RemoveAt(0);
|
|
Debug.Log($"ItemType based count: {itemBasesCollection[itemType].Count}");
|
|
|
|
if (itemBasesCollection[itemType].Count == 0)
|
|
{
|
|
Debug.Log($"Removing item");
|
|
itemBasesCollection.Remove(itemType);
|
|
Debug.Log($"after removal itemBasesCollection: {itemBasesCollection.Count}");
|
|
}
|
|
|
|
return itemToRemove;
|
|
}
|
|
|
|
public void RemoveItemsDataFromCachedData(ItemType cachedKey, int availSlots)
|
|
{
|
|
if (cachedGoodsSet.ContainsKey(cachedKey))
|
|
{
|
|
cachedGoodsSet[cachedKey] -= availSlots;
|
|
if (cachedGoodsSet[cachedKey] == 0)
|
|
cachedGoodsSet.Remove(cachedKey);
|
|
}
|
|
}
|
|
|
|
public ItemBase RemoveAndRetrieveFromCachedItemBases(ItemType itemType)
|
|
{
|
|
ItemBase itemToRemove = cachedItemBases[itemType][0];
|
|
cachedItemBases[itemType].RemoveAt(0);
|
|
|
|
if (cachedItemBases[itemType].Count == 0)
|
|
{
|
|
Debug.Log($"Removing item");
|
|
cachedItemBases.Remove(itemType);
|
|
Debug.Log($"after removal itemBasesCollection: {cachedItemBases.Count}");
|
|
}
|
|
|
|
return itemToRemove;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void AddNeighborsData(Vector3 hexOffset)
|
|
{
|
|
neighborsHexOffsets.Add(hexOffset);
|
|
}
|
|
|
|
public void OnMouseDown()
|
|
{
|
|
if (!isNodeOccupied) // game's not over
|
|
{
|
|
nodeManager.OnNodeClickedOrFound(this);
|
|
}
|
|
else
|
|
{
|
|
nodeManager.OnNodeBeingOccupied(this);
|
|
}
|
|
}
|
|
|
|
public void SetNodeOccupiedState(bool state)
|
|
{
|
|
Debug.Log($"totalOccupiedNodesState({name}): isNodeOccupied: {isNodeOccupied}, state: {state}");
|
|
if (isNodeOccupied == state) return;
|
|
|
|
isNodeOccupied = state;
|
|
meshRenderer.material = isNodeOccupied ? occupiedMat : unOccupiedMat;
|
|
|
|
// nodeManager.UpdateOccupiedNodesCount(state ? 1 : -1);
|
|
nodeOccupiedView.SetActive(isNodeOccupied);
|
|
nodeUnoccupiedView.SetActive(!isNodeOccupied);
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
m_NodePlacementLength = m_NodePlacements.Length;
|
|
m_NodePlacementDatas = new NodePlacementData[m_NodePlacementLength];
|
|
|
|
for (int i = 0; i < m_NodePlacementLength; i++)
|
|
{
|
|
m_NodePlacementDatas[i] = new NodePlacementData();
|
|
m_NodePlacementDatas[i].isOccupied = false;
|
|
m_NodePlacementDatas[i].transform = m_NodePlacements[i];
|
|
}
|
|
}
|
|
|
|
public bool IsNodeFullOrCleared()
|
|
{
|
|
var itemBaseCount = GetItemBaseCount();
|
|
return (itemBasesCollection.Count == 1 && totalSlotsInNode == itemBaseCount) || itemBaseCount == 0;
|
|
}
|
|
|
|
public void CheckIfNodeIsFullOrCleared()
|
|
{
|
|
var itemBaseCount = GetItemBaseCount();
|
|
|
|
Debug.Log($"GameOverCheck :: CheckIfNodeIsFullOrCleared() :: Nodename: {this.name}, itemBaseCount: {itemBaseCount}");
|
|
|
|
if (itemBasesCollection.Count == 1 && totalSlotsInNode == itemBaseCount)
|
|
{
|
|
OnNodeFull();
|
|
|
|
goodsSetDict.Clear();
|
|
itemBasesCollection.Clear();
|
|
SetNodeOccupiedState(false);
|
|
}
|
|
else if (itemBaseCount == 0)
|
|
{
|
|
// goodsSetDict.Clear();
|
|
// itemBasesCollection.Clear();
|
|
SetNodeOccupiedState(false);
|
|
}
|
|
}
|
|
|
|
private void OnNodeFull()
|
|
{
|
|
nodeManager.OnNodeFilled(this, goodsSetDict.First().Key);
|
|
}
|
|
|
|
public void UpdateOccupiedSlotsState()
|
|
{
|
|
var itemsCount = GetItemBaseCount();
|
|
|
|
for (int index = 0; index < totalSlotsInNode; index++)
|
|
{
|
|
m_NodePlacementDatas[index].isOccupied = index < itemsCount;
|
|
}
|
|
}
|
|
|
|
public void UpdateOccupiedNodes()
|
|
{
|
|
var itemsCount = GetItemBaseCount();
|
|
|
|
Debug.Log($"NodeData :: {name} :: itemsCount: {itemsCount}");
|
|
if (itemsCount == 0 || itemsCount == totalSlotsInNode)
|
|
{
|
|
Debug.Log($"NodeData :: remove from occupied nodes list for {name}");
|
|
nodeManager.UpdateOccupiedNodes(toAdd: false, GetNodePos());
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"NodeData :: Updating occupied nodes list for {name}");
|
|
nodeManager.UpdateOccupiedNodes(toAdd: true, GetNodePos());
|
|
}
|
|
}
|
|
|
|
public void ClearOrResetGoodsDataAndView()
|
|
{
|
|
objectPoolManager = objectPoolManager == null ? InterfaceManager.Instance?.GetInterfaceInstance<ObjectPoolManager>() : objectPoolManager;
|
|
goodsSetDict.Clear();
|
|
cachedGoodsSet.Clear();
|
|
|
|
foreach (var pair in itemBasesCollection)
|
|
{
|
|
foreach (var itemBase in itemBasesCollection[pair.Key])
|
|
{
|
|
objectPoolManager.PassObjectToPool<ItemBase>($"{pair.Key}", PoolType.Item, itemBase);
|
|
itemBase.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
itemBasesCollection.Clear();
|
|
cachedItemBases.Clear();
|
|
|
|
SetNodeOccupiedState(state: false);
|
|
UpdateOccupiedSlotsState();
|
|
UpdateOccupiedNodes();
|
|
}
|
|
|
|
public void SetGameOverEmoji(bool state)
|
|
{
|
|
gameOverEmoji.SetActive(state);
|
|
}
|
|
}
|