Introduced VisualBounds on SelectionDecorations

To allow visual selection boxes to be independent from Selectable.Bounds.
This commit is contained in:
reaperrr
2015-04-07 22:32:38 +02:00
parent f72a14faea
commit d6fb05ce68
6 changed files with 51 additions and 10 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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). "

View File

@@ -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)
{

View File

@@ -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);
}
}