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 { [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 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(IceScene); ice.Life = IceLife; ice.FreezeModule = this; } } private List GetNearbyBullets() { var nearbyBullets = new List(); 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; } }