3D Boss scripts implementation

This commit is contained in:
Marco 2025-06-30 17:28:19 +02:00
commit dbf7f1a963
29 changed files with 1805 additions and 1188 deletions

View file

@ -0,0 +1,14 @@
using Cirno.Scripts.Weapons;
using Godot;
namespace Cirno.Scripts.Components.Actors._3D;
public partial class BulletSprite3D : Sprite3D
{
private Bullet3D _parent;
public override void _Ready()
{
_parent = GetParent<Bullet3D>();
}
}

View file

@ -0,0 +1 @@
uid://c4j8jwgs6okew

View file

@ -0,0 +1,117 @@
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);
}
}

View file

@ -0,0 +1 @@
uid://dej2tbl70yiyp

View file

@ -0,0 +1,59 @@
using System.Threading.Tasks;
using Cirno.Scripts.Components.FSM.Enemy._3D;
using Cirno.Scripts.Enums;
using Godot;
namespace Cirno.Scripts.Components.FSM.Boss._3D;
public partial class Idle : EnemyStateBase3D
{
public override EnemyState StateId => EnemyState.Idle;
[Export] public EnemyStorage3D Storage { get; private set; }
[Export] public GravityProvider GravityProvider { get; private set; }
[Export] public bool DebugEnabled { get; set; } = false;
public override void EnterState()
{
base.EnterState();
// player detection
// damage receiver will be a module
GD.Print("Entered Idle");
_ = DelayStart();
}
public override void ExitState()
{
base.ExitState();
// Disable DamageReceiver
}
private async Task DelayStart()
{
await Task.Delay(1000);
ChangeState(EnemyState.Shooting);
}
public override void PhysicsProcessState(double delta)
{
base.PhysicsProcessState(delta);
MainObject.Velocity = new Vector3(MainObject.Velocity.X, GravityProvider.CalculateGravityVelocity(MainObject.Velocity.Y, delta), MainObject.Velocity.Z);
MainObject.MoveAndSlide();
}
public override void ProcessState(double delta)
{
base.ProcessState(delta);
}
}

View file

@ -0,0 +1 @@
uid://05agh8h015fy

View file

@ -0,0 +1,45 @@
using Cirno.Scripts.Components.FSM.Enemy._3D;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Utils;
using Cirno.Scripts.Weapons;
using Godot;
namespace Cirno.Scripts.Components.FSM.Boss._3D;
public partial class Shooting : EnemyStateBase3D
{
public override EnemyState StateId => EnemyState.Shooting;
[Export] public EnemyStorage3D Storage { get; private set; }
[Export] public GravityProvider GravityProvider { get; private set; }
public override void EnterState()
{
base.EnterState();
// Enable damage receiver
}
public override void ExitState()
{
base.ExitState();
}
public override void PhysicsProcessState(double delta)
{
base.PhysicsProcessState(delta);
// Calculate gravity
MainObject.Velocity = new Vector3(MainObject.Velocity.X, GravityProvider.CalculateGravityVelocity(MainObject.Velocity.Y, delta), MainObject.Velocity.Z);
MainObject.MoveAndSlide();
}
public override void ProcessState(double delta)
{
base.ProcessState(delta);
}
}

View file

@ -0,0 +1 @@
uid://d2838a10x33w8