using System; using Cirno.Scripts.Components.Actors; using Godot; namespace Cirno.Scripts.Components.FSM.Player; public partial class Active : PlayerFSMState { private Vector2 _movementDirection { get; set; } public Vector2 FacingDirection { get; private set; } = Vector2.Down; [Export] public int Speed { get; set; } = 45; [Export] public int StrafeSpeed { get; set; } = 35; [ExportCategory("Providers")] [Export] private PlayerWeaponProvider _weaponProvider; [Export] private PlayerAnimationProvider _animationProvider; [Export] private PlayerCrosshairProvider _crosshairProvider; [Export] private PlayerHitboxSpriteProvider _hitboxSpriteProvider; [Export] private InputProvider _inputProvider; [Export] private PlayerDamageReceiver _damageReceiver; [Export] private ActivationProvider _activationProvider; private bool _isStrafing; public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed; private PlayerStateMachine _player; private Hud _hud; public override void Init(ActorStateMachine stateMachine) { base.Init(stateMachine); _hud = Hud.Instance; _player = (PlayerStateMachine)stateMachine; _damageReceiver.Death += () => { ChangeState(PlayerState.Dead); }; _damageReceiver.HealthChanged += (value, maxValue) => { _animationProvider.Blink(); _hud.UpdateHealth(value, maxValue); }; _damageReceiver.ShieldChanged += (value, maxValue) => { _animationProvider.PlayShieldAnimation(); _hud.UpdateShield(value, maxValue); }; _damageReceiver.Init(); _damageReceiver.RefillHealth(); _damageReceiver.RefillShield(); _activationProvider.Init(stateMachine); //_weaponProvider = stateMachine.GetNode("WeaponProvider"); //_animationProvider = stateMachine.GetNode("AnimationProvider"); _weaponProvider.Init(stateMachine); } public override void EnterState() { // enable sprite // enable crosshair _crosshairProvider.Show(); _animationProvider.ShowSprite(); _damageReceiver.Enabled = true; _activationProvider.Enabled = true; } public override void ExitState() { _animationProvider.SetAnimation(Vector2.Zero); _crosshairProvider.Hide(); _hitboxSpriteProvider.Hide(); _damageReceiver.Enabled = false; _activationProvider.Enabled = false; } public override void PhysicsProcessState(double delta) { _stateMachine.Velocity = _movementDirection * MovementSpeed; _stateMachine.MoveAndSlide(); } public override void ProcessState(double delta) { _movementDirection = _inputProvider.GetMovementInput().Normalized(); _isStrafing = _inputProvider.GetStrafePressed(); // Toggle visibility of the hitbox sprite based on strafing _hitboxSpriteProvider.SetVisibility(_isStrafing); var rightStickInput = _inputProvider.GetAimInput().Normalized(); // Update Facing Direction if (!_isStrafing) { if (rightStickInput.Length() > 0.1f) // If the right stick is moved { FacingDirection = rightStickInput.Normalized(); } else if (_movementDirection != Vector2.Zero) // Fall back to movement direction { FacingDirection = _movementDirection; } } _animationProvider.SetAnimation(_stateMachine.Velocity); _crosshairProvider.UpdatePosition(FacingDirection); HandleShoot(); HandleInteraction(); // FindInteractable(); // _crosshair.Position = CalculateCrosshairPosition(); if (_inputProvider.GetInventoryJustPressed()) { GameManager.Instance.ChangeState(GameState.Inventory); } if (_inputProvider.GetPauseJustPressed()) { //CallDeferred(MethodName.PauseDeferred); PauseDeferred(); } } private void PauseDeferred() { GameManager.Instance.Pause(); } private void HandleShoot() { if (!_inputProvider.GetShootPressed()) return; _weaponProvider.Shoot(this.FacingDirection); } private void HandleInteraction() { _activationProvider.HandleInteraction(); } }