using UnityEngine; using UnityEngine.Assertions; using Spine.Unity; using Skill_V2; using System.Collections.Generic; using IVDataFormat; public class IVMate : Entity { [SerializeField] SkeletonAnimation skeletonAnimation; [SerializeField] CircleCollider2D castSkillDistance; [SerializeField] StateHandler stateHandler; Skill skillInstance; ContactFilter2D castSkillDistFilter; List castSkillDistOverlaped = new List(); public MateData Data { get; private set; } public SkeletonAnimation SkeletonAnimation => skeletonAnimation; public bool IsSafeChange => stateHandler.CurrentState is IVMateIdle || stateHandler.CurrentState is IVMateChasePlayer; public bool IsCastSkillAvailable => IsSafeChange && !Skill.IsInCoolTime && IsEnemyExistInCastSkillDistance; public bool IsEnemyExistInCastSkillDistance { get { castSkillDistance.radius = Data.DefaultCastSkillDistance; castSkillDistOverlaped.Clear(); castSkillDistance.OverlapCollider(castSkillDistFilter, castSkillDistOverlaped); for(int i = 0; i < castSkillDistOverlaped.Count; ++i) { var overlapped = castSkillDistOverlaped[i]; if (overlapped.CompareTag("Enemy") && overlapped.TryGetComponent(out CreatureBase creature) && creature.IsBattleAvail()) return true; } return false; } } public Skill Skill => skillInstance; private void OnDestroy() { if(skillInstance != null) { skillInstance.Stop(); Destroy(skillInstance.gameObject); } } public void SetMateData(MateData mateData) { Assert.IsTrue(mateData != null, Logger.LogMessage(LogType.Assert, nameof(SetMateData), "Mate data is null")); Data = mateData; var skillData = Data.Skill; if (skillData is null) return; skillInstance = Instantiate(skillData.Prefab); var buffGroup = GamePlayBuffMgr.Instance.BuffGroup; if (skillData.TryGetStat(StatID.CoolTime, out var coolTime)) { const eEffectType coolTimeEffectTypeStart = eEffectType.DecMateSkillCoolFlat; const eEffectType coolTimeEffectTypeEnd = eEffectType.DecMateSkillCoolRate; for (int i = (int)coolTimeEffectTypeStart; i <= (int)coolTimeEffectTypeEnd; i++) { foreach (var buff in buffGroup.GetBuffs((eEffectType)i)) { coolTime.AddModifier(buff.Value); } } buffGroup.OnChanged -= OnChangeBuff; buffGroup.OnChanged += OnChangeBuff; } skillInstance.SetSkillData(skillData); skillInstance.Stop(); } private void OnChangeBuff(BuffData buff, bool added) { if (!Data.Skill.TryGetStat(StatID.CoolTime, out var coolTime)) return; const eEffectType coolTimeEffectTypeStart = eEffectType.DecMateSkillCoolFlat; const eEffectType coolTimeEffectTypeEnd = eEffectType.DecMateSkillCoolRate; if (buff.Key >= coolTimeEffectTypeStart && buff.Key <= coolTimeEffectTypeEnd) { if (added) coolTime.AddModifier(buff.Value); else coolTime.RemoveModifier(buff.Value); } } public void UpdateSkillCoolTime() => skillInstance?.UpdateSkillCoolTime(); public void Spawn(IVCharacter player, Vector2 lookDir, Transform spawnPosition = null) { gameObject.SetActive(true); stateHandler?.ChangeState(new IVMateAppear(this, player, lookDir, spawnPosition)); } public void Dispose() { stateHandler?.ChangeState(new IVMateDisappear(this, () => gameObject.SetActive(false))); } public bool CastSkill() { if (IsCastSkillAvailable) { stateHandler?.ChangeState(new IVMateCastSkill(this, BattleMgr.Instance.GetPlayer())); return true; } return false; } }