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.
 
 
 
 
 
 

218 lines
6.5 KiB

using System.Collections.Generic;
using UnityEngine;
public class MateMgr : Singleton<MateMgr>
{
[SerializeField] MateSkillCutSceneView skillCutSceneView;
[SerializeField] MateSkillCoolTimeView skillCoolTimeView;
bool isInitialized;
Dictionary<uint, IVMate> mateInstanceGroup;
SlotGroup<IVMate> settedMates;
int currentMateSlotIndex;
IVMate activeMate;
List<IHasBuff> activeSynergies = new();
public SlotGroup<IVMate> SettedMates => settedMates;
public IVMate ActiveMate => activeMate;
public void Init()
{
if (isInitialized) return;
mateInstanceGroup = new Dictionary<uint, IVMate>();
foreach (var id in MateDataGroup.Instance.MateIDs)
{
if(!MateDataGroup.Instance.TryGetMateInstance(id, out var mate)) continue;
mate.gameObject.SetActive(false);
mateInstanceGroup.Add(mate.Data.ID, mate);
}
settedMates = new SlotGroup<IVMate>(GameProperty.Instance.MateMaxCount);
foreach (var row in MateDataGroup.Instance.GetMateDataMatrix(MateData.CompareBySettedSlotIndex))
{
settedMates.GetEmptySlots(out var emptySlots);
foreach (var mate in row)
{
if(emptySlots.Count == 0) break;
if(mate.IsSetted)
{
SetMateAt(mate.ID, mate.SettedSlotIndex);
emptySlots.RemoveAt(0);
}
}
}
isInitialized = true;
}
private void Update()
{
if(!isInitialized || BattleMgr.Instance.BattlePause) return;
for(int i = 0; i < settedMates.SlotCount; i++)
{
var currentSlot = settedMates.GetSlot(i);
if(!currentSlot.IsEmpty)
currentSlot.item.UpdateSkillCoolTime();
}
if (activeMate is null) return;
if (IsSafeToChangeCurrentMate() && activeMate.Skill.IsInCoolTime)
{
for (int i = currentMateSlotIndex + 1; true; i++)
{
int nextIndex = i % settedMates.SlotCount;
if (nextIndex == currentMateSlotIndex) break;
var slot = settedMates.GetSlot(nextIndex);
if (!slot.IsEmpty)
{
if(!slot.item.Skill.IsInCoolTime)
ChangeActiveMate(slot.item, slot.slotIndex);
break;
}
}
}
if (activeMate.CastSkill())
{
skillCutSceneView.Show();
}
}
private void ChangeActiveMate(IVMate target, int slotIndex)
{
if(activeMate == target) return;
var player = BattleMgr.Instance.GetPlayer();
Transform spawnTrans = null;
Vector2 lookDir = player.transform.position - target.transform.position;
if (activeMate != null)
{
spawnTrans = activeMate.transform;
lookDir = activeMate.LookDirection;
activeMate.Dispose();
}
currentMateSlotIndex = slotIndex;
activeMate = target;
activeMate.Spawn(player, lookDir, spawnTrans);
skillCutSceneView.SetMate(activeMate);
}
public bool IsSafeToChangeCurrentMate() => activeMate?.IsSafeChange ?? true;
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 (settedMates.TryGetSlot(targetMate, out SlotGroup<IVMate>.Slot _))
return;
if (settedMates.TryGetItem(slotIndex, out IVMate existedMate))
{
existedMate.Data.RemoveSlotIndex();
existedMate.Dispose();
settedMates.ClearSlot(slotIndex);
if(activeMate == existedMate)
activeMate = null;
}
settedMates[slotIndex] = targetMate;
targetMate.Data.SetSlotIndex(slotIndex);
if (activeMate is null)
ChangeActiveMate(targetMate, slotIndex);
RefreshSynergies();
skillCoolTimeView?.SetMateAt(settedMates.GetSlot(slotIndex));
}
public void RemoveMateAt(int slotIndex)
{
if (!IsValidSpawnSlotIndex(slotIndex))
throw new System.Exception("Invalid spawn position index");
if (!settedMates.TryGetItem(slotIndex, out IVMate existedMate)) return;
existedMate.Data.RemoveSlotIndex();
existedMate.Dispose();
settedMates.ClearSlot(slotIndex);
if (activeMate == existedMate)
{
for(int i = currentMateSlotIndex + 1; true; i++)
{
int nextIndex = i % settedMates.SlotCount;
if (nextIndex == currentMateSlotIndex)
{
currentMateSlotIndex = -1;
activeMate = null;
break;
}
var slot = settedMates.GetSlot(nextIndex);
if(!slot.IsEmpty)
{
ChangeActiveMate(slot.item, slot.slotIndex);
break;
}
}
}
RefreshSynergies();
skillCoolTimeView?.RemoveMateAt(slotIndex);
}
private void RefreshSynergies()
{
foreach (var synergy in activeSynergies)
{
GamePlayBuffMgr.Instance.BuffGroup.RemoveBuffs(synergy.Buffs);
}
activeSynergies.Clear();
_RefreshSynergies(settedMates.ConvertAll((mate) => mate.Data.Nationality), MateDataGroup.Instance.NationalitySynergies);
_RefreshSynergies(settedMates.ConvertAll((mate) => mate.Data.Grade), MateDataGroup.Instance.GradeSynergies);
_RefreshSynergies(settedMates.ConvertAll((mate) => mate.Data.Property), MateDataGroup.Instance.DestinySynergies);
foreach (var synergy in activeSynergies)
{
GamePlayBuffMgr.Instance.BuffGroup.AddBuffs(synergy.Buffs);
}
}
private void _RefreshSynergies<T>(IReadOnlyList<T> toCheck, IReadOnlyList<SynergyData<T>> synergyDatas)
{
foreach (var synergyData in synergyDatas)
{
if (synergyData.CheckCondition(toCheck))
{
activeSynergies.Add(synergyData);
}
}
}
public bool IsValidSpawnSlotIndex(int slotIndex) => slotIndex >= 0 && slotIndex < GameProperty.Instance.MateMaxCount;
}