mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
191 lines
No EOL
5.7 KiB
C#
191 lines
No EOL
5.7 KiB
C#
using System.Threading.Tasks;
|
|
using Cirno.Scripts.Resources;
|
|
using Cirno.Scripts.Resources.ScriptableBullets;
|
|
using Cirno.Scripts.UI;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
|
|
namespace Cirno.Scripts.Actors;
|
|
|
|
public partial class Boss : Enemy, IActivable
|
|
{
|
|
[Export] public string BossName { get; private set; }
|
|
//[Export] private Array<BossPhase> Phases;
|
|
[Export] public BossScript BossScript { get; private set; }
|
|
//[Export] private PackedScene BossHudPrefab;
|
|
[Export] public Vector2 BossPhaseAnimationStartingPosition = new Vector2(180, 10);
|
|
|
|
private int currentPhaseIndex = 0;
|
|
|
|
private bool _started = false;
|
|
private bool _waiting = false;
|
|
|
|
private GameManager _gameManager;
|
|
public GameManager GameManager => _gameManager;
|
|
private Vector2 _homePosition;
|
|
public Vector2 HomePosition => _homePosition;
|
|
private BossPhase CurrentPhase => BossScript.Phases[currentPhaseIndex];
|
|
|
|
private Marker2D _cameraMarker;
|
|
|
|
[Export]
|
|
public Vector2 CameraOffset = Vector2.Zero;
|
|
|
|
private TextureRect _animationTextureRect;
|
|
|
|
//[Export] private Texture2D _bossPortraitTexture;
|
|
|
|
private BossHud _bossHud;
|
|
|
|
[Signal] public delegate void ActorSpriteChangeEventHandler(Vector2 direction);
|
|
|
|
public override void _Ready()
|
|
{
|
|
base._Ready();
|
|
if (BossScript is null)
|
|
{
|
|
GD.PrintErr($"No boss script defined in {this.Name}");
|
|
return;
|
|
}
|
|
|
|
_gameManager = this.GetGameManager();
|
|
|
|
_homePosition = this.GlobalPosition;
|
|
|
|
_cameraMarker = new Marker2D();
|
|
_gameManager.CallDeferred("add_child", _cameraMarker);
|
|
_cameraMarker.GlobalPosition = _homePosition + CameraOffset;
|
|
|
|
if (BossScript.HudPrefab is not null)
|
|
{
|
|
_bossHud = BossScript.HudPrefab.Instantiate<BossHud>();
|
|
_gameManager.CallDeferred("add_child", _bossHud);
|
|
|
|
_bossHud.Name = $"{BossName}_BossHud";
|
|
_bossHud.Visible = false;
|
|
_bossHud.BossName = BossName;
|
|
_bossHud.BossMaxHealth = this.Health;
|
|
_bossHud.BossHealth = this._currentHealth;
|
|
_bossHud.SpellCardName = CurrentPhase.PhaseName;
|
|
|
|
// TODO: Do some translation for health values to match the thresholds
|
|
this.HealthChanged += (float newValue) => {_bossHud.BossHealth = newValue;};
|
|
|
|
if (BossScript.PortraitTexture is not null)
|
|
{
|
|
// var canvas = new CanvasLayer();
|
|
// canvas.Name = "BossPhaseAnimationCanvas";
|
|
|
|
// _gameManager.CallDeferred("add_child", canvas);
|
|
|
|
_animationTextureRect = new TextureRect();
|
|
_animationTextureRect.Texture = BossScript.PortraitTexture;
|
|
|
|
_bossHud.CallDeferred("add_child", _animationTextureRect);
|
|
|
|
_animationTextureRect.Position = BossPhaseAnimationStartingPosition;
|
|
|
|
_animationTextureRect.Visible = false;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
base._Process(delta);
|
|
|
|
if (!_started) return;
|
|
if (_waiting) return;
|
|
|
|
CurrentPhase.UpdatePhase(delta);
|
|
if (_currentHealth <= CurrentPhase.Threshold && currentPhaseIndex + 1 < BossScript.Phases.Count)
|
|
{
|
|
currentPhaseIndex++;
|
|
_bossHud.SpellCardName = CurrentPhase.PhaseName;
|
|
StartPhase(CurrentPhase);
|
|
}
|
|
}
|
|
|
|
protected override void Explode()
|
|
{
|
|
if (_bossHud is not null)
|
|
{
|
|
_bossHud.QueueFree();
|
|
}
|
|
|
|
_gameManager.CameraTargetPlayer();
|
|
|
|
base.Explode();
|
|
}
|
|
|
|
private void StartPhase(BossPhase phase)
|
|
{
|
|
if (phase.PlayAnimation)
|
|
{
|
|
_waiting = true;
|
|
_invulnerable = true;
|
|
_ = Switchphase(phase);
|
|
}
|
|
else
|
|
{
|
|
phase.Start(this);
|
|
}
|
|
}
|
|
|
|
public void TakeDamage(int amount)
|
|
{
|
|
if (!_started) return;
|
|
|
|
_currentHealth -= amount;
|
|
}
|
|
|
|
public void Activate(ActivationType activationType = ActivationType.Toggle)
|
|
{
|
|
_started = true;
|
|
if (_bossHud is not null)
|
|
{
|
|
_bossHud.Visible = true;
|
|
}
|
|
_gameManager.CameraTargetObject(_cameraMarker);
|
|
StartPhase(CurrentPhase);
|
|
}
|
|
|
|
private async Task Switchphase(BossPhase phase)
|
|
{
|
|
await PlayAnimation();
|
|
|
|
_waiting = false;
|
|
_invulnerable = false;
|
|
phase.Start(this);
|
|
}
|
|
|
|
private async Task PlayAnimation()
|
|
{
|
|
_animationTextureRect.Modulate = new Color(_animationTextureRect.Modulate.R, _animationTextureRect.Modulate.G, _animationTextureRect.Modulate.B, 0f);
|
|
_animationTextureRect.Position = BossPhaseAnimationStartingPosition;
|
|
_animationTextureRect.Visible = true;
|
|
|
|
var tween = GetTree().CreateTween();
|
|
tween.SetEase(Tween.EaseType.InOut);
|
|
tween.SetTrans(Tween.TransitionType.Linear);
|
|
|
|
tween.TweenProperty(_animationTextureRect, "modulate:a", 1f, 0.2f);
|
|
|
|
tween.TweenProperty(_animationTextureRect, "global_position", _animationTextureRect.GlobalPosition + new Vector2(-64f, 20f), 1.5f);
|
|
|
|
tween.TweenProperty(_animationTextureRect, "modulate:a", 0f, 0.2f);
|
|
|
|
//await Task.Delay(800);
|
|
|
|
// Wait for the tween to finish
|
|
await ToSignal(tween, "finished");
|
|
|
|
_animationTextureRect.Visible = false;
|
|
}
|
|
|
|
public void ChangeSpriteDirection(Vector2 direction)
|
|
{
|
|
EmitSignal(SignalName.ActorSpriteChange, direction);
|
|
}
|
|
} |