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

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