You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.3 KiB
166 lines
5.3 KiB
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using UnityEngine;
|
|
|
|
#if UNITY_EDITOR
|
|
public partial class MateMgr : Singleton<MateMgr>
|
|
#else
|
|
public class MateMgr : Singleton<MateMgr>
|
|
#endif
|
|
{
|
|
[SerializeField, ReadOnly(true)] bool isInitialized;
|
|
[SerializeField] IVMate[] matePrefabs;
|
|
|
|
Dictionary<uint, IVMate> mateInstanceGroup;
|
|
SlotGroup<IVMate> currentSettedMates;
|
|
IVMate currentActiveMate;
|
|
|
|
SimpleHeap<SlotGroup<IVMate>.Slot> skillAvailableMates;
|
|
|
|
public void Init()
|
|
{
|
|
if (isInitialized) return;
|
|
|
|
mateInstanceGroup = new Dictionary<uint, IVMate>();
|
|
for (int i = 0; i < matePrefabs.Length; ++i)
|
|
{
|
|
IVMate mate = Instantiate(matePrefabs[i]);
|
|
mate.gameObject.SetActive(false);
|
|
mateInstanceGroup.Add(mate.Property.id, mate);
|
|
}
|
|
|
|
currentSettedMates = new SlotGroup<IVMate>(GameProperty.Instance.MateMaxCount);
|
|
skillAvailableMates = new SimpleHeap<SlotGroup<IVMate>.Slot>(CompareUseSkillPriority);
|
|
|
|
isInitialized = true;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if(!isInitialized) return;
|
|
|
|
skillAvailableMates.Clear();
|
|
foreach (var slot in currentSettedMates)
|
|
{
|
|
if (slot.IsEmpty) continue;
|
|
|
|
slot.item.UpdateSkillCoolTime();
|
|
if (slot.item.IsAvailableSkill)
|
|
skillAvailableMates.Push(slot);
|
|
}
|
|
|
|
if (skillAvailableMates.TryGetRootValue(out SlotGroup<IVMate>.Slot rootSlot) && rootSlot.item != currentActiveMate)
|
|
{
|
|
var player = BattleMgr.Instance.GetPlayer();
|
|
|
|
Transform spawnTrans = null;
|
|
Vector2 lookDir = player.transform.position - rootSlot.item.transform.position;
|
|
if(currentActiveMate != null)
|
|
{
|
|
spawnTrans = currentActiveMate.transform;
|
|
lookDir = currentActiveMate.LookDirection;
|
|
currentActiveMate.Dispose();
|
|
}
|
|
|
|
currentActiveMate = rootSlot.item;
|
|
currentActiveMate.Spawn(player, lookDir, spawnTrans);
|
|
}
|
|
|
|
currentActiveMate?.UseSkill();
|
|
}
|
|
|
|
public void SetMateAt(uint id, int slotIndex)
|
|
{
|
|
IVMate targetMate;
|
|
|
|
if (!IsValidSpawnSlotIndex(slotIndex))
|
|
throw new System.Exception("Invalid spawn position index");
|
|
else if (!mateInstanceGroup.TryGetValue(id, out targetMate))
|
|
throw new System.Exception("Invalid mate id");
|
|
else if (currentSettedMates.TryGetSlot(targetMate, out SlotGroup<IVMate>.Slot _))
|
|
throw new System.Exception("Already exist mate");
|
|
|
|
if(currentSettedMates.TryGetItem(slotIndex, out IVMate existedMate))
|
|
{
|
|
existedMate.Dispose();
|
|
currentSettedMates.ClearSlot(slotIndex);
|
|
|
|
if(currentActiveMate == existedMate)
|
|
currentActiveMate = null;
|
|
}
|
|
|
|
currentSettedMates[slotIndex] = targetMate;
|
|
|
|
if (currentActiveMate is null)
|
|
{
|
|
currentActiveMate = targetMate;
|
|
|
|
var player = BattleMgr.Instance.GetPlayer();
|
|
Vector2 lookDir = player.transform.position - currentActiveMate.transform.position;
|
|
|
|
currentActiveMate.Spawn(player, lookDir);
|
|
}
|
|
}
|
|
|
|
public void RemoveMateAt(int slotIndex)
|
|
{
|
|
if (!IsValidSpawnSlotIndex(slotIndex))
|
|
throw new System.Exception("Invalid spawn position index");
|
|
|
|
if (!currentSettedMates.TryGetItem(slotIndex, out IVMate existedMate)) return;
|
|
|
|
existedMate.Dispose();
|
|
currentSettedMates.ClearSlot(slotIndex);
|
|
|
|
if (currentActiveMate == existedMate)
|
|
{
|
|
currentActiveMate = null;
|
|
|
|
skillAvailableMates.Clear();
|
|
foreach (var slot in currentSettedMates)
|
|
{
|
|
if (slot.IsEmpty) continue;
|
|
skillAvailableMates.Push(slot);
|
|
}
|
|
|
|
if (skillAvailableMates.TryGetRootValue(out SlotGroup<IVMate>.Slot rootSlot))
|
|
{
|
|
currentActiveMate = rootSlot.item;
|
|
currentActiveMate.Spawn(BattleMgr.Instance.GetPlayer(), existedMate.LookDirection, existedMate.transform);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsValidSpawnSlotIndex(int slotIndex) => slotIndex >= 0 && slotIndex < GameProperty.Instance.MateMaxCount;
|
|
|
|
private bool CompareUseSkillPriority(SlotGroup<IVMate>.Slot slot1, SlotGroup<IVMate>.Slot slot2)
|
|
{
|
|
#if UNITY_EDITOR
|
|
if(slot1.IsEmpty || slot2.IsEmpty)
|
|
throw new System.Exception("Invalid slot");
|
|
#endif
|
|
if(slot1.item.IsAvailableSkill && slot2.item.IsAvailableSkill)
|
|
return slot1.slotIndex < slot2.slotIndex;
|
|
else if(!slot1.item.IsAvailableSkill && !slot2.item.IsAvailableSkill)
|
|
return slot1.item.ElapsedCoolTimeRate < slot2.item.ElapsedCoolTimeRate;
|
|
else
|
|
return slot1.item.IsAvailableSkill;
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public partial class MateMgr : Singleton<MateMgr>
|
|
{
|
|
[ContextMenu("TestSpawnRandomMate")]
|
|
void TestSpawnRandomMates()
|
|
{
|
|
foreach (var mate in mateInstanceGroup.Values)
|
|
{
|
|
currentSettedMates.GetEmptySlots(out List<SlotGroup<IVMate>.Slot> emptySlots);
|
|
if(emptySlots.Count == 0) break;
|
|
|
|
SetMateAt(mate.Property.id, emptySlots[0].slotIndex);
|
|
}
|
|
}
|
|
}
|
|
#endif
|