using System.Collections; using System.Collections.Generic; using System.Linq; using BlueWater.Audios; using BlueWater.Items; using BlueWater.Maps; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Enemies.Bosses.SandMole { public enum SandMoleSkill { None = 0, GateOfSpikes, MultiThrowSpikes, SingleRoll, SpikeBarrage } public enum SandMoleSkin { Idle = 0, Normal, Spin } public enum SandMoleAnimation { None = 0, Die, DigIn, DigOut, Idle, Roar, Spin, SpinReady, SpinReady2, Stun, ShootingStart, ShootingIdle, ShootingEnd } public class SandMole : SpineBoss { // Variables #region Variables [field: Title("SandMole 컴포넌트")] [field: SerializeField, Required] public SandMoleStatus SandMoleStatus { get; private set; } private List _summonMiniSandMoles; public SandMoleData SandMoleData { get; private set; } public SandMoleMapController SandMoleMapController { get; private set; } #endregion // Unity events #region Unity events protected override void Update() { base.Update(); HandleMovement(); FlipVisualLook(); } protected override void OnDestroy() { base.OnDestroy(); BossHealthPoint.OnHealthChanged -= SummonMiniSandMole; } #endregion // Initialize methods #region Initialize methods protected override void InitializeComponents() { base.InitializeComponents(); SandMoleStatus = GetComponent(); SandMoleData = BossData as SandMoleData; if (SandMoleData != null) { _summonMiniSandMoles = SandMoleData.SummonMiniSandMoles.ConvertAll(mole => new SummonMiniSandMole(mole)); } SandMoleMapController = MapManager.Instance.SandMoleMapController; } public override void Initialize() { StartCoroutine(InitializeCoroutine()); } #endregion // Methods #region Methods private IEnumerator InitializeCoroutine() { HitBoxCollider.enabled = false; BossHealthPoint.Initialize(true, SandMoleData.MaxHealthPoint, SandMoleData.DisplayName, SandMoleMapController.ParticleInstanceLocation); BossHealthPoint.OnHealthChanged += SummonMiniSandMole; BossSkillController.Initialize(BossData.SkillDataList); SetMoveSpeed(SandMoleData.MoveSpeed); StopMove(); SpineController.SetSkin(SandMoleSkin.Normal.ToString()); var isCameraShakeActive = false; var roarTrack = SpineController.PlayAnimation(SandMoleAnimation.Roar.ToString(), false); while (!roarTrack.IsComplete) { if (CurrentHealthPoint == 0) yield break; if (roarTrack.TrackTime >= 1f && !isCameraShakeActive) { AudioManager.Instance.PlaySfx("SandMoleCry"); VisualFeedbackManager.Instance.CameraShake(CombatCameraManager.Instance.BaseCombatCamera, 2f, 1f); isCameraShakeActive = true; } yield return null; } BehaviorTree.EnableBehavior(); HitBoxCollider.enabled = true; } protected override async void Die() { BossSkillController.StopAllCoroutine(); SandMoleStatus.StopAllCoroutine(); BehaviorTree.DisableBehavior(); StopMove(); HitBoxCollider.enabled = false; if (Rigidbody) { Rigidbody.linearVelocity = Vector3.zero; Rigidbody.isKinematic = true; } SpineController.SetSkin(SandMoleSkin.Idle.ToString()); var dieTrack = SpineController.PlayAnimation(SandMoleAnimation.Die.ToString(), false); SandMoleMapController.ClearMap(gameObject); await SpineController.WaitForAnimationCompletion(dieTrack); ItemManager.Instance.ItemDropRandomPosition(BossData.CharacterIdx, transform.position); Destroy(gameObject); } private void SummonMiniSandMole(int currentHp, string bossName) { if (currentHp == 0) return; var currentHealthPercentage = (float)currentHp / BossData.MaxHealthPoint * 100f; foreach (var element in _summonMiniSandMoles) { if (currentHealthPercentage > element.HealthPercentage || element.SummonTrigger) continue; SandMoleMapController.SummonMiniSandMole(); element.SummonTrigger = true; } } #endregion } }