From 9c3f22760bb9074bc31b29b55a4d99205f17cf9e Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 5 Mar 2025 10:55:14 +0100 Subject: [PATCH] Migrated player state machine --- Scenes/InteractionController.cs | 18 ++++++++++++- Scripts/Activables/LevelTeleporter.cs | 8 +++--- Scripts/Activables/PlayerMover.cs | 4 +-- Scripts/Activables/Teleporter.cs | 23 +++++++++-------- .../Components/Actors/ActivationProvider.cs | 2 +- .../Actors/EnemyPossessionMovement.cs | 4 +-- Scripts/Components/FSM/BaseState.cs | 5 ++++ Scripts/Components/FSM/Player/Active.cs | 21 ++++++++-------- Scripts/Components/FSM/Player/Controlling.cs | 3 ++- Scripts/Components/FSM/Player/Cutscene.cs | 5 ++-- Scripts/Components/FSM/Player/Dead.cs | 25 ++++++------------- Scripts/Components/FSM/Player/Init.cs | 6 +++-- .../Components/FSM/Player/PlayerStateBase.cs | 8 ++++++ Scripts/Components/FSM/Player/Teleporting.cs | 4 ++- .../Components/FSM/Player/UnTeleporting.cs | 4 ++- Scripts/Components/FSM/PlayerArea2DModule.cs | 18 +++++++++++++ Scripts/Components/FSM/PlayerStateMachine.cs | 13 +++------- Scripts/Resources/Events/ControlEnemyEvent.cs | 2 +- Scripts/Resources/Events/MovePlayerEvent.cs | 4 +-- 19 files changed, 108 insertions(+), 69 deletions(-) create mode 100644 Scripts/Components/FSM/Player/PlayerStateBase.cs create mode 100644 Scripts/Components/FSM/PlayerArea2DModule.cs diff --git a/Scenes/InteractionController.cs b/Scenes/InteractionController.cs index 097be002..323a4c7f 100644 --- a/Scenes/InteractionController.cs +++ b/Scenes/InteractionController.cs @@ -1,8 +1,9 @@ using Godot; using System; using Cirno.Scripts.Components.Actors; +using Cirno.Scripts.Components.FSM; -public partial class InteractionController : Area2D +public partial class InteractionController : PlayerArea2DModule { [Export] public ActorResourceProvider Health { get; private set; } [Export] public ActorResourceProvider Shield { get; private set; } @@ -35,4 +36,19 @@ public partial class InteractionController : Area2D public override void _Process(double delta) { } + + public override void Init(IStateMachine machine) + { + + } + + public override void Process(double delta) + { + + } + + public override void PhysicsProcess(double delta) + { + + } } diff --git a/Scripts/Activables/LevelTeleporter.cs b/Scripts/Activables/LevelTeleporter.cs index afbc3ffa..9cefc1e5 100644 --- a/Scripts/Activables/LevelTeleporter.cs +++ b/Scripts/Activables/LevelTeleporter.cs @@ -11,18 +11,18 @@ public partial class LevelTeleporter : Teleporter [Export] public string LevelPath {get; private set;} - protected override async Task Teleport(PlayerStateMachine player) + protected override async Task Teleport(IStateMachine player) { if (string.IsNullOrWhiteSpace(LevelPath)) return; //player.RequestMovementDisable(true); - player.SetState((int)PlayerState.Cutscene); + player.SetState(PlayerState.Cutscene); - await TweenPlayer(player); + await TweenPlayer(player.MainObject); _particles.Emitting = true; //await player.Teleport(); - player.SetState((int)PlayerState.UnTeleporting); + player.SetState(PlayerState.UnTeleporting); await Task.Delay((int)(0.6f * 1000)); await Task.Delay((int)(TeleportAnimationLength * 1000)); diff --git a/Scripts/Activables/PlayerMover.cs b/Scripts/Activables/PlayerMover.cs index 0a16e7e7..c8639671 100644 --- a/Scripts/Activables/PlayerMover.cs +++ b/Scripts/Activables/PlayerMover.cs @@ -37,7 +37,7 @@ public partial class PlayerMover : ChainActivable private async Task MovePlayer() { //_gameManager.Player.RequestMovementDisable(true); - _gameManager.Player.SetState((int)PlayerState.Cutscene); + _gameManager.Player.SetState(PlayerState.Cutscene); Tween tween = GetTree().CreateTween(); tween.SetEase(EaseType); @@ -48,7 +48,7 @@ public partial class PlayerMover : ChainActivable await ToSignal(tween, "finished"); //_gameManager.Player.RequestMovementDisable(false); - _gameManager.Player.SetState((int)PlayerState.Cutscene); + _gameManager.Player.SetState(PlayerState.Cutscene); ActivateTargets(); } diff --git a/Scripts/Activables/Teleporter.cs b/Scripts/Activables/Teleporter.cs index f021acd1..946fee3d 100644 --- a/Scripts/Activables/Teleporter.cs +++ b/Scripts/Activables/Teleporter.cs @@ -114,9 +114,10 @@ private AudioStreamPlayer2D _teleportEndSound; _particleTimer = 0; } - private void _on_body_entered(CharacterBody2D area) + private void _on_area_entered(Area2D area) { - if (area is not PlayerStateMachine player) return; + if (!IsEnabled) return; + if (area is not InteractionController interactionController) return; if (!IsPrimed) { @@ -130,16 +131,16 @@ private AudioStreamPlayer2D _teleportEndSound; // Call Teleport here - _ = Teleport(player); + _ = Teleport(interactionController.StateMachine); } - protected virtual async Task Teleport(PlayerStateMachine player) + protected virtual async Task Teleport(IStateMachine player) { if (Target is null) return; //player.RequestMovementDisable(true); - player.SetState((int)PlayerState.Cutscene); + player.SetState(PlayerState.Cutscene); - await TweenPlayer(player); + await TweenPlayer(player.MainObject); PlayTeleportStartSound(); @@ -147,21 +148,21 @@ private AudioStreamPlayer2D _teleportEndSound; FireParticles(); //await player.Teleport(); - player.SetState((int)PlayerState.Teleporting); + player.SetState(PlayerState.Teleporting); await Task.Delay((int)(0.6f * 1000)); await Task.Delay((int)(TeleportAnimationLength * 1000)); Target.PrepareForReceiving(); - player.GlobalPosition = Target.GlobalPosition + TeleportOffset; + player.MainObject.GlobalPosition = Target.GlobalPosition + TeleportOffset; Target.PlayTeleportEndSound(); //await player.UnTeleport(); - player.SetState((int)PlayerState.UnTeleporting); + player.SetState(PlayerState.UnTeleporting); await Task.Delay((int)(0.6f * 1000)); //player.RequestMovementDisable(false); - player.SetState((int)PlayerState.Active); + player.SetState(PlayerState.Active); } public void PlayTeleportStartSound() @@ -174,7 +175,7 @@ private AudioStreamPlayer2D _teleportEndSound; _teleportEndSound?.Play(); } - protected async Task TweenPlayer(PlayerStateMachine player) + protected async Task TweenPlayer(CharacterBody2D player) { await player.TweenGlobalPosition(GlobalPosition + new Vector2(0, -4f), TeleportAnimationLength).PlayAsync(CancellationToken.None); diff --git a/Scripts/Components/Actors/ActivationProvider.cs b/Scripts/Components/Actors/ActivationProvider.cs index 5b3eef05..69009932 100644 --- a/Scripts/Components/Actors/ActivationProvider.cs +++ b/Scripts/Components/Actors/ActivationProvider.cs @@ -23,7 +23,7 @@ public partial class ActivationProvider : Area2D [Signal] public delegate void InteractableAreaExitedEventHandler(Interactable interactable); - public void Init(ActorStateMachine actor) + public void Init(CharacterBody2D actor) { if (SelectorScene is not null && _selector is null) { diff --git a/Scripts/Components/Actors/EnemyPossessionMovement.cs b/Scripts/Components/Actors/EnemyPossessionMovement.cs index 7ab28c8c..084d0848 100644 --- a/Scripts/Components/Actors/EnemyPossessionMovement.cs +++ b/Scripts/Components/Actors/EnemyPossessionMovement.cs @@ -78,7 +78,7 @@ public partial class EnemyPossessionMovement : ActorFreeMovement { GameManager.Instance.CameraTargetObject(_parent); //GameManager.Instance.Player.RequestMovementDisable(true); - GameManager.Instance.Player.SetState((int)PlayerState.Controlling); + GameManager.Instance.Player.SetState(PlayerState.Controlling); _previousAiState = _actorAi.Ai; _actorAi.Ai = AiState.Controlled; @@ -94,7 +94,7 @@ public partial class EnemyPossessionMovement : ActorFreeMovement GameManager.Instance.CameraTargetPlayer(); //GameManager.Instance.Player.RequestMovementDisable(false); - GameManager.Instance.Player.SetState((int)PlayerState.Active); + GameManager.Instance.Player.SetState(PlayerState.Active); DamageReceiver.BulletGroup = BulletOwner.Enemy; diff --git a/Scripts/Components/FSM/BaseState.cs b/Scripts/Components/FSM/BaseState.cs index da0e95a4..2b4a24c4 100644 --- a/Scripts/Components/FSM/BaseState.cs +++ b/Scripts/Components/FSM/BaseState.cs @@ -35,6 +35,11 @@ public abstract partial class BaseState : Node2D, IState PlayerState.Active; private Vector2 _movementDirection { get; set; } public Vector2 FacingDirection { get; private set; } = Vector2.Down; @@ -36,18 +37,16 @@ public partial class Active : PlayerFSMState public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed; - private PlayerStateMachine _player; + private CharacterBody2D _player; private Hud _hud; - public override void Init(ActorStateMachine stateMachine) + public override void Init(IStateMachine machine) { - base.Init(stateMachine); + base.Init(machine); _hud = Hud.Instance; - _player = (PlayerStateMachine)stateMachine; - _damageReceiver.Death += () => { ChangeState(PlayerState.Dead); @@ -70,12 +69,12 @@ public partial class Active : PlayerFSMState _damageReceiver.RefillHealth(); _damageReceiver.RefillShield(); - _activationProvider.Init(stateMachine); + _activationProvider.Init(MainObject); //_weaponProvider = stateMachine.GetNode("WeaponProvider"); //_animationProvider = stateMachine.GetNode("AnimationProvider"); - _weaponProvider.Init(stateMachine); + _weaponProvider.Init(MainObject); } public override void EnterState() @@ -102,9 +101,9 @@ public partial class Active : PlayerFSMState public override void PhysicsProcessState(double delta) { - _stateMachine.Velocity = _movementDirection * MovementSpeed; + MainObject.Velocity = _movementDirection * MovementSpeed; - _stateMachine.MoveAndSlide(); + MainObject.MoveAndSlide(); } public override void ProcessState(double delta) @@ -130,7 +129,7 @@ public partial class Active : PlayerFSMState } } - _animationProvider.SetAnimation(_stateMachine.Velocity); + _animationProvider.SetAnimation(MainObject.Velocity); _crosshairProvider.UpdatePosition(FacingDirection); diff --git a/Scripts/Components/FSM/Player/Controlling.cs b/Scripts/Components/FSM/Player/Controlling.cs index 5f87aa19..17018911 100644 --- a/Scripts/Components/FSM/Player/Controlling.cs +++ b/Scripts/Components/FSM/Player/Controlling.cs @@ -2,8 +2,9 @@ namespace Cirno.Scripts.Components.FSM.Player; -public partial class Controlling : PlayerFSMState +public partial class Controlling : PlayerStateBase { + public override PlayerState StateId => PlayerState.Controlling; [Export] private PlayerAnimationProvider _animationProvider; diff --git a/Scripts/Components/FSM/Player/Cutscene.cs b/Scripts/Components/FSM/Player/Cutscene.cs index ccb78aee..938b47bb 100644 --- a/Scripts/Components/FSM/Player/Cutscene.cs +++ b/Scripts/Components/FSM/Player/Cutscene.cs @@ -2,8 +2,9 @@ namespace Cirno.Scripts.Components.FSM.Player; -public partial class Cutscene : PlayerFSMState +public partial class Cutscene : PlayerStateBase { + public override PlayerState StateId => PlayerState.Cutscene; [Export] private PlayerAnimationProvider _animationProvider; @@ -19,7 +20,7 @@ public partial class Cutscene : PlayerFSMState public override void ProcessState(double delta) { - _animationProvider.SetAnimation(_stateMachine.Velocity); + _animationProvider.SetAnimation(MainObject.Velocity); } public override void PhysicsProcessState(double delta) diff --git a/Scripts/Components/FSM/Player/Dead.cs b/Scripts/Components/FSM/Player/Dead.cs index 32d88b37..56917cb4 100644 --- a/Scripts/Components/FSM/Player/Dead.cs +++ b/Scripts/Components/FSM/Player/Dead.cs @@ -3,8 +3,10 @@ using Godot; namespace Cirno.Scripts.Components.FSM.Player; -public partial class Dead : PlayerFSMState +public partial class Dead : PlayerStateBase { + public override PlayerState StateId => PlayerState.Dead; + [Export] private PlayerAnimationProvider _animationProvider; @@ -13,30 +15,19 @@ public partial class Dead : PlayerFSMState [Export] private ActorResourceProvider _healthProvider; - - private GameManager _gameManager; - private Hud _hud; - - public override void Init(ActorStateMachine stateMachine) - { - base.Init(stateMachine); - - _gameManager = GameManager.Instance; - _hud = Hud.Instance; - } public override void EnterState() { _animationProvider.PlayDeathAnimation(); // show game over - _hud.ShowGameOver(); + Hud.Instance.ShowGameOver(); } public override void ExitState() { // Hide game over - _hud.HideGameOver(); + Hud.Instance.HideGameOver(); } public override void ProcessState(double delta) @@ -55,10 +46,10 @@ public partial class Dead : PlayerFSMState public void Respawn() { - _stateMachine.GlobalPosition = _gameManager.LastCheckpointPosition; + MainObject.GlobalPosition = GameManager.Instance.LastCheckpointPosition; _healthProvider.FillResource(); - _gameManager.ClearBullets(); + GameManager.Instance.ClearBullets(); - _stateMachine.SetState((int)PlayerState.Active); + ChangeState(PlayerState.Active); } } \ No newline at end of file diff --git a/Scripts/Components/FSM/Player/Init.cs b/Scripts/Components/FSM/Player/Init.cs index 3c1fe8f7..cad0b296 100644 --- a/Scripts/Components/FSM/Player/Init.cs +++ b/Scripts/Components/FSM/Player/Init.cs @@ -4,8 +4,10 @@ using Godot; namespace Cirno.Scripts.Components.FSM.Player; -public partial class Init : PlayerFSMState +public partial class Init : PlayerStateBase { + public override PlayerState StateId => PlayerState.Init; + [Export] private PlayerAnimationProvider _animationProvider; public override void EnterState() @@ -32,6 +34,6 @@ public partial class Init : PlayerFSMState private async Task AutoSwitchToStart() { await Task.Delay(500); - _stateMachine.SetState((int)PlayerState.Active); + StateMachine.SetState(PlayerState.Active); } } diff --git a/Scripts/Components/FSM/Player/PlayerStateBase.cs b/Scripts/Components/FSM/Player/PlayerStateBase.cs new file mode 100644 index 00000000..c7974cf1 --- /dev/null +++ b/Scripts/Components/FSM/Player/PlayerStateBase.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace Cirno.Scripts.Components.FSM.Player; + +public abstract partial class PlayerStateBase : BaseState +{ + +} \ No newline at end of file diff --git a/Scripts/Components/FSM/Player/Teleporting.cs b/Scripts/Components/FSM/Player/Teleporting.cs index 8870fde9..a8eaa1ac 100644 --- a/Scripts/Components/FSM/Player/Teleporting.cs +++ b/Scripts/Components/FSM/Player/Teleporting.cs @@ -2,8 +2,10 @@ namespace Cirno.Scripts.Components.FSM.Player; -public partial class Teleporting : PlayerFSMState +public partial class Teleporting : PlayerStateBase { + public override PlayerState StateId => PlayerState.Init; + [Export] private PlayerAnimationProvider _animationProvider; diff --git a/Scripts/Components/FSM/Player/UnTeleporting.cs b/Scripts/Components/FSM/Player/UnTeleporting.cs index 1a49cd26..1c414be9 100644 --- a/Scripts/Components/FSM/Player/UnTeleporting.cs +++ b/Scripts/Components/FSM/Player/UnTeleporting.cs @@ -2,8 +2,10 @@ namespace Cirno.Scripts.Components.FSM.Player; -public partial class UnTeleporting : PlayerFSMState +public partial class UnTeleporting : PlayerStateBase { + public override PlayerState StateId => PlayerState.UnTeleporting + ; [Export] private PlayerAnimationProvider _animationProvider; diff --git a/Scripts/Components/FSM/PlayerArea2DModule.cs b/Scripts/Components/FSM/PlayerArea2DModule.cs new file mode 100644 index 00000000..b4bdf8f1 --- /dev/null +++ b/Scripts/Components/FSM/PlayerArea2DModule.cs @@ -0,0 +1,18 @@ +using Godot; + +namespace Cirno.Scripts.Components.FSM; + +public abstract partial class PlayerArea2DModule : Area2D, IModule +{ + public IStateMachine StateMachine { get; private set; } + + public CharacterBody2D CharacterBody => StateMachine.MainObject; + + + public virtual void Init(IStateMachine machine) + { + StateMachine = machine; + } + public abstract void Process(double delta); + public abstract void PhysicsProcess(double delta); +} \ No newline at end of file diff --git a/Scripts/Components/FSM/PlayerStateMachine.cs b/Scripts/Components/FSM/PlayerStateMachine.cs index 3ea9cf06..8553ad7d 100644 --- a/Scripts/Components/FSM/PlayerStateMachine.cs +++ b/Scripts/Components/FSM/PlayerStateMachine.cs @@ -3,15 +3,8 @@ using Godot; namespace Cirno.Scripts.Components.FSM; -public partial class PlayerStateMachine : ActorStateMachine +public partial class PlayerStateMachine : StateMachineBase { - [Export] - public PlayerState InitialState { get; private set; } - - public override void _Ready() - { - base._Ready(); - - this.SetState((int)InitialState); - } + [Export] public override PlayerState InitialState { get; protected set; } = PlayerState.Init; + } diff --git a/Scripts/Resources/Events/ControlEnemyEvent.cs b/Scripts/Resources/Events/ControlEnemyEvent.cs index f37393de..dc9ade28 100644 --- a/Scripts/Resources/Events/ControlEnemyEvent.cs +++ b/Scripts/Resources/Events/ControlEnemyEvent.cs @@ -30,7 +30,7 @@ public partial class ControlEnemyEvent : EventResource if (_parent.GetNode(Target) is Enemy enemy) { _gameManager.CameraTargetObject(enemy); - GameManager.Instance.Player.SetState((int)PlayerState.Controlling); + GameManager.Instance.Player.SetState(PlayerState.Controlling); // _gameManager.Player.RequestMovementDisable(true); enemy.AssumeControl(); // TODO: Do this on the enemy as a module instead diff --git a/Scripts/Resources/Events/MovePlayerEvent.cs b/Scripts/Resources/Events/MovePlayerEvent.cs index 26fe711e..68e1b4f7 100644 --- a/Scripts/Resources/Events/MovePlayerEvent.cs +++ b/Scripts/Resources/Events/MovePlayerEvent.cs @@ -35,7 +35,7 @@ public partial class MovePlayerEvent : EventResource protected async Task MovePlayer() { - GameManager.Instance.Player.SetState((int)PlayerState.Cutscene); + GameManager.Instance.Player.SetState(PlayerState.Cutscene); //_gameManager.Player.RequestMovementDisable(true); Tween tween = _gameManager.GetTree().CreateTween(); @@ -46,7 +46,7 @@ public partial class MovePlayerEvent : EventResource // Wait for the tween to finish await ToSignal(tween, "finished"); - GameManager.Instance.Player.SetState((int)PlayerState.Active); + GameManager.Instance.Player.SetState(PlayerState.Active); //_gameManager.Player.RequestMovementDisable(false); _isComplete = true;