Introduced VisualBounds on SelectionDecorations
To allow visual selection boxes to be independent from Selectable.Bounds.
This commit is contained in:
@@ -41,12 +41,14 @@ namespace OpenRA
|
||||
public int Generation;
|
||||
|
||||
Lazy<Rectangle> bounds;
|
||||
Lazy<Rectangle> visualBounds;
|
||||
Lazy<IFacing> facing;
|
||||
Lazy<Health> health;
|
||||
Lazy<IOccupySpace> occupySpace;
|
||||
Lazy<IEffectiveOwner> effectiveOwner;
|
||||
|
||||
public Rectangle Bounds { get { return bounds.Value; } }
|
||||
public Rectangle VisualBounds { get { return visualBounds.Value; } }
|
||||
public IOccupySpace OccupiesSpace { get { return occupySpace.Value; } }
|
||||
public IEffectiveOwner EffectiveOwner { get { return effectiveOwner.Value; } }
|
||||
|
||||
@@ -110,6 +112,19 @@ namespace OpenRA
|
||||
return new Rectangle(offset.X, offset.Y, size.X, size.Y);
|
||||
});
|
||||
|
||||
visualBounds = Exts.Lazy(() =>
|
||||
{
|
||||
var sd = Info.Traits.GetOrDefault<SelectionDecorationsInfo>();
|
||||
var size = (sd != null && sd.VisualBounds != null) ? new int2(sd.VisualBounds[0], sd.VisualBounds[1]) :
|
||||
TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
|
||||
|
||||
var offset = -size / 2;
|
||||
if (sd != null && sd.VisualBounds != null && sd.VisualBounds.Length > 2)
|
||||
offset += new int2(sd.VisualBounds[2], sd.VisualBounds[3]);
|
||||
|
||||
return new Rectangle(offset.X, offset.Y, size.X, size.Y);
|
||||
});
|
||||
|
||||
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
|
||||
renders = TraitsImplementing<IRender>().ToArray();
|
||||
disables = TraitsImplementing<IDisable>().ToArray();
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace OpenRA.Graphics
|
||||
var health = actor.TraitOrDefault<Health>();
|
||||
|
||||
var screenPos = wr.ScreenPxPosition(pos);
|
||||
var bounds = actor.Bounds;
|
||||
var bounds = actor.VisualBounds;
|
||||
bounds.Offset(screenPos.X, screenPos.Y);
|
||||
|
||||
var start = new float2(bounds.Left + 1, bounds.Top);
|
||||
|
||||
@@ -18,16 +18,16 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
readonly WPos pos;
|
||||
readonly float scale;
|
||||
readonly Rectangle bounds;
|
||||
readonly Rectangle visualBounds;
|
||||
readonly Color color;
|
||||
|
||||
public SelectionBoxRenderable(Actor actor, Color color)
|
||||
: this(actor.CenterPosition, actor.Bounds, 1f, color) { }
|
||||
: this(actor.CenterPosition, actor.VisualBounds, 1f, color) { }
|
||||
|
||||
public SelectionBoxRenderable(WPos pos, Rectangle bounds, float scale, Color color)
|
||||
public SelectionBoxRenderable(WPos pos, Rectangle visualBounds, float scale, Color color)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.bounds = bounds;
|
||||
this.visualBounds = visualBounds;
|
||||
this.scale = scale;
|
||||
this.color = color;
|
||||
}
|
||||
@@ -40,15 +40,15 @@ namespace OpenRA.Graphics
|
||||
|
||||
public IRenderable WithPalette(PaletteReference newPalette) { return this; }
|
||||
public IRenderable WithZOffset(int newOffset) { return this; }
|
||||
public IRenderable OffsetBy(WVec vec) { return new SelectionBoxRenderable(pos + vec, bounds, scale, color); }
|
||||
public IRenderable OffsetBy(WVec vec) { return new SelectionBoxRenderable(pos + vec, visualBounds, scale, color); }
|
||||
public IRenderable AsDecoration() { return this; }
|
||||
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
var screenPos = wr.ScreenPxPosition(pos);
|
||||
var tl = screenPos + scale * new float2(bounds.Left, bounds.Top);
|
||||
var br = screenPos + scale * new float2(bounds.Right, bounds.Bottom);
|
||||
var tl = screenPos + scale * new float2(visualBounds.Left, visualBounds.Top);
|
||||
var br = screenPos + scale * new float2(visualBounds.Right, visualBounds.Bottom);
|
||||
var tr = new float2(br.X, tl.Y);
|
||||
var bl = new float2(tl.X, br.Y);
|
||||
var u = new float2(4f / wr.Viewport.Zoom, 0);
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
public readonly bool Selectable = true;
|
||||
public readonly int Priority = 10;
|
||||
[Desc("Bounds for the selectable area.")]
|
||||
public readonly int[] Bounds = null;
|
||||
|
||||
[Desc("All units having the same selection class specified will be selected with select-by-type commands (e.g. double-click). "
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace OpenRA.Traits
|
||||
public class SelectionDecorationsInfo : ITraitInfo
|
||||
{
|
||||
public readonly string Palette = "chrome";
|
||||
[Desc("Visual bounds for the selection box. If null, it matches Bounds.")]
|
||||
public readonly int[] VisualBounds = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new SelectionDecorations(init.Self, this); }
|
||||
}
|
||||
@@ -41,7 +43,7 @@ namespace OpenRA.Traits
|
||||
if (!self.Owner.IsAlliedWith(self.World.RenderPlayer) || self.World.FogObscures(self))
|
||||
yield break;
|
||||
|
||||
var b = self.Bounds;
|
||||
var b = self.VisualBounds;
|
||||
var pos = wr.ScreenPxPosition(self.CenterPosition);
|
||||
var tl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Top));
|
||||
var bl = wr.Viewport.WorldToViewPx(pos + new int2(b.Left, b.Bottom));
|
||||
@@ -85,7 +87,7 @@ namespace OpenRA.Traits
|
||||
var pipxyBase = basePosition + new int2(1 - pipSize.X / 2, -(3 + pipSize.Y / 2));
|
||||
var pipxyOffset = new int2(0, 0);
|
||||
var pal = wr.Palette(Info.Palette);
|
||||
var width = self.Bounds.Width;
|
||||
var width = self.VisualBounds.Width;
|
||||
|
||||
foreach (var pips in pipSources)
|
||||
{
|
||||
|
||||
@@ -1152,6 +1152,29 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
}
|
||||
|
||||
if (engineVersion < 20150603)
|
||||
{
|
||||
if (depth == 0 && node.Value.Nodes.Exists(n => n.Key == "Selectable"))
|
||||
{
|
||||
var selectable = node.Value.Nodes.FirstOrDefault(n => n.Key == "Selectable");
|
||||
var selDecor = node.Value.Nodes.FirstOrDefault(n => n.Key == "SelectionDecorations");
|
||||
var selectableNodes = selectable.Value.Nodes;
|
||||
var bounds = selectableNodes.FirstOrDefault(n => n.Key == "Bounds");
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
var visualBounds = FieldLoader.GetValue<string>("Bounds", bounds.Value.Value);
|
||||
if (selDecor != null)
|
||||
selDecor.Value.Nodes.Add(new MiniYamlNode("VisualBounds", visualBounds.ToString()));
|
||||
else
|
||||
node.Value.Nodes.Add(new MiniYamlNode("SelectionDecorations", "", new List<MiniYamlNode>
|
||||
{
|
||||
new MiniYamlNode("VisualBounds", visualBounds),
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user