using System; using System.Threading.Tasks; using Cirno.Scripts.Utils; using Godot; namespace Cirno.Scripts.Components.Actors; public partial class KeyboardInputProvider : InputProvider { [ExportCategory("Movement")] [Export] public StringName LeftAxisName { get; private set; } = "left"; [Export] public StringName RightAxisName { get; private set; } = "right"; [Export] public StringName UpAxisName { get; private set; } = "up"; [Export] public StringName DownAxisName { get; private set; } = "down"; [ExportCategory("Aiming")] [Export] public StringName LeftAimName { get; private set; } = "aim_left"; [Export] public StringName RightAimName { get; private set; } = "aim_right"; [Export] public StringName UpAimName { get; private set; } = "aim_up"; [Export] public StringName DownAimName { get; private set; } = "aim_down"; [ExportCategory("Action Names")] [Export] private StringName _shootActionName = "shoot"; [Export] private StringName _useActionName = "Use"; [Export] private StringName _scanActionName = "scan"; [Export] private StringName _strafeActionName = "strafe"; [Export] private StringName _nextWeaponActionName = "next_weapon"; [Export] private StringName _previousWeaponActionName = "previous_weapon"; [Export] private StringName _inventoryActionName = "inventory"; [Export] private StringName _freezeActionName = "Freeze"; [Export] private StringName _reloadActionName = "Reload"; private IMouseAimProvider _mouseAImProvider; private enum AimInputMethod { RightStick, Mouse } private AimInputMethod _lastUsedInput = AimInputMethod.RightStick; public override void _Ready() { CallDeferred(MethodName.DelayedRegisterGameManager); } private void DelayedRegisterGameManager() { _mouseAImProvider = this.GetParent().GetNodeOrNull("MouseAimProvider"); if (_mouseAImProvider is null) { GD.Print("Mouse aim provider is null"); } GameStateManager.Instance.GameStateChange += InstanceOnGameStateChange; _enabled = true; } private bool _enabled = false; private void InstanceOnGameStateChange(GameState state) { if (state is not GameState.Playing) return; _enabled = false; _ = DelayResume(); } private async Task DelayResume() { //await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame); await Task.Delay(200); _enabled = true; } public override Vector2 GetMovementInput() { return Input.GetVector(LeftAxisName, RightAxisName, UpAxisName, DownAxisName); } public override Vector2 GetAimInput() { // TODO: Make a solution that does not rotate in 2D Vector2 rightStickInput = GetRightStickInput().Rotated(Mathf.DegToRad(-45f)); Vector2 mouseInput = GetMouseAimInput(); // Determine which input method to use if (rightStickInput != Vector2.Zero) { _lastUsedInput = AimInputMethod.RightStick; } else if (mouseInput != Vector2.Zero) { _lastUsedInput = AimInputMethod.Mouse; } return _lastUsedInput == AimInputMethod.RightStick ? rightStickInput : mouseInput; } private Vector2 GetRightStickInput() { return Input.GetVector(LeftAimName, RightAimName, UpAimName, DownAimName); // return new Vector2( // Input.GetAxis(LeftAimName, RightAimName), // Input.GetAxis(UpAimName, DownAimName) // ); } private Vector2 GetMouseAimInput() { return _mouseAImProvider?.GetMouseAimInput() ?? Vector2.Zero; } public override bool GetActionJustPressed(string action) { return Input.IsActionJustPressed(action); } public override bool GetActionPressed(string action) { return Input.IsActionPressed(action); } public override bool GetInventoryJustPressed() { return GetActionJustPressed(_inventoryActionName); } public override bool GetShootPressed() { return _enabled && GetActionPressed(_shootActionName); } public override bool GetShootJustPressed() { return GetActionJustPressed(_shootActionName); } public override bool GetUseJustPressed() { return GetActionJustPressed(_useActionName); } public override bool GetScanJustPressed() { return GetActionJustPressed(_scanActionName); } public override bool GetStrafePressed() { return GetActionPressed(_strafeActionName); } public override bool GetWeaponNextJustPressed() { return GetActionJustPressed(_nextWeaponActionName); } public override bool GetWeaponPreviousJustPressed() { return GetActionJustPressed(_previousWeaponActionName); } public override bool GetPauseJustPressed() { return GlobalInputManager.IsPauseJustPressed(); } public override bool GetFreezeJustPressed() { return GetActionJustPressed(_freezeActionName); } public override bool GetFreezePressed() { return GetActionPressed(_freezeActionName); } public override bool GetReloadJustPressed() { return GetActionJustPressed(_reloadActionName); } public override bool GetReloadPressed() { return GetActionPressed(_reloadActionName); } }