Skip to content

Commit

Permalink
Add WIP asset editor
Browse files Browse the repository at this point in the history
  • Loading branch information
PunkPun committed Apr 10, 2024
1 parent 6050179 commit 2edb58a
Show file tree
Hide file tree
Showing 21 changed files with 1,172 additions and 15 deletions.
5 changes: 5 additions & 0 deletions OpenRA.Game/FieldSaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ public static MiniYamlNode SaveField(object o, string field)
return new MiniYamlNode(field, FormatValue(o, o.GetType().GetField(field)));
}

public static MiniYamlNode SaveField(object o, FieldInfo field)
{
return new MiniYamlNode(field.Name, FormatValue(o, field));
}

public static string FormatValue(object v)
{
if (v == null)
Expand Down
3 changes: 3 additions & 0 deletions OpenRA.Game/Graphics/Sprite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

using System;
using OpenRA.Primitives;
using OpenRA.Traits;

namespace OpenRA.Graphics
{
Expand All @@ -22,6 +23,8 @@ public class Sprite
public readonly TextureChannel Channel;
public readonly float ZRamp;
public readonly float3 Size;

[AssetEditor]
public readonly float3 Offset;
public readonly float Top, Left, Bottom, Right;

Expand Down
7 changes: 7 additions & 0 deletions OpenRA.Game/Traits/TraitsInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ namespace OpenRA.Traits
[AttributeUsage(AttributeTargets.Interface)]
public sealed class RequireExplicitImplementationAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Field)]
public sealed class AssetEditorAttribute : Attribute
{
public readonly bool EditAllMembers;
public AssetEditorAttribute(bool editAllMembers = false) { EditAllMembers = editAllMembers; }
}

[Flags]
public enum DamageState
{
Expand Down
23 changes: 15 additions & 8 deletions OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Graphics
{
Expand Down Expand Up @@ -206,9 +207,13 @@ public ReservationInfo(string filename, List<int> loadFrames, int[] frames, Mini

protected readonly ISpriteSequenceLoader Loader;

protected string image;
public readonly string Image;
protected List<SpriteReservation> spritesToLoad = new();

[AssetEditor(true)]
protected Sprite[] sprites;

[AssetEditor(true)]
protected Sprite[] shadowSprites;
protected bool reverseFacings;
protected bool reverses;
Expand All @@ -222,6 +227,8 @@ public ReservationInfo(string filename, List<int> loadFrames, int[] frames, Mini
protected int facings;
protected int? interpolatedFacings;
protected int tick;

[AssetEditor]
protected int zOffset;
protected int shadowZOffset;
protected bool ignoreWorldTint;
Expand All @@ -236,7 +243,7 @@ public ReservationInfo(string filename, List<int> loadFrames, int[] frames, Mini
protected void ThrowIfUnresolved()
{
if (bounds == null)
throw new InvalidOperationException($"Unable to query unresolved sequence {image}.{Name}.");
throw new InvalidOperationException($"Unable to query unresolved sequence {Image}.{Name}.");
}

int ISpriteSequence.Length
Expand Down Expand Up @@ -367,7 +374,7 @@ protected virtual IEnumerable<ReservationInfo> ParseCombineFilenames(ModData mod

public DefaultSpriteSequence(SpriteCache cache, ISpriteSequenceLoader loader, string image, string sequence, MiniYaml data, MiniYaml defaults)
{
this.image = image;
Image = image;
Name = sequence;
Loader = loader;

Expand Down Expand Up @@ -522,7 +529,7 @@ public virtual void ResolveSprites(SpriteCache cache)
if (alpha.Length == 1)
alpha = Exts.MakeArray(length.Value, _ => alpha[0]);
else if (alpha.Length != length.Value)
throw new YamlException($"Sequence {image}.{Name} must define either 1 or {length.Value} Alpha values.");
throw new YamlException($"Sequence {Image}.{Name} must define either 1 or {length.Value} Alpha values.");
}
else if (alphaFade)
alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f)));
Expand All @@ -536,12 +543,12 @@ public virtual void ResolveSprites(SpriteCache cache)
}

if (index.Count == 0)
throw new YamlException($"Sequence {image}.{Name} does not define any frames.");
throw new YamlException($"Sequence {Image}.{Name} does not define any frames.");

var minIndex = index.Min();
var maxIndex = index.Max();
if (minIndex < 0 || maxIndex >= allSprites.Length)
throw new YamlException($"Sequence {image}.{Name} uses frames between {minIndex}..{maxIndex}, but only 0..{allSprites.Length - 1} exist.");
throw new YamlException($"Sequence {Image}.{Name} uses frames between {minIndex}..{maxIndex}, but only 0..{allSprites.Length - 1} exist.");

sprites = index.Select(f => allSprites[f]).ToArray();
if (shadowStart >= 0)
Expand Down Expand Up @@ -583,7 +590,7 @@ public Sprite GetShadow(int frame, WAngle facing)
var index = GetFacingFrameOffset(facing) * length.Value + frame % length.Value;
var sprite = shadowSprites[index];
if (sprite == null)
throw new InvalidOperationException($"Attempted to query unloaded shadow sprite from {image}.{Name} frame={frame} facing={facing}.");
throw new InvalidOperationException($"Attempted to query unloaded shadow sprite from {Image}.{Name} frame={frame} facing={facing}.");

return sprite;
}
Expand All @@ -594,7 +601,7 @@ public virtual Sprite GetSprite(int frame, WAngle facing)
var index = GetFacingFrameOffset(facing) * length.Value + frame % length.Value;
var sprite = sprites[index];
if (sprite == null)
throw new InvalidOperationException($"Attempted to query unloaded sprite from {image}.{Name} frame={frame} facing={facing}.");
throw new InvalidOperationException($"Attempted to query unloaded sprite from {Image}.{Name} frame={frame} facing={facing}.");

return sprite;
}
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/Traits/Armament.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class ArmamentInfo : PausableConditionalTraitInfo, Requires<AttackBaseInf
[Desc("Time (in frames) until the weapon can fire again.")]
public readonly int FireDelay = 0;

[AssetEditor]
[Desc("Muzzle position relative to turret or body, (forward, right, up) triples.",
"If weapon Burst = 1, it cycles through all listed offsets, otherwise the offset corresponding to current burst is used.")]
public readonly WVec[] LocalOffset = Array.Empty<WVec>();
Expand Down
2 changes: 2 additions & 0 deletions OpenRA.Mods.Common/Traits/Buildings/Exit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Where the unit should leave the building. Multiples are allowed if IDs are added: Exit@2, ...")]
public class ExitInfo : ConditionalTraitInfo, Requires<IOccupySpaceInfo>
{
[AssetEditor]
[Desc("Offset at which that the exiting actor is spawned relative to the center of the producing actor.")]
public readonly WVec SpawnOffset = WVec.Zero;

[AssetEditor]
[Desc("Cell offset where the exiting actor enters the ActorMap relative to the topleft cell of the producing actor.")]
public readonly CVec ExitCell = CVec.Zero;
public readonly WAngle? Facing = null;
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/Traits/HitShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class HitShapeInfo : ConditionalTraitInfo, Requires<BodyOrientationInfo>
[Desc("Name of turret this shape is linked to. Leave empty to link shape to body.")]
public readonly string Turret = null;

[AssetEditor]
[Desc("Create a targetable position for each offset listed here (relative to CenterPosition).")]
public readonly WVec[] TargetableOffsets = { WVec.Zero };

Expand Down
2 changes: 2 additions & 0 deletions OpenRA.Mods.Common/Traits/Interactable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Used to enable mouse interaction on actors that are not Selectable.")]
public class InteractableInfo : TraitInfo, IMouseBoundsInfo
{
[AssetEditor]
[Desc("Defines a custom rectangle for mouse interaction with the actor.",
"If null, the engine will guess an appropriate size based on the With*Body trait.",
"The first two numbers define the width and height of the rectangle as a world distance.",
"The (optional) second two numbers define an x and y offset from the actor center.")]
public readonly WDist[] Bounds = null;

[AssetEditor]
[Desc("Defines a custom rectangle for Decorations (e.g. the selection box).",
"If null, Bounds will be used instead")]
public readonly WDist[] DecorationBounds = null;
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class WithIdleOverlayInfo : PausableConditionalTraitInfo, IRenderActorPre
[Desc("Sequence name to use")]
public readonly string Sequence = "idle-overlay";

[AssetEditor]
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;

Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/Traits/Turreted.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class TurretedInfo : PausableConditionalTraitInfo, Requires<BodyOrientati
[Desc("Number of ticks before turret is realigned. (-1 turns off realignment)")]
public readonly int RealignDelay = 40;

[AssetEditor]
[Desc("Muzzle position relative to turret or body. (forward, right, up) triples")]
public readonly WVec Offset = WVec.Zero;

Expand Down

0 comments on commit 2edb58a

Please sign in to comment.