using System.Threading.Tasks; using Cirno.Scripts.AttackPatterns; using Cirno.Scripts.Components.Actors; using Cirno.Scripts.Components.FSM.Enemy._3D; using Cirno.Scripts.Controllers; using Cirno.Scripts.Enums; using Cirno.Scripts.Resources; using Cirno.Scripts.Resources.ScriptableBullets; using Godot; namespace Cirno.Scripts.Components.FSM.Boss._3D; public partial class BossScriptHostModule3D : ModuleBase, IScriptHost3D { [Export] public BossScript BossScript { get; set; } [Export] public EnemyStorage3D StorageModule { get; private set; } [Export] public DamageReceiver3D DamageReceiver { get; private set; } public Node3D ParentObject => _machine.MainObject; public Vector3 HomePosition => StorageModule.HomePosition; private IStateMachine _machine; private int _currentPhaseIndex = 0; private BossPhase CurrentPhase => BossScript.Phases[_currentPhaseIndex]; private bool _waiting = false; public float CurrentHealth => DamageReceiver.HealthProvider.CurrentResource; public void ChangeSpriteDirection(Vector2 direction) { } public override void EnterState(EnemyState state) { DamageReceiver.ChangeState(true); DamageReceiver.HealthProvider.ResourceDepleted += HealthProviderOnResourceDepleted; StartPhase(CurrentPhase); } public override void ExitState(EnemyState state) { DamageReceiver.HealthProvider.ResourceDepleted -= HealthProviderOnResourceDepleted; DamageReceiver.ChangeState(false); } public override void Init(IStateMachine machine) { _machine = machine; if (StorageModule.Root.EnemyResource.BossScript is not null) { this.BossScript = StorageModule.Root.EnemyResource.BossScript; } } private void HealthProviderOnResourceDepleted() { _machine.SetState(EnemyState.Dead); } public override void Process(double delta) { if (_waiting) return; CurrentPhase.UpdatePhase(delta); if (CurrentHealth <= CurrentPhase.Threshold && _currentPhaseIndex + 1 < BossScript.Phases.Count) { _currentPhaseIndex++; //_bossHud.SpellCardName = CurrentPhase.PhaseName; StartPhase(CurrentPhase); } } public override void PhysicsProcess(double delta) { } private void StartPhase(BossPhase phase) { PoolingManager.Instance.ClearBullets(); //GameController.Instance.ClearBullets(); if (phase.PlayAnimation) { _waiting = true; DamageReceiver.ChangeState(false); _ = SwitchPhase(phase); } else { phase.Start(this); } } private async Task SwitchPhase(BossPhase phase) { await PlayAnimation(); _waiting = false; DamageReceiver.ChangeState(true); phase.Start(this); } private async Task PlayAnimation() { await Task.Delay(1000); } }