Add script tags to map editor actor properties.

This commit is contained in:
darkademic
2025-07-20 14:13:45 +01:00
committed by Gustas Kažukauskas
parent 53f959e4bf
commit 0fac8d0d31
5 changed files with 98 additions and 1 deletions

View File

@@ -10,14 +10,41 @@
#endregion #endregion
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("Allows this actor to be 'tagged' with arbitrary strings. Tags must be unique or they will be rejected.")] [Desc("Allows this actor to be 'tagged' with arbitrary strings. Tags must be unique or they will be rejected.")]
public class ScriptTagsInfo : TraitInfo public class ScriptTagsInfo : TraitInfo, IEditorActorOptions
{ {
[Desc("Display order for the script tags text field in the map editor")]
public readonly int EditorScriptTagsDisplayOrder = 5;
public override object Create(ActorInitializer init) { return new ScriptTags(init, this); } public override object Create(ActorInitializer init) { return new ScriptTags(init, this); }
IEnumerable<EditorActorOption> IEditorActorOptions.ActorOptions(ActorInfo ai, World world)
{
yield return new EditorActorTextField("Tags", EditorScriptTagsDisplayOrder,
actor =>
{
var init = actor.GetInitOrDefault<ScriptTagsInit>(this);
if (init != null)
return string.Join(", ", init.Value);
return "";
},
(actor, value) =>
{
var tags = string.IsNullOrWhiteSpace(value)
? [] :
value.Split(',').Select(t => t.Trim()).Where(t => !string.IsNullOrWhiteSpace(t)).ToArray();
if (tags.Length == 0)
actor.RemoveInit<ScriptTagsInit>(this);
else
actor.ReplaceInit(new ScriptTagsInit(tags), this);
});
}
} }
public class ScriptTags public class ScriptTags

View File

@@ -710,6 +710,21 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public class EditorActorTextField : EditorActorOption
{
public readonly Func<EditorActorPreview, string> GetValue;
public readonly Action<EditorActorPreview, string> OnChange;
public EditorActorTextField(string name, int displayOrder,
Func<EditorActorPreview, string> getValue,
Action<EditorActorPreview, string> onChange)
: base(name, displayOrder)
{
GetValue = getValue;
OnChange = onChange;
}
}
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface INotifyEditorPlacementInfo : ITraitInfoInterface public interface INotifyEditorPlacementInfo : ITraitInfoInterface
{ {

View File

@@ -51,6 +51,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly Widget checkboxOptionTemplate; readonly Widget checkboxOptionTemplate;
readonly Widget sliderOptionTemplate; readonly Widget sliderOptionTemplate;
readonly Widget dropdownOptionTemplate; readonly Widget dropdownOptionTemplate;
readonly Widget textFieldOptionTemplate;
ActorIDStatus actorIDStatus = ActorIDStatus.Normal; ActorIDStatus actorIDStatus = ActorIDStatus.Normal;
ActorIDStatus nextActorIDStatus = ActorIDStatus.Normal; ActorIDStatus nextActorIDStatus = ActorIDStatus.Normal;
@@ -85,6 +86,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
checkboxOptionTemplate = initContainer.Get("CHECKBOX_OPTION_TEMPLATE"); checkboxOptionTemplate = initContainer.Get("CHECKBOX_OPTION_TEMPLATE");
sliderOptionTemplate = initContainer.Get("SLIDER_OPTION_TEMPLATE"); sliderOptionTemplate = initContainer.Get("SLIDER_OPTION_TEMPLATE");
dropdownOptionTemplate = initContainer.Get("DROPDOWN_OPTION_TEMPLATE"); dropdownOptionTemplate = initContainer.Get("DROPDOWN_OPTION_TEMPLATE");
textFieldOptionTemplate = initContainer.Get("TEXTFIELD_OPTION_TEMPLATE");
initContainer.RemoveChildren(); initContainer.RemoveChildren();
var deleteButton = actorEditPanel.Get<ButtonWidget>("DELETE_BUTTON"); var deleteButton = actorEditPanel.Get<ButtonWidget>("DELETE_BUTTON");
@@ -320,6 +322,31 @@ namespace OpenRA.Mods.Common.Widgets.Logic
initContainer.AddChild(dropdownContainer); initContainer.AddChild(dropdownContainer);
} }
else if (o is EditorActorTextField tfo)
{
var textFieldContainer = textFieldOptionTemplate.Clone();
textFieldContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += textFieldContainer.Bounds.Height;
textFieldContainer.Get<LabelWidget>("LABEL").GetText = () => tfo.Name;
var editorActionHandle = new EditorActorOptionActionHandle<string>(tfo.OnChange, tfo.GetValue(SelectedActor));
editActorPreview.Add(editorActionHandle);
var textField = textFieldContainer.Get<TextFieldWidget>("OPTION");
textField.Text = tfo.GetValue(SelectedActor);
textField.OnTextEdited = () =>
{
tfo.OnChange(SelectedActor, textField.Text);
editorActionHandle.OnChange(textField.Text);
};
textField.OnEscKey = _ => { textField.YieldKeyboardFocus(); return true; };
textField.OnEnterKey = _ => { textField.YieldKeyboardFocus(); return true; };
typableFields.Add(textField);
initContainer.AddChild(textFieldContainer);
}
} }
buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight; buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight;

View File

@@ -651,6 +651,20 @@ Container@EDITOR_WORLD_ROOT:
Width: 213 Width: 213
Height: 25 Height: 25
Font: Bold Font: Bold
Container@TEXTFIELD_OPTION_TEMPLATE:
Width: PARENT_WIDTH
Height: 27
Children:
Label@LABEL:
Y: 1
Width: 55
Height: 25
Align: Right
TextField@OPTION:
X: 69
Y: 1
Width: 213
Height: 25
Container@BUTTON_CONTAINER: Container@BUTTON_CONTAINER:
Y: 70 Y: 70
Children: Children:

View File

@@ -618,6 +618,20 @@ Container@EDITOR_WORLD_ROOT:
Width: 213 Width: 213
Height: 25 Height: 25
Font: Bold Font: Bold
Container@TEXTFIELD_OPTION_TEMPLATE:
Width: PARENT_WIDTH
Height: 27
Children:
Label@LABEL:
Y: 1
Width: 55
Height: 25
Align: Right
TextField@OPTION:
X: 69
Y: 1
Width: 213
Height: 25
Container@BUTTON_CONTAINER: Container@BUTTON_CONTAINER:
Y: 75 Y: 75
Children: Children: