2025-02-24 13:47:38 +01:00
|
|
|
using System.Threading.Tasks;
|
2025-02-21 11:39:22 +01:00
|
|
|
using Cirno.Scripts.Resources;
|
2025-02-27 08:37:55 +01:00
|
|
|
using Cirno.Scripts.Utils;
|
2025-02-20 21:26:51 +01:00
|
|
|
using Godot;
|
2025-02-24 13:47:38 +01:00
|
|
|
using GTweens.Builders;
|
|
|
|
|
using GTweensGodot.Extensions;
|
2025-02-20 21:26:51 +01:00
|
|
|
|
|
|
|
|
public partial class GlobalState : Node
|
|
|
|
|
{
|
|
|
|
|
public static GlobalState Instance { get; private set; }
|
|
|
|
|
|
|
|
|
|
public Node CurrentScene { get; set; }
|
2025-02-24 13:47:38 +01:00
|
|
|
|
|
|
|
|
private ColorRect _fader { get; set; }
|
2025-02-20 21:26:51 +01:00
|
|
|
|
2025-02-27 08:37:55 +01:00
|
|
|
public SessionSettings SessionSettings { get; set; }
|
|
|
|
|
|
2025-02-20 21:26:51 +01:00
|
|
|
public override void _Ready()
|
|
|
|
|
{
|
|
|
|
|
Instance = this;
|
|
|
|
|
|
2025-02-24 10:37:27 +01:00
|
|
|
this.ProcessMode = ProcessModeEnum.Always;
|
|
|
|
|
|
2025-02-20 21:26:51 +01:00
|
|
|
Viewport root = GetTree().Root;
|
|
|
|
|
// Using a negative index counts from the end, so this gets the last child node of `root`.
|
|
|
|
|
CurrentScene = root.GetChild(-1);
|
2025-02-24 13:47:38 +01:00
|
|
|
|
|
|
|
|
_fader = CreateFader();
|
2025-02-20 21:26:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void GotoScene(string path)
|
|
|
|
|
{
|
|
|
|
|
// This function will usually be called from a signal callback,
|
|
|
|
|
// or some other function from the current scene.
|
|
|
|
|
// Deleting the current scene at this point is
|
|
|
|
|
// a bad idea, because it may still be executing code.
|
|
|
|
|
// This will result in a crash or unexpected behavior.
|
|
|
|
|
|
|
|
|
|
// The solution is to defer the load to a later time, when
|
|
|
|
|
// we can be sure that no code from the current scene is running:
|
2025-02-24 13:47:38 +01:00
|
|
|
|
|
|
|
|
//CallDeferred(MethodName.DeferredGotoScene, path, new MapStartDataResource());
|
|
|
|
|
|
|
|
|
|
GoToScene(path, new MapStartDataResource());
|
2025-02-20 21:26:51 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-21 11:39:22 +01:00
|
|
|
public void GoToScene(string path, MapStartDataResource startData)
|
|
|
|
|
{
|
2025-02-24 13:47:38 +01:00
|
|
|
GTweenSequenceBuilder.New()
|
|
|
|
|
//.Append(_fader.TweenModulateAlpha(0, 0f))
|
|
|
|
|
.Append(_fader.TweenModulateAlpha(1, 0.5f))
|
|
|
|
|
.AppendCallback(() =>
|
|
|
|
|
{
|
|
|
|
|
CallDeferred(MethodName.DeferredGotoScene, path, startData);
|
|
|
|
|
})
|
|
|
|
|
.Build()
|
|
|
|
|
.PlayUnpausable();
|
|
|
|
|
//CallDeferred(MethodName.DeferredGotoScene, path, startData);
|
2025-02-21 11:39:22 +01:00
|
|
|
}
|
2025-02-24 13:47:38 +01:00
|
|
|
|
2025-02-21 11:39:22 +01:00
|
|
|
private void DeferredGotoScene(string path, MapStartDataResource startData = null)
|
2025-02-20 21:26:51 +01:00
|
|
|
{
|
|
|
|
|
// It is now safe to remove the current scene.
|
|
|
|
|
CurrentScene.Free();
|
|
|
|
|
|
|
|
|
|
// Load a new scene.
|
|
|
|
|
var nextScene = GD.Load<PackedScene>(path);
|
|
|
|
|
|
|
|
|
|
// Instance the new scene.
|
|
|
|
|
CurrentScene = nextScene.Instantiate();
|
|
|
|
|
|
|
|
|
|
// Add it to the active scene, as child of root.
|
|
|
|
|
GetTree().Root.AddChild(CurrentScene);
|
|
|
|
|
|
|
|
|
|
// Optionally, to make it compatible with the SceneTree.change_scene_to_file() API.
|
|
|
|
|
GetTree().CurrentScene = CurrentScene;
|
2025-02-21 11:39:22 +01:00
|
|
|
|
2025-02-21 12:09:42 +01:00
|
|
|
// // Update current scene here too
|
|
|
|
|
// CurrentScene = GetTree().Root.GetChild(-1);
|
|
|
|
|
|
2025-02-24 21:54:20 +01:00
|
|
|
if (startData is not null && GameManager.Instance is not null)
|
2025-02-21 11:39:22 +01:00
|
|
|
{
|
|
|
|
|
// Call deferred if it gives issues
|
|
|
|
|
DeferredAddStartDataToGameManager(startData);
|
|
|
|
|
}
|
2025-02-27 08:37:55 +01:00
|
|
|
|
|
|
|
|
if (GameManager.Instance is not null) {
|
|
|
|
|
GameManager.Instance.ApplySessionState(SessionSettings);
|
|
|
|
|
}
|
2025-02-24 13:47:38 +01:00
|
|
|
|
|
|
|
|
FadeIn();
|
2025-02-20 21:26:51 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-21 11:39:22 +01:00
|
|
|
private void DeferredAddStartDataToGameManager(MapStartDataResource resource)
|
|
|
|
|
{
|
2025-02-24 21:54:20 +01:00
|
|
|
GameManager.Instance?.ApplyMapStartData(resource);
|
2025-02-21 11:39:22 +01:00
|
|
|
}
|
2025-02-24 13:47:38 +01:00
|
|
|
|
|
|
|
|
private ColorRect CreateFader()
|
|
|
|
|
{
|
|
|
|
|
var canvas = new CanvasLayer();
|
|
|
|
|
canvas.ProcessMode = ProcessModeEnum.Always;
|
|
|
|
|
|
|
|
|
|
var rect = new ColorRect();
|
|
|
|
|
rect.SetAnchorsPreset(Control.LayoutPreset.FullRect);
|
|
|
|
|
rect.Color = new Color(Colors.Black, 1f);
|
|
|
|
|
rect.ProcessMode = ProcessModeEnum.Always;
|
|
|
|
|
|
|
|
|
|
rect.Modulate = new Color(0,0,0,0);
|
|
|
|
|
|
|
|
|
|
rect.MouseFilter = Control.MouseFilterEnum.Ignore;
|
|
|
|
|
|
|
|
|
|
canvas.CallDeferred("add_child", rect);
|
|
|
|
|
|
|
|
|
|
this.CallDeferred("add_child", canvas);
|
|
|
|
|
|
|
|
|
|
return rect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FadeOut()
|
|
|
|
|
{
|
|
|
|
|
_fader.TweenModulateAlpha(1, 0.5f).PlayUnpausable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FadeIn()
|
|
|
|
|
{
|
|
|
|
|
_fader.TweenModulateAlpha(0, 1f).PlayUnpausable();
|
|
|
|
|
}
|
2025-02-20 21:26:51 +01:00
|
|
|
}
|