cirnogodot/Scripts/Components/FSM/Enemy/Controlled.cs

140 lines
No EOL
4.1 KiB
C#

using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Enums;
using Godot;
namespace Cirno.Scripts.Components.FSM.Enemy;
public partial class Controlled : EnemyStateBase
{
public override EnemyState StateId => EnemyState.Controlled;
private EnemyStorageModule StorageModule { get; set; }
private GenericDamageReceiver DamageReceiver { get; set; }
[Export]
private InputProvider _inputProvider;
private PlayerCrosshairProvider CrosshairProvider { get; set; }
[Export] public Weapon EquippedWeapon { get; private set; }
[Export] public StringName ControlEndAction { get; private set; } = "pause";
[Export] public StringName ShootAction { get; private set; } = "shoot";
private bool _isStrafing = false;
public override void Init(IStateMachine<EnemyState, CharacterBody2D> machine)
{
base.Init(machine);
StorageModule ??= StateMachine.GetModule<EnemyStorageModule>();
DamageReceiver ??= StateMachine.GetModule<GenericDamageReceiver>();
CrosshairProvider ??= StateMachine.GetModule<PlayerCrosshairProvider>();
}
public override void EnterState()
{
base.EnterState();
GD.Print($"{StorageModule.Root.Name} Controlled");
DamageReceiver.ChangeState(true);
DamageReceiver.HealthProvider.ResourceDepleted += HealthProviderOnResourceDepleted;
GameManager.Instance.CameraTargetObject(MainObject);
GameManager.Instance.Player.SetState(PlayerState.Controlling);
DamageReceiver.BulletGroup = BulletOwner.Player;
_isStrafing = false;
CrosshairProvider.Visible = true;
// Show possession sprite
}
private void HealthProviderOnResourceDepleted()
{
ChangeState(EnemyState.Dead);
}
public override void ExitState()
{
base.ExitState();
DamageReceiver.HealthProvider.ResourceDepleted -= HealthProviderOnResourceDepleted;
DamageReceiver.ChangeState(false);
GameManager.Instance.CameraTargetPlayer();
GameManager.Instance.Player.SetState(PlayerState.Active);
DamageReceiver.BulletGroup = BulletOwner.Enemy;
CrosshairProvider.Visible = false;
// Hide possession sprite
}
public override void PhysicsProcessState(double delta)
{
base.PhysicsProcessState(delta);
if (_inputProvider.GetShootPressed())
{
Shoot();
}
if (Input.IsActionJustPressed(ControlEndAction))
{
StateMachine.SetState(EnemyState.Idle);
}
HandlePhysics(delta);
StorageModule.FacingDirection = MainObject.Velocity.SnapToCardinal().Normalized();
}
private void HandlePhysics(double delta)
{
StorageModule.MovementDirection = _inputProvider.GetMovementInput().Normalized();
_isStrafing = _inputProvider.GetStrafePressed();
var rightStickInput = _inputProvider.GetAimInput().Normalized();
if (rightStickInput.Length() > 0.1f) // If the right stick is moved
{
StorageModule.AimingDirection = rightStickInput;
}
else if (StorageModule.MovementDirection != Vector2.Zero) // Fall back to movement direction
{
StorageModule.AimingDirection = StorageModule.MovementDirection;
}
// Update crosshair
CrosshairProvider.UpdatePosition(StorageModule.AimingDirection);
MainObject.Velocity = StorageModule.MovementDirection * StorageModule.MovementSpeed;
MainObject.MoveAndSlide();
}
private void Shoot()
{
if (EquippedWeapon == null) return;
var direction = StorageModule.AimingDirection;
// Shoot at the player's last known position
EquippedWeapon.ShootDirection = direction;
//StorageModule.FacingDirection = direction.SnapToCardinal().Normalized();
EquippedWeapon.Shoot(BulletOwner.Player);
}
public override void ProcessState(double delta)
{
base.ProcessState(delta);
}
}