using Cirno.Scripts.Actors; using Cirno.Scripts.Resources; using Godot; namespace Cirno.Scripts.AttackPatterns; [GlobalClass] [Tool] public partial class MovementPattern : AttackPattern { [Export] public Vector2 relativeTargetPosition; [Export] public float moveDuration = 2f; [Export] public Tween.TransitionType transitionType = Tween.TransitionType.Linear; [Export] public Tween.EaseType easeType = Tween.EaseType.InOut; [Export] public AttackPattern shootingPattern; public override IPatternMachine MakeMachine(Node parent) { return new MovementPatternMachine(this, parent); } public class MovementPatternMachine(MovementPattern pattern, Node parent) : IPatternMachine { public Node Parent => parent; public MovementPattern Pattern { get; } = pattern; private IPatternMachine _machine; private Tween tween; private bool isComplete = false; protected IScriptHost Boss; public void Start() { if (parent is not IScriptHost boss) return; Boss = boss; tween = parent.CreateTween(); isComplete = false; Vector2 targetPosition = (Boss?.HomePosition ?? boss.ParentObject.GlobalPosition) + Pattern.relativeTargetPosition; tween.TweenProperty(boss.ParentObject, "position", targetPosition, Pattern.moveDuration) .SetTrans(Pattern.transitionType) .SetEase(Pattern.easeType) .Finished += () => isComplete = true; if (Pattern.shootingPattern != null && !Pattern.WaitForCompletion) { _machine = Pattern.shootingPattern.MakeMachine(parent); _machine.Start(); } } public void UpdatePattern(double delta) { if (_machine is not null && !Pattern.WaitForCompletion) { _machine.UpdatePattern(delta); //shootingPattern.UpdatePattern(delta); } } public bool IsComplete() { if (Pattern.WaitForCompletion && _machine is not null) return isComplete && _machine.IsComplete(); return isComplete; } } }