Files
OpenRA/OpenRA.Mods.Common/Traits/Render/WithVoxelBody.cs
Paul Chote 6f5d035e79 Introduce IMouseBounds and split/rework mouse rectangles.
The render bounds for an actor now include the area covered
by bibs, shadows, and any other widgets. In many cases this
area is much larger than we really want to consider for
tooltips and mouse selection.

An optional Margin is added to Selectable to support cases
like infantry, where we want the mouse area of the actor
to be larger than the drawn selection box.
2017-12-11 19:45:07 +01:00

76 lines
2.7 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Also returns a default selection size that is calculated automatically from the voxel dimensions.")]
public class WithVoxelBodyInfo : ConditionalTraitInfo, IRenderActorPreviewVoxelsInfo, Requires<RenderVoxelsInfo>, IAutoSelectionSizeInfo, IAutoRenderSizeInfo
{
public readonly string Sequence = "idle";
[Desc("Defines if the Voxel should have a shadow.")]
public readonly bool ShowShadow = true;
public override object Create(ActorInitializer init) { return new WithVoxelBody(init.Self, this); }
public IEnumerable<ModelAnimation> RenderPreviewVoxels(
ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, Func<WRot> orientation, int facings, PaletteReference p)
{
var body = init.Actor.TraitInfo<BodyOrientationInfo>();
var model = init.World.ModelCache.GetModelSequence(image, Sequence);
yield return new ModelAnimation(model, () => WVec.Zero,
() => new[] { body.QuantizeOrientation(orientation(), facings) },
() => false, () => 0, ShowShadow);
}
}
public class WithVoxelBody : ConditionalTrait<WithVoxelBodyInfo>, IAutoSelectionSize, IAutoRenderSize, IAutoMouseBounds
{
readonly int2 size;
readonly ModelAnimation modelAnimation;
readonly RenderVoxels rv;
public WithVoxelBody(Actor self, WithVoxelBodyInfo info)
: base(info)
{
var body = self.Trait<BodyOrientation>();
rv = self.Trait<RenderVoxels>();
var model = self.World.ModelCache.GetModelSequence(rv.Image, info.Sequence);
modelAnimation = new ModelAnimation(model, () => WVec.Zero,
() => new[] { body.QuantizeOrientation(self, self.Orientation) },
() => IsTraitDisabled, () => 0, info.ShowShadow);
rv.Add(modelAnimation);
// Selection size
var rvi = self.Info.TraitInfo<RenderVoxelsInfo>();
var s = (int)(rvi.Scale * model.Size.Aggregate(Math.Max));
size = new int2(s, s);
}
public int2 SelectionSize(Actor self) { return size; }
public int2 RenderSize(Actor self) { return size; }
Rectangle IAutoMouseBounds.AutoMouseoverBounds(Actor self, WorldRenderer wr)
{
return modelAnimation.ScreenBounds(self.CenterPosition, wr, rv.Info.Scale);
}
}
}