cirnogodot/Scripts/Components/FSM/Player/FreezeModule.cs
2025-04-26 11:24:20 +02:00

98 lines
No EOL
2.6 KiB
C#

using System.Collections.Generic;
using Cirno.Scripts.Actors;
using Cirno.Scripts.Components.Actors;
using Godot;
namespace Cirno.Scripts.Components.FSM.Player;
public partial class FreezeModule : ModuleBase<PlayerState, CharacterBody2D>
{
[Export] public float ResourceCost { get; private set; } = 15f;
[Export] public float FreezeRadius { get; private set; } = 64f;
[Export] public double Cooldown { get; private set; } = 0.5f;
[Export] public double IceLife { get; private set; } = 4f;
[Export] public PackedScene IceScene { get; private set; }
[ExportGroup("Providers")]
[Export]
public ActorResourceProvider Shield { get; private set; }
[Export]
public InputProvider InputProvider { get; private set; }
public bool Enabled { get; set; } = false;
private double _cooldownTimer = 0;
public override void EnterState(PlayerState state)
{
Enabled = true;
}
public override void ExitState(PlayerState state)
{
Enabled = false;
}
public override void Init(IStateMachine<PlayerState, CharacterBody2D> machine)
{
}
public override void Process(double delta)
{
if (!Enabled) return;
// TODO: Handle cooldown
}
public override void PhysicsProcess(double delta)
{
if (!Enabled) return;
if (InputProvider.GetFreezeJustPressed())
{
if (Shield.CurrentResource >= ResourceCost)
{
Shield.CurrentResource -= ResourceCost;
FreezeBullets();
}
}
}
private void FreezeBullets()
{
var bullets = GetNearbyBullets();
foreach (var bullet in bullets)
{
bullet.Freeze();
var ice = bullet.CreateSibling<Ice>(IceScene);
ice.Life = IceLife;
ice.FreezeModule = this;
}
}
private List<Bullet> GetNearbyBullets()
{
var nearbyBullets = new List<Bullet>();
foreach (var child in GameManager.Instance.BulletsContainer.GetChildren())
{
if (child is not Bullet bullet) continue;
if (bullet.BulletOwner is BulletOwner.Player)
{
continue;
}
if (bullet.IsFrozen) continue;
if (!bullet.BulletInfo.Freezable) continue;
var distance = GlobalPosition.DistanceTo(bullet.GlobalPosition);
if (distance <= FreezeRadius)
{
nearbyBullets.Add(bullet);
}
}
return nearbyBullets;
}
}