cirnogodot/Scripts/Components/FSM/Player/FreezeModule.cs
2025-06-08 16:33:38 +02:00

84 lines
No EOL
2.4 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Cirno.Scripts.Actors;
using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Controllers;
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()
{
return (from child in PoolingManager.Instance.GetAllActiveBullets()
where child is not null
where child.Enabled // Could be redundant but better check in case of errors
where child.BulletOwner is not BulletOwner.Player
where !child.IsFrozen
where child.BulletInfo.Freezable
let distance = GlobalPosition.DistanceTo(child.GlobalPosition)
where distance <= FreezeRadius
select child).ToList();
}
}