Game state manager and restored inventory

This commit is contained in:
Marco 2025-06-25 15:36:50 +02:00
commit a0ec2f3d74
27 changed files with 1283 additions and 1175 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -55,8 +55,9 @@ script = ExtResource("1_vsywg")
[node name="Init" type="Node" parent="StateMachine"]
script = ExtResource("2_3oyrx")
[node name="Active" type="Node" parent="StateMachine" node_paths=PackedStringArray("_moduleNodes")]
[node name="Active" type="Node" parent="StateMachine" node_paths=PackedStringArray("_inputProvider", "_moduleNodes")]
script = ExtResource("3_cc7e7")
_inputProvider = NodePath("../../InputProvider")
_moduleNodes = [NodePath("../../InputProvider"), NodePath("../../MovementModule"), NodePath("../../ShadowModule"), NodePath("../../InteractionController"), NodePath("../../ActivationProvider"), NodePath("../../WeaponModule"), NodePath("../../AcidDeathModule")]
[node name="Dead" type="Node" parent="StateMachine"]

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dhm44md5hllhn"]
[ext_resource type="Script" uid="uid://y776grpi3a30" path="res://Scripts/Utils/GlobalInputManager.cs" id="1_kms28"]
[node name="GlobalInputManager" type="Node"]
script = ExtResource("1_kms28")

View file

@ -1,4 +1,5 @@
using Godot;
using Cirno.Scripts.Utils;
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Activables;
@ -36,7 +37,7 @@ public partial class DialogueStarter : ChainActivable
private void OnTimelineEnded()
{
_gameManager.ChangeState(GameState.Playing);
GameStateManager.SetState(GameState.Playing);
if (_dialogic.IsConnected("timeline_ended", Callable.From(OnTimelineEnded)))
{
_dialogic.Disconnect("timeline_ended", Callable.From(OnTimelineEnded));
@ -60,7 +61,7 @@ public partial class DialogueStarter : ChainActivable
var dialogicNode = _dialogic.Call("start", _trackName);
((Node)dialogicNode).ProcessMode = ProcessModeEnum.Always;
_gameManager.ChangeState(GameState.Dialogue);
GameStateManager.SetState(GameState.Dialogue);
return true;
// Script dialogic = ResourceLoader.Load("res://addons/dialogic/Other/DialogicClass.gd") as Script;
@ -73,7 +74,7 @@ public partial class DialogueStarter : ChainActivable
{
_dialogueActive = false;
Hud.Instance?.HideHud();
_gameManager.ChangeState(GameState.Playing);
GameStateManager.SetState(GameState.Playing);
ActivateTargets();
// foreach (var activationTarget in _dialogueEndActivationTargets)
// {

View file

@ -1,6 +1,7 @@
using System.Linq;
using Cirno.Scripts.Resources;
using Cirno.Scripts.UI;
using Cirno.Scripts.Utils;
using Godot;
using Godot.Collections;
@ -18,7 +19,7 @@ public partial class VendingMachine : Interactable
public override bool Activate(ActivationType activationType = ActivationType.Toggle)
{
GameManager.Instance.ChangeState(GameState.Shop);
GameStateManager.SetState(GameState.Shop);
var ui = UiScene.Instantiate<VendingMachineUi>();

View file

@ -47,14 +47,15 @@ public partial class EnemyPossessionMovement : ActorFreeMovement
{
Shoot();
}
if (GetActionJustPressed(ControlEndAction))
{
if (GameManager.Instance.ToggleControlMode() is GameState.Playing)
{
ResumeControl();
}
}
// TODO: Restore control
// if (GetActionJustPressed(ControlEndAction))
// {
// if (GameManager.Instance.ToggleControlMode() is GameState.Playing)
// {
// ResumeControl();
// }
// }
}
private void Shoot()

View file

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.Components.Actors;
@ -25,7 +26,7 @@ public partial class KeyboardInputProvider : InputProvider
[Export] private StringName _nextWeaponActionName = "next_weapon";
[Export] private StringName _previousWeaponActionName = "previous_weapon";
[Export] private StringName _inventoryActionName = "inventory";
[Export] private StringName _pauseActionName = "pause";
[Export] private StringName _freezeActionName = "Freeze";
[Export] private StringName _reloadActionName = "Reload";
@ -54,20 +55,7 @@ public partial class KeyboardInputProvider : InputProvider
GD.Print("Mouse aim provider is null");
}
if (GameManager.Instance is null)
{
GD.Print("No GameManager found for keyboard inputprovider");
}
else
{
GameManager.Instance.GameStateChange += InstanceOnGameStateChange;
}
if (GameController.Instance is not null)
{
GameController.Instance.GameStateChange += InstanceOnGameStateChange;
}
GameStateManager.Instance.GameStateChange += InstanceOnGameStateChange;
_enabled = true;
}
@ -178,7 +166,7 @@ public partial class KeyboardInputProvider : InputProvider
public override bool GetPauseJustPressed()
{
return GetActionJustPressed(_pauseActionName);
return GlobalInputManager.IsPauseJustPressed();
}
public override bool GetFreezeJustPressed()

View file

@ -1,4 +1,6 @@
using Godot;
using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.Components.FSM._3DPlayer;
@ -7,6 +9,7 @@ public partial class Active : BaseState<PlayerState, CharacterBody3D>
public override PlayerState StateId => PlayerState.Active;
private CharacterBody3D _player;
[Export] private InputProvider _inputProvider;
public override void Init(IStateMachine<PlayerState, CharacterBody3D> machine)
{
@ -84,12 +87,28 @@ public partial class Active : BaseState<PlayerState, CharacterBody3D>
{
base.ProcessState(delta);
HandleInputHotkeys();
}
private void HandleInputHotkeys()
{
if (_inputProvider.GetInventoryJustPressed())
{
GameStateManager.SetState(GameState.Inventory);
return;
}
if (_inputProvider.GetPauseJustPressed())
{
GameStateManager.Instance.Pause();
//PauseDeferred();
return;
}
}
private void PauseDeferred()
{
GameManager.Instance.Pause();
GameStateManager.Instance.Pause();
}

View file

@ -1,5 +1,6 @@
using System;
using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.Components.FSM.Player;
@ -180,7 +181,7 @@ public partial class Active : PlayerStateBase
if (_inputProvider.GetInventoryJustPressed())
{
GameManager.Instance.ChangeState(GameState.Inventory);
GameStateManager.SetState(GameState.Inventory);
}
if (_inputProvider.GetPauseJustPressed())
@ -192,7 +193,7 @@ public partial class Active : PlayerStateBase
private void PauseDeferred()
{
GameManager.Instance.Pause();
GameStateManager.Instance.Pause();
}
private void HandleShoot()

View file

@ -1,4 +1,5 @@
using Cirno.Scripts.Components.Actors;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.Components.FSM.Player.Hacking;
@ -180,7 +181,7 @@ public partial class HackingActive : PlayerStateBase
if (_inputProvider.GetInventoryJustPressed())
{
GameManager.Instance.ChangeState(GameState.Inventory);
GameStateManager.SetState(GameState.Inventory);
}
if (_inputProvider.GetPauseJustPressed())
@ -192,7 +193,7 @@ public partial class HackingActive : PlayerStateBase
private void PauseDeferred()
{
GameManager.Instance.Pause();
GameStateManager.Instance.Pause();
}
private void HandleShoot()

View file

@ -3,6 +3,7 @@ using Cirno.Scripts.Components.FSM._3DPlayer;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Misc;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Utils;
using Godot;
using Godot.Collections;
@ -19,16 +20,10 @@ public partial class GameController : Node
[Export] private Marker3D _cameraTarget;
public Vector3? PlayerPosition => _player?.GlobalPosition ?? null;
public Vector3? PlayerVelocity => _player?.Velocity ?? null;
public GameState GameState { get; private set; }
[Signal]
public delegate void GameStateChangeEventHandler(GameState state);
[Signal]
public delegate void ManagerReadyEventHandler();
[Export] public StringName PauseActionName { get; private set; } = "pause";
[Export] public MapResource MapResource { get; private set; }
[Export] public PackedScene PlayerTemplate { get; set; }
@ -43,6 +38,8 @@ public partial class GameController : Node
private Vector3 _lastCheckPointPosition;
private GameState GameState => GameStateManager.Instance.GameState;
public Vector3 LastCheckPointPosition
{
get => _lastCheckPointPosition;
@ -52,6 +49,12 @@ public partial class GameController : Node
public override void _Ready()
{
Instance = this;
var gsm = new GameStateManager();
gsm.ProcessMode = ProcessModeEnum.Always;
this.AddChild(gsm);
gsm.Init(GameState.Playing);
RenderingServer.SetDefaultClearColor(Colors.Black);
if (GlobalState.Instance.SessionSettings.GameMode is GameMode.Roguelite)
{
@ -90,7 +93,7 @@ public partial class GameController : Node
if (_hud != null)
{
this.GameStateChange += _hud.OnGameStateChanged;
GameStateManager.Instance.GameStateChange += _hud.OnGameStateChanged;
}
if (_inventoryManager != null && _hud != null)
@ -100,7 +103,7 @@ public partial class GameController : Node
//PlayerRespawned += OnPlayerRespawned;
GameState = GameState.Playing;
//GameStateManager.Instance.GameState = GameState.Playing;
CallDeferred(MethodName.DelayPlayerSpawn);
@ -112,86 +115,6 @@ public partial class GameController : Node
{
EmitSignalManagerReady();
}
public override void _Process(double delta)
{
if (GameState is GameState.Paused && Input.IsActionJustPressed(PauseActionName))
{
Unpause();
}
}
public void Pause()
{
if (GameState == GameState.Playing)
{
ChangeState(GameState.Paused);
}
}
public void Unpause()
{
if (GameState == GameState.Paused)
{
CallDeferred(MethodName.ChangeState, (int)GameState.Playing);
//ChangeState(GameState.Playing);
}
}
public GameState ToggleControlMode()
{
if (GameState is GameState.Playing)
{
ChangeState(GameState.Controlling);
}
else if (GameState is GameState.Controlling)
{
ChangeState(GameState.Playing);
}
return GameState;
}
public void ChangeState(GameState state)
{
if (state == GameState) return;
GameState = state;
EmitSignal(SignalName.GameStateChange, (int)state);
GD.Print($"Game state changed to {state}");
switch (state)
{
case GameState.Paused:
case GameState.Dialogue:
case GameState.Shop:
case GameState.Inventory:
GlobalState.Instance.ChangeCursor(true);
GetTree().SetPause(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
break;
case GameState.Playing:
case GameState.Controlling:
//Input.MouseMode = Input.MouseModeEnum.Confined;
GlobalState.Instance.ChangeCursor(false);
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
case GameState.Menu:
GlobalState.Instance.ChangeCursor(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
}
}
private void DelayedUnpause()
{
GetTree().SetPause(false);
}
private void DelayPlayerSpawn()
{

View file

@ -19,8 +19,6 @@ public partial class GameManager : Node2D
private PlayerFSMProxy _player;
public GameState GameState { get; private set; }
public PlayerStateMachine Player => _player.PlayerFSM;
private Node2D _cameraTarget;
@ -52,9 +50,6 @@ public partial class GameManager : Node2D
private Node2D _bulletsContainer;
public Node2D BulletsContainer => _bulletsContainer;
[Signal]
public delegate void GameStateChangeEventHandler(GameState state);
[Signal]
public delegate void PlayerRespawnedEventHandler();
@ -76,6 +71,12 @@ public partial class GameManager : Node2D
public override void _Ready()
{
Instance = this;
var gsm = new GameStateManager();
gsm.ProcessMode = ProcessModeEnum.Always;
this.AddChild(gsm);
gsm.Init(GameState.Playing);
RenderingServer.SetDefaultClearColor(Colors.Black);
if (GlobalState.Instance.SessionSettings.GameMode is GameMode.Roguelite)
{
@ -116,7 +117,7 @@ public partial class GameManager : Node2D
if (_hud != null)
{
this.GameStateChange += _hud.OnGameStateChanged;
GameStateManager.Instance.GameStateChange += _hud.OnGameStateChanged;
}
if (_inventoryManager != null && _hud != null)
@ -128,8 +129,7 @@ public partial class GameManager : Node2D
}
PlayerRespawned += OnPlayerRespawned;
GameState = GameState.Playing;
//_ = DelayPlayerSpawn();
@ -166,14 +166,6 @@ public partial class GameManager : Node2D
//_inventoryManager.Load(settings.Items);
}
public override void _Process(double delta)
{
if (GameState is GameState.Paused && Input.IsActionJustPressed(PauseActionName))
{
Unpause();
}
}
private void DelayPlayerSpawn()
{
if (SpawnMarkers.Any())
@ -316,73 +308,6 @@ public partial class GameManager : Node2D
// }
// }
public void Pause()
{
if (GameState == GameState.Playing)
{
ChangeState(GameState.Paused);
}
}
public void Unpause()
{
if (GameState == GameState.Paused)
{
CallDeferred(MethodName.ChangeState, (int)GameState.Playing);
//ChangeState(GameState.Playing);
}
}
public GameState ToggleControlMode()
{
if (GameState is GameState.Playing)
{
ChangeState(GameState.Controlling);
}
else if (GameState is GameState.Controlling)
{
ChangeState(GameState.Playing);
}
return GameState;
}
public void ChangeState(GameState state)
{
if (state == GameState) return;
GameState = state;
EmitSignal(SignalName.GameStateChange, (int)state);
GD.Print($"Game state changed to {state}");
switch (state)
{
case GameState.Paused:
case GameState.Dialogue:
case GameState.Shop:
case GameState.Inventory:
GlobalState.Instance.ChangeCursor(true);
GetTree().SetPause(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
break;
case GameState.Playing:
case GameState.Controlling:
//Input.MouseMode = Input.MouseModeEnum.Confined;
GlobalState.Instance.ChangeCursor(false);
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
case GameState.Menu:
GlobalState.Instance.ChangeCursor(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
}
}
private void DelayedUnpause()
{
GetTree().SetPause(false);

View file

@ -311,39 +311,6 @@ public partial class Hud : CanvasLayer
}
}
// public void RemoveInventoryItem(string itemKey, int currentAmount)
// {
// if (_items.TryGetValue(itemKey, out var itm))
// {
// if (currentAmount <= 0)
// {
// itm.Container.QueueFree();
// _items.Remove(itemKey);
// }
// else
// {
// if (itm.Item.UiType == UiItemType.IconText)
// {
// itm.Label.Text = currentAmount.ToString();
// }
// }
// }
// else
// {
// GD.Print($"Tried to remove item {itemKey} but it was not found");
// }
//
// // var containerItem = _items.FirstOrDefault(x => x.Item == item);
// // if (containerItem == null)
// // {
// // GD.Print($"Tried to remove item {item.ItemName} but it was not found");
// // return;
// // }
// //
// // containerItem.Container.QueueFree();
//
// }
private void SpawnDebugMenu()
{
ClearPauseMenu();
@ -364,7 +331,7 @@ public partial class Hud : CanvasLayer
menu.MenuClosed += () =>
{
DebugMenuHolder.Visible = false;
if (GameManager.Instance.GameState is GameState.Paused)
if (GameStateManager.Instance.GameState is GameState.Paused)
{
SpawnPauseMenu();
}

View file

@ -9,6 +9,7 @@ using Cirno.Scripts.Resources;
using Godot.Collections;
using System.Threading.Tasks;
using Cirno.Scripts.Controllers;
using Cirno.Scripts.Utils;
public partial class PlayerMovement : CharacterBody2D, IDestructible
{
@ -157,7 +158,7 @@ public partial class PlayerMovement : CharacterBody2D, IDestructible
//_gameManager = this.GetGameManager();
_inventoryManager = this.GetInventoryManager();
_gameManager.GameStateChange += GameManagerOnGameStateChange;
GameStateManager.Instance.GameStateChange += GameManagerOnGameStateChange;
if (SelectorScene != null)
{

View file

@ -27,10 +27,11 @@ public partial class ControlActorEvent : EventResource
if (_parent.GetNode<Node2D>(Target) is Actor enemy)
{
if (GameManager.Instance.ToggleControlMode() is GameState.Controlling)
{
enemy.AssumeControl();
}
// TODO: Restore control
// if (GameManager.Instance.ToggleControlMode() is GameState.Controlling)
// {
// enemy.AssumeControl();
// }
}
_isComplete = true;

View file

@ -3,6 +3,7 @@ using System;
using Cirno.Scripts;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Resources.DebugMenu;
using Cirno.Scripts.Utils;
using Godot.Collections;
using DebugMapSelectData = Cirno.Scripts.Resources.DebugMenu.DebugMapSelectData;
@ -26,9 +27,9 @@ public partial class DebugMenu : MenuBase
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
if (GameManager.Instance is not null)
if (GameStateManager.Instance is not null)
{
GameManager.Instance.GameStateChange += OnGameStateChange;
GameStateManager.Instance.GameStateChange += OnGameStateChange;
}
DefaultSelectedButton.GrabFocus();
@ -63,7 +64,7 @@ public partial class DebugMenu : MenuBase
{
if (state is not GameState.Paused)
{
GameManager.Instance.GameStateChange -= OnGameStateChange;
GameStateManager.Instance.GameStateChange -= OnGameStateChange;
CloseMenu();
}
@ -91,9 +92,9 @@ public partial class DebugMenu : MenuBase
private void ButtonOnPressed(DebugMapSelectResource scene)
{
if (GameManager.Instance is not null)
if (GameStateManager.Instance is not null)
{
GameManager.Instance.Unpause();
GameStateManager.Instance.Unpause();
}
GlobalState.Instance.GoToScene(scene.ScenePath, scene.StartData);
}

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.UI;
@ -29,7 +30,7 @@ public partial class InventoryMenu : TabContainer
{
if (Visible)
{
GameManager.Instance.ChangeState(GameState.Playing);
GameStateManager.Instance.ChangeState(GameState.Playing);
//CallDeferred(MethodName.HideInventory);
}
// else
@ -55,9 +56,9 @@ public partial class InventoryMenu : TabContainer
//ItemActivated += OnItemSelected;
// TODO: Move this on the game manager/controller side
if (GameManager.Instance is not null)
if (GameStateManager.Instance is not null)
{
GameManager.Instance.GameStateChange += state =>
GameStateManager.Instance.GameStateChange += state =>
{
switch (state)
{

View file

@ -3,6 +3,7 @@ using System;
using System.Linq;
using Cirno.Scripts;
using Cirno.Scripts.UI;
using Cirno.Scripts.Utils;
using Godot.Collections;
public partial class ItemsMenu : ItemList
@ -53,7 +54,7 @@ public partial class ItemsMenu : ItemList
InventoryManager.Instance.TryGetItem(item, out var lootItem);
if (!lootItem.Item.Selectable) return;
GameManager.Instance.ChangeState(GameState.Playing);
GameStateManager.Instance.ChangeState(GameState.Playing);
InventoryManager.Instance.UseItem(item);
}

View file

@ -1,12 +1,10 @@
using Godot;
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.UI;
public partial class PauseMenu : Control
{
[Export]
public StringName PauseActionName = "pause";
[ExportGroup("Scenes")]
[Export]
public string MainMenuScene { get; private set; }
@ -43,9 +41,9 @@ public partial class PauseMenu : Control
public override void _Process(double delta)
{
if (_gameManager.GameState == GameState.Paused && Input.IsActionJustPressed(PauseActionName))
if (GameStateManager.Instance.GameState is GameState.Paused && GlobalInputManager.IsPauseJustPressed())
{
_gameManager.Unpause();
GameStateManager.Instance.Unpause();
}
}
@ -56,12 +54,12 @@ public partial class PauseMenu : Control
private void ResumeButtonOnPressed()
{
_gameManager.Unpause();
GameStateManager.Instance.Unpause();
}
private void QuitButtonOnPressed()
{
_gameManager.Unpause();
GameStateManager.Instance.Unpause();
GlobalState.Instance.ChangeCursor(true);
GlobalState.Instance.GotoScene(MainMenuScene);
//GetTree().ChangeSceneToFile(MainMenuScene);

View file

@ -1,6 +1,7 @@
using System.Linq;
using Cirno.Scripts.Actors;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Utils;
using Godot;
using Godot.Collections;
@ -74,7 +75,7 @@ public partial class VendingMachineUi : CanvasLayer
private void Exit()
{
GD.Print("Closing");
GameManager.Instance.ChangeState(GameState.Playing);
GameStateManager.Instance.ChangeState(GameState.Playing);
QueueFree();
}
}

View file

@ -40,14 +40,7 @@ public partial class DialogueTools : RefCounted
private void ChangeState(GameState state)
{
if (GameManager.Instance is not null)
{
GameManager.Instance.ChangeState(state);
}
else if (GameController.Instance is not null)
{
GameController.Instance.ChangeState(state);
}
GameStateManager.Instance.ChangeState(state);
}
private void CreateSkipListener(Node parent)

View file

@ -0,0 +1,90 @@
using Godot;
namespace Cirno.Scripts.Utils;
public partial class GameStateManager : Node
{
public static GameStateManager Instance { get; private set; }
public GameState GameState { get; private set; }
[Signal] public delegate void GameStateChangeEventHandler(GameState state);
public void Init(GameState initialState)
{
Instance = this;
GameState = initialState;
}
public void Pause()
{
if (GameState == GameState.Playing)
{
ChangeState(GameState.Paused);
}
}
public void Unpause()
{
if (GameState == GameState.Paused)
{
CallDeferred(MethodName.ChangeState, (int)GameState.Playing);
//ChangeState(GameState.Playing);
}
}
public static void SetState(GameState state)
{
GameStateManager.Instance.ChangeState(state);
}
public void ChangeState(GameState state)
{
if (state == GameState) return;
GameState = state;
EmitSignal(SignalName.GameStateChange, (int)state);
GD.Print($"Game state changed to {state}");
switch (state)
{
case GameState.Paused:
case GameState.Dialogue:
case GameState.Shop:
case GameState.Inventory:
GlobalState.Instance.ChangeCursor(true);
GetTree().SetPause(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
break;
case GameState.Playing:
case GameState.Controlling:
//Input.MouseMode = Input.MouseModeEnum.Confined;
GlobalState.Instance.ChangeCursor(false);
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
case GameState.Menu:
GlobalState.Instance.ChangeCursor(true);
//Input.MouseMode = Input.MouseModeEnum.Visible;
DelayedUnpause();
//CallDeferred(MethodName.DelayedUnpause);
//GetTree().SetPause(false);
break;
}
}
private void DelayedUnpause()
{
GetTree().SetPause(false);
}
public override void _Process(double delta)
{
if (GameState is GameState.Paused && GlobalInputManager.IsPauseJustPressed())
{
Unpause();
return;
}
}
}

View file

@ -0,0 +1 @@
uid://dgt75vijkdgxy

View file

@ -0,0 +1,19 @@
using Godot;
namespace Cirno.Scripts.Utils;
public partial class GlobalInputManager : Node
{
public static GlobalInputManager Instance;
[Export] public StringName PauseActionName { get; private set; } = "pause";
public static bool IsPauseJustPressed()
{
return Input.IsActionJustPressed(Instance.PauseActionName);
}
public override void _Ready()
{
Instance = this;
}
}

View file

@ -0,0 +1 @@
uid://y776grpi3a30

View file

@ -51,6 +51,7 @@ GodotGTweensContextNode="*res://GTweensGodot/Godot/Source/Contexts/GodotGTweensC
CyclopsAutoload="*res://addons/cyclops_level_builder/cyclops_global_scene.tscn"
PoolingManager="*res://Scenes/Utils/pooling_manager.tscn"
TBGAME="*res://3D/TrenchBroom/EntityScripts/tb_manager.gd"
GlobalInputManager="*res://Scenes/Utils/GlobalInputManager.tscn"
[debug_draw_3d]