Files
MovementTests/addons/forge/ForgePluginLoader.cs
Minimata 1d856fd937
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 5m42s
Replicated the weapon flying tick setup using resources
2026-04-07 16:32:26 +02:00

275 lines
7.5 KiB
C#

// Copyright © Gamesmiths Guild.
#if TOOLS
using System;
using System.Diagnostics;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Editor;
using Gamesmiths.Forge.Godot.Editor.Attributes;
using Gamesmiths.Forge.Godot.Editor.Cues;
using Gamesmiths.Forge.Godot.Editor.Statescript;
using Gamesmiths.Forge.Godot.Editor.Tags;
using Gamesmiths.Forge.Godot.Resources.Statescript;
using Godot;
namespace Gamesmiths.Forge.Godot;
[Tool]
public partial class ForgePluginLoader : EditorPlugin
{
private const string AutoloadPath = "uid://ba8fquhtwu5mu";
private TagsEditorDock? _tagsEditorDock;
private TagContainerInspectorPlugin? _tagContainerInspectorPlugin;
private TagInspectorPlugin? _tagInspectorPlugin;
private AttributeSetInspectorPlugin? _attributeSetInspectorPlugin;
private CueHandlerInspectorPlugin? _cueHandlerInspectorPlugin;
private AttributeEditorPlugin? _attributeEditorPlugin;
private SharedVariableSetInspectorPlugin? _sharedVariableSetInspectorPlugin;
private StatescriptGraphEditorDock? _statescriptGraphEditorDock;
private EditorFileSystem? _fileSystem;
private Callable _resourcesReimportedCallable;
public override void _EnterTree()
{
EnsureForgeDataExists();
_tagsEditorDock = new TagsEditorDock();
AddDock(_tagsEditorDock);
_tagContainerInspectorPlugin = new TagContainerInspectorPlugin();
AddInspectorPlugin(_tagContainerInspectorPlugin);
_tagInspectorPlugin = new TagInspectorPlugin();
AddInspectorPlugin(_tagInspectorPlugin);
_attributeSetInspectorPlugin = new AttributeSetInspectorPlugin();
AddInspectorPlugin(_attributeSetInspectorPlugin);
_cueHandlerInspectorPlugin = new CueHandlerInspectorPlugin();
AddInspectorPlugin(_cueHandlerInspectorPlugin);
_attributeEditorPlugin = new AttributeEditorPlugin();
AddInspectorPlugin(_attributeEditorPlugin);
_sharedVariableSetInspectorPlugin = new SharedVariableSetInspectorPlugin();
_sharedVariableSetInspectorPlugin.SetUndoRedo(GetUndoRedo());
AddInspectorPlugin(_sharedVariableSetInspectorPlugin);
_statescriptGraphEditorDock = new StatescriptGraphEditorDock();
_statescriptGraphEditorDock.SetUndoRedo(GetUndoRedo());
AddDock(_statescriptGraphEditorDock);
AddToolMenuItem("Repair assets tags", new Callable(this, MethodName.CallAssetRepairTool));
_fileSystem = EditorInterface.Singleton.GetResourceFilesystem();
_resourcesReimportedCallable = new Callable(this, nameof(OnResourcesReimported));
_fileSystem.Connect(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable);
Validation.Enabled = true;
}
public override void _ExitTree()
{
Debug.Assert(
_tagsEditorDock is not null,
$"{nameof(_tagsEditorDock)} should have been initialized on _Ready().");
Debug.Assert(
_statescriptGraphEditorDock is not null,
$"{nameof(_statescriptGraphEditorDock)} should have been initialized on _Ready().");
if (_fileSystem?.IsConnected(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable)
== true)
{
_fileSystem.Disconnect(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable);
}
RemoveDock(_tagsEditorDock);
_tagsEditorDock.Free();
RemoveInspectorPlugin(_tagContainerInspectorPlugin);
RemoveInspectorPlugin(_tagInspectorPlugin);
RemoveInspectorPlugin(_attributeSetInspectorPlugin);
RemoveInspectorPlugin(_cueHandlerInspectorPlugin);
RemoveInspectorPlugin(_attributeEditorPlugin);
RemoveInspectorPlugin(_sharedVariableSetInspectorPlugin);
RemoveDock(_statescriptGraphEditorDock);
_statescriptGraphEditorDock.Free();
RemoveToolMenuItem("Repair assets tags");
}
public override bool _Handles(GodotObject @object)
{
return @object is StatescriptGraph;
}
public override void _Edit(GodotObject? @object)
{
if (@object is StatescriptGraph graph && _statescriptGraphEditorDock is not null)
{
_statescriptGraphEditorDock.OpenGraph(graph);
}
}
public override void _MakeVisible(bool visible)
{
if (_statescriptGraphEditorDock is null)
{
return;
}
if (visible)
{
_statescriptGraphEditorDock.Open();
}
_statescriptGraphEditorDock.Visible = visible;
}
public override void _EnablePlugin()
{
base._EnablePlugin();
EnsureForgeDataExists();
var config = ProjectSettings.LoadResourcePack(AutoloadPath);
if (config)
{
GD.PrintErr("Failed to load script at res://addons/forge/core/ForgeBootstrap.cs");
return;
}
if (!ProjectSettings.HasSetting("autoload/Forge Bootstrap"))
{
ProjectSettings.SetSetting("autoload/Forge Bootstrap", AutoloadPath);
ProjectSettings.Save();
}
}
public override void _DisablePlugin()
{
if (ProjectSettings.HasSetting("autoload/Forge Bootstrap"))
{
ProjectSettings.Clear("autoload/Forge Bootstrap");
ProjectSettings.Save();
}
}
public override void _SaveExternalData()
{
_statescriptGraphEditorDock?.SaveAllOpenGraphs();
}
public override string _GetPluginName()
{
return "Forge";
}
public override void _GetWindowLayout(ConfigFile configuration)
{
if (_statescriptGraphEditorDock is null)
{
return;
}
var paths = _statescriptGraphEditorDock.GetOpenResourcePaths();
if (paths.Length == 0)
{
return;
}
configuration.SetValue("Forge", "open_tabs", string.Join(";", paths));
configuration.SetValue("Forge", "active_tab", _statescriptGraphEditorDock.GetActiveTabIndex());
var varStates = _statescriptGraphEditorDock.GetVariablesPanelStates();
configuration.SetValue("Forge", "variables_states", string.Join(";", varStates));
}
public override void _SetWindowLayout(ConfigFile configuration)
{
if (_statescriptGraphEditorDock is null)
{
return;
}
Variant tabsValue = configuration.GetValue("Forge", "open_tabs", string.Empty);
Variant active = configuration.GetValue("Forge", "active_tab", -1);
var tabsString = tabsValue.AsString();
if (string.IsNullOrEmpty(tabsString))
{
return;
}
var paths = tabsString.Split(';', StringSplitOptions.RemoveEmptyEntries);
var activeIndex = active.AsInt32();
bool[]? variablesStates = null;
Variant varStatesValue = configuration.GetValue("Forge", "variables_states", string.Empty);
var varString = varStatesValue.AsString();
if (!string.IsNullOrEmpty(varString))
{
var parts = varString.Split(';');
variablesStates = new bool[parts.Length];
for (var i = 0; i < parts.Length; i++)
{
variablesStates[i] = bool.TryParse(parts[i], out var v) && v;
}
}
_statescriptGraphEditorDock.RestoreFromPaths(paths, activeIndex, variablesStates);
}
private static void EnsureForgeDataExists()
{
if (ResourceLoader.Exists(ForgeData.ForgeDataResourcePath))
{
return;
}
var forgeData = new ForgeData();
Error error = ResourceSaver.Save(forgeData, ForgeData.ForgeDataResourcePath);
if (error != Error.Ok)
{
GD.PrintErr($"Failed to create ForgeData resource: {error}");
return;
}
EditorInterface.Singleton.GetResourceFilesystem().Scan();
GD.Print("Created default ForgeData resource at ", ForgeData.ForgeDataResourcePath);
}
private static void CallAssetRepairTool()
{
AssetRepairTool.RepairAllAssetsTags();
}
private void OnResourcesReimported(string[] resources)
{
foreach (var path in resources)
{
if (!ResourceLoader.Exists(path))
{
continue;
}
var fileType = EditorInterface.Singleton.GetResourceFilesystem().GetFileType(path);
if (fileType != "StatescriptGraph" && fileType != "Resource")
{
continue;
}
Resource resource = ResourceLoader.Load(path);
if (resource is StatescriptGraph graph)
{
_statescriptGraphEditorDock?.OpenGraph(graph);
}
}
}
}
#endif