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.
235 lines
6.8 KiB
235 lines
6.8 KiB
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class MateMgr : MonoSingleton<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();
|
|
foreach (var id in MateDataGroup.Instance.MateIDs)
|
|
{
|
|
if (!MateDataGroup.Instance.TryGetMateData(id, out var mate)) continue;
|
|
|
|
var instance = Instantiate(mate.Prefab);
|
|
instance.SetData(mate);
|
|
|
|
instance.gameObject.SetActive(false);
|
|
mateInstanceGroup.Add(mate.ID, instance);
|
|
}
|
|
|
|
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)
|
|
{
|
|
var player = BattleMgr.Instance.GetPlayer();
|
|
|
|
Transform spawnTrans = null;
|
|
Vector2 lookDir = player.LookDirection;
|
|
|
|
if (activeMate != null && activeMate != target)
|
|
{
|
|
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)
|
|
{
|
|
Debug.Assert(slotIndex >= 0 && slotIndex < GameProperty.Instance.MateMaxCount, "Invalid spawn position index");
|
|
|
|
if (!mateInstanceGroup.TryGetValue(id, out var targetMate) || 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)
|
|
{
|
|
Debug.Assert(slotIndex >= 0 && slotIndex < GameProperty.Instance.MateMaxCount, "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);
|
|
}
|
|
|
|
public void SetAcitveMateToFirst()
|
|
{
|
|
for(int i = 0; i < settedMates.SlotCount; i++)
|
|
{
|
|
var slot = settedMates.GetSlot(i);
|
|
if(!slot.IsEmpty)
|
|
{
|
|
currentMateSlotIndex = i;
|
|
activeMate = slot.item;
|
|
skillCutSceneView?.SetMate(activeMate);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void EndAllSettedMateSkillCool()
|
|
{
|
|
settedMates.LoopValidSlot((mate) =>
|
|
{
|
|
mate.Skill.EndCoolTime();
|
|
return true;
|
|
});
|
|
}
|
|
|
|
private void RefreshSynergies()
|
|
{
|
|
foreach (var synergy in activeSynergies)
|
|
{
|
|
GamePlayBuffMgr.Instance.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.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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|