cirnogodot/Scripts/Components/FSM/Boss/3D/BossScriptHostModule3D.cs
2025-06-30 17:28:19 +02:00

117 lines
No EOL
3.1 KiB
C#

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<EnemyState, CharacterBody3D>, 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<EnemyState, CharacterBody3D> _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<EnemyState, CharacterBody3D> 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);
}
}