using Cirno.Scripts.Actors; using Cirno.Scripts.Resources; using Godot; using Godot.Collections; namespace Cirno.Scripts.AttackPatterns; [GlobalClass] [Tool] public partial class CreateEmitterPattern : AttackPattern { [Export] public Vector2 SpawnOffset { get; set; } [Export] public BulletScript Script { get; set; } [Export] public PackedScene Prefab { get; set; } [Export] public bool CreateAsChild { get; set; } [Export] public double LifeTime { get; set; } = 10d; public override IPatternMachine MakeMachine(Node parent) { return new EmitterPatternMachine(this, parent); } public class EmitterPatternMachine(CreateEmitterPattern pattern, Node parent) : IPatternMachine { private bool _active = false; public Node Parent => parent; public AutonomousBulletEmitter Emitter { get; private set; } public void Start() { if (parent is not Node2D parent2d) { return; } Emitter = pattern.CreateAsChild ? parent2d.CreateChild(pattern.Prefab, parent2d.GlobalPosition + pattern.SpawnOffset) : parent2d.CreateSibling(pattern.Prefab, parent2d.GlobalPosition + pattern.SpawnOffset); Emitter.Script = pattern.Script; Emitter.EmitOnStart = true; Emitter.LifeTime = pattern.LifeTime; _active = true; Emitter.Autonomous = !pattern.WaitForCompletion; Emitter.Death += EmitterOnDeath; Emitter.Start(); } private void EmitterOnDeath() { _active = false; Emitter.Death -= EmitterOnDeath; } public void UpdatePattern(double delta) { if (_active) { if (pattern.WaitForCompletion) { Emitter.Update(delta); } } } public bool IsComplete() { if (pattern.WaitForCompletion) return !_active; return _active; } } }