update forge
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 27s
Create tag and build when new code gets to main / Export (push) Successful in 7m25s

This commit is contained in:
2026-05-17 00:06:44 +02:00
parent 8b54f00814
commit e09714cf83
473 changed files with 13577 additions and 767 deletions

View File

@@ -0,0 +1,180 @@
// Copyright © Gamesmiths Guild.
#if TOOLS
using System;
using System.Collections.Generic;
using Gamesmiths.Forge.Godot.Editor.Statescript.Resolvers.Bases;
using Gamesmiths.Forge.Godot.Resources.Statescript;
using Gamesmiths.Forge.Godot.Resources.Statescript.Resolvers;
using Godot;
using ForgeEulerOrder = Gamesmiths.Forge.Statescript.Properties.EulerOrder;
using ForgeVariant128 = Gamesmiths.Forge.Statescript.Variant128;
using GodotVector2 = Godot.Vector2;
using SysQuaternion = System.Numerics.Quaternion;
using SysVector3 = System.Numerics.Vector3;
namespace Gamesmiths.Forge.Godot.Editor.Statescript.Resolvers;
[Tool]
internal sealed partial class EulerAnglesFromQuaternionResolverEditor : NodeEditorProperty
{
private StatescriptGraph? _graph;
private Action? _onChanged;
private VBoxContainer? _editorContainer;
private NodeEditorProperty? _quaternionEditor;
private List<Func<NodeEditorProperty>> _factories = [];
private ForgeEulerOrder _order = ForgeEulerOrder.XYZ;
public override string DisplayName => "Euler Angles From Quaternion";
public override string ResolverTypeId => "EulerAnglesFromQuaternion";
public override bool IsCompatibleWith(Type expectedType)
{
return expectedType == typeof(SysVector3) || expectedType == typeof(ForgeVariant128);
}
public override void Setup(
StatescriptGraph graph,
StatescriptNodeProperty? property,
Type expectedType,
Action onChanged,
bool isArray)
{
_graph = graph;
_onChanged = onChanged;
_factories = ResolverEditorFactoryCatalog.GetCompatibleFactories(typeof(SysQuaternion));
var existing = property?.Resolver as EulerAnglesFromQuaternionResolverResource;
_order = existing?.Order ?? ForgeEulerOrder.XYZ;
SizeFlagsHorizontal = SizeFlags.ExpandFill;
var root = new VBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill };
AddChild(root);
FoldableContainer foldable = CreateFoldable("Quaternion:");
root.AddChild(foldable);
var container = new VBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill };
foldable.AddChild(container);
OptionButton dropdown = CreateResolverDropdown(existing?.Operand);
_editorContainer = new VBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill };
container.AddChild(dropdown);
container.AddChild(_editorContainer);
ShowEditor(GetSelectedIndex(existing?.Operand), existing?.Operand);
dropdown.ItemSelected += OnResolverDropdownItemSelected;
var orderRow = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill };
root.AddChild(orderRow);
orderRow.AddChild(new Label
{
Text = "Order:",
CustomMinimumSize = new GodotVector2(55, 0),
HorizontalAlignment = HorizontalAlignment.Right,
});
var orderDropdown = new OptionButton { SizeFlagsHorizontal = SizeFlags.ExpandFill };
foreach (ForgeEulerOrder value in Enum.GetValues<ForgeEulerOrder>())
{
orderDropdown.AddItem(value.ToString());
}
orderDropdown.Selected = (int)_order;
orderDropdown.ItemSelected += OnOrderDropdownItemSelected;
orderRow.AddChild(orderDropdown);
}
public override void SaveTo(StatescriptNodeProperty property)
{
StatescriptResolverResource? operand = null;
if (_quaternionEditor is not null)
{
var operandProperty = new StatescriptNodeProperty();
_quaternionEditor.SaveTo(operandProperty);
operand = operandProperty.Resolver;
}
property.Resolver = new EulerAnglesFromQuaternionResolverResource
{
Operand = operand,
Order = _order,
};
}
public override void ClearCallbacks()
{
base.ClearCallbacks();
_onChanged = null;
_quaternionEditor?.ClearCallbacks();
}
private FoldableContainer CreateFoldable(string title)
{
var foldable = new FoldableContainer { Title = title };
foldable.FoldingChanged += _ => RaiseLayoutSizeChanged();
return foldable;
}
private void OnResolverDropdownItemSelected(long index)
{
if (_editorContainer is null)
{
return;
}
foreach (Node child in _editorContainer.GetChildren())
{
_editorContainer.RemoveChild(child);
child.Free();
}
_quaternionEditor = null;
ShowEditor((int)index, null);
_onChanged?.Invoke();
RaiseLayoutSizeChanged();
}
private void OnOrderDropdownItemSelected(long index)
{
_order = (ForgeEulerOrder)(int)index;
_onChanged?.Invoke();
}
private int GetSelectedIndex(StatescriptResolverResource? existingResolver)
{
return ResolverEditorFactoryCatalog.GetDefaultFactoryIndex(_factories, existingResolver, "Variant");
}
private OptionButton CreateResolverDropdown(StatescriptResolverResource? existingResolver)
{
var dropdown = new OptionButton { SizeFlagsHorizontal = SizeFlags.ExpandFill };
foreach (Func<NodeEditorProperty> factory in _factories)
{
dropdown.AddItem(StatescriptResolverRegistry.GetDisplayName(factory));
}
dropdown.Selected = GetSelectedIndex(existingResolver);
return dropdown;
}
private void ShowEditor(int factoryIndex, StatescriptResolverResource? existingResolver)
{
if (_graph is null || _editorContainer is null || factoryIndex < 0 || factoryIndex >= _factories.Count)
{
return;
}
NodeEditorProperty editor = _factories[factoryIndex]();
StatescriptNodeProperty? tempProperty =
existingResolver is null ? null : new StatescriptNodeProperty { Resolver = existingResolver };
editor.Setup(_graph, tempProperty, typeof(SysQuaternion), OnNestedEditorChanged, false);
editor.LayoutSizeChanged += RaiseLayoutSizeChanged;
_editorContainer.AddChild(editor);
_quaternionEditor = editor;
}
private void OnNestedEditorChanged()
{
_onChanged?.Invoke();
}
}
#endif