Merge pull request #8028 from RoosterDragon/cache-traits

Cache traits
This commit is contained in:
Paul Chote
2015-04-26 18:23:15 +12:00
30 changed files with 86 additions and 89 deletions

View File

@@ -83,8 +83,9 @@ namespace OpenRA
}
}
readonly IRenderModifier[] traitsImplementingRenderModifier;
readonly IRender[] traitsImplementingRender;
readonly IRenderModifier[] renderModifiers;
readonly IRender[] renders;
readonly IDisable[] disables;
internal Actor(World world, string name, TypeDictionary initDict)
{
@@ -126,8 +127,9 @@ namespace OpenRA
return new Rectangle(offset.X, offset.Y, size.X, size.Y);
});
traitsImplementingRenderModifier = TraitsImplementing<IRenderModifier>().ToArray();
traitsImplementingRender = TraitsImplementing<IRender>().ToArray();
renderModifiers = TraitsImplementing<IRenderModifier>().ToArray();
renders = TraitsImplementing<IRender>().ToArray();
disables = TraitsImplementing<IDisable>().ToArray();
}
public void Tick()
@@ -143,14 +145,14 @@ namespace OpenRA
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
var renderables = Renderables(wr);
foreach (var modifier in traitsImplementingRenderModifier)
foreach (var modifier in renderModifiers)
renderables = modifier.ModifyRender(this, wr, renderables);
return renderables;
}
IEnumerable<IRenderable> Renderables(WorldRenderer wr)
{
foreach (var render in traitsImplementingRender)
foreach (var render in renders)
foreach (var renderable in render.Render(this, wr))
yield return renderable;
}
@@ -277,6 +279,14 @@ namespace OpenRA
health.Value.InflictDamage(this, attacker, health.Value.MaxHP, null, true);
}
public bool IsDisabled()
{
foreach (var disable in disables)
if (disable.Disabled)
return true;
return false;
}
#region Scripting interface
Lazy<ScriptActorInterface> luaInterface;

View File

@@ -19,8 +19,8 @@ namespace OpenRA.GameRules
public class ProjectileArgs
{
public WeaponInfo Weapon;
public IEnumerable<int> DamageModifiers;
public IEnumerable<int> InaccuracyModifiers;
public int[] DamageModifiers;
public int[] InaccuracyModifiers;
public int Facing;
public WPos Source;
public Actor SourceActor;

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Traits
if (lobbyShroudFogDisabled)
return;
var disabled = self.TraitsImplementing<IDisable>().Any(d => d.Disabled);
var disabled = self.IsDisabled();
if (cachedLocation != self.Location || cachedDisabled != disabled)
{
cachedLocation = self.Location;

View File

@@ -329,14 +329,6 @@ namespace OpenRA.Traits
void OnObjectiveFailed(Player player, int objectiveID);
}
public static class DisableExts
{
public static bool IsDisabled(this Actor a)
{
return a.TraitsImplementing<IDisable>().Any(d => d.Disabled);
}
}
public interface ILegacyEditorRenderInfo
{
string EditorPalette { get; }

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Activities
{
readonly Target target;
readonly AttackPlane attackPlane;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
Activity inner;
int ticksUntilTurn;
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Activities
{
this.target = target;
attackPlane = self.TraitOrDefault<AttackPlane>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
ticksUntilTurn = attackPlane.AttackPlaneInfo.AttackTurnDelay;
}
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Activities
// Move to the next activity only if all ammo pools are depleted and none reload automatically
// TODO: This should check whether there is ammo left that is actually suitable for the target
if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
return NextActivity;
if (attackPlane != null)

View File

@@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Activities
readonly Target target;
readonly Helicopter helicopter;
readonly AttackHeli attackHeli;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
public HeliAttack(Actor self, Target target)
{
this.target = target;
helicopter = self.Trait<Helicopter>();
attackHeli = self.Trait<AttackHeli>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
}
public override Activity Tick(Actor self)
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Activities
// If all ammo pools are depleted and none reload automatically, return to helipad to reload and then move to next activity
// TODO: This should check whether there is ammo left that is actually suitable for the target
if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
return Util.SequenceActivities(new HeliReturn(self), NextActivity);
var dist = target.CenterPosition - self.CenterPosition;

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
class Demolish : Enter
{
readonly Actor target;
readonly IEnumerable<IDemolishable> demolishables;
readonly IDemolishable[] demolishables;
readonly int delay;
readonly int flashes;
readonly int flashesDelay;
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities
: base(self, target)
{
this.target = target;
demolishables = target.TraitsImplementing<IDemolishable>();
demolishables = target.TraitsImplementing<IDemolishable>().ToArray();
this.delay = delay;
this.flashes = flashes;
this.flashesDelay = flashesDelay;

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
{
readonly IPositionable positionable;
readonly IMove movement;
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
WPos start, end;
int length;
int ticks = 0;
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Activities
{
positionable = self.Trait<IPositionable>();
movement = self.TraitOrDefault<IMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.start = start;
this.end = end;
this.length = length;

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities
static readonly List<CPos> NoPath = new List<CPos>();
readonly Mobile mobile;
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
readonly WRange nearEnough;
readonly Func<List<CPos>> getPath;
readonly Actor ignoredActor;
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
self.World.WorldActor.Trait<IPathFinder>().FindPath(
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, WRange nearEnough)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
.FindUnitPath(mobile.ToCell, destination, self);
@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, SubCell subCell, WRange nearEnough)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
.FindUnitPathToRange(mobile.FromCell, subCell, self.World.Map.CenterOfSubCell(destination, subCell), nearEnough, self);
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, Actor ignoredActor)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
self.World.WorldActor.Trait<IPathFinder>().FindPath(
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, Target target, WRange range)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
{
@@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, Func<List<CPos>> getPath)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.getPath = getPath;
@@ -315,13 +315,12 @@ namespace OpenRA.Mods.Common.Activities
public override Activity Tick(Actor self)
{
var mobile = self.Trait<Mobile>();
var ret = InnerTick(self, Move.mobile);
mobile.IsMoving = ret is MovePart;
Move.mobile.IsMoving = ret is MovePart;
if (moveFraction > MoveFractionTotal)
moveFraction = MoveFractionTotal;
UpdateCenterLocation(self, mobile);
UpdateCenterLocation(self, Move.mobile);
return ret;
}

View File

@@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities
{
public class Rearm : Activity
{
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
readonly Dictionary<AmmoPool, int> ammoPoolsReloadTimes;
public Rearm(Actor self)
{
ammoPools = self.TraitsImplementing<AmmoPool>().Where(p => !p.Info.SelfReloads);
ammoPools = self.TraitsImplementing<AmmoPool>().Where(p => !p.Info.SelfReloads).ToArray();
if (ammoPools == null)
return;

View File

@@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities
{
public class Turn : Activity
{
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
readonly int desiredFacing;
public Turn(Actor self, int desiredFacing)
{
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.desiredFacing = desiredFacing;
}

View File

@@ -59,12 +59,12 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptPropertyGroup("Power")]
public class ActorPowerProperties : ScriptActorProperties, Requires<PowerInfo>
{
readonly IEnumerable<PowerTrait> power;
readonly PowerTrait[] power;
public ActorPowerProperties(ScriptContext context, Actor self)
: base(context, self)
{
power = self.TraitsImplementing<PowerTrait>();
power = self.TraitsImplementing<PowerTrait>().ToArray();
}
[Desc("Returns the power drained/provided by this actor.")]

View File

@@ -84,13 +84,13 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptPropertyGroup("Production")]
public class ProductionQueueProperties : ScriptActorProperties, Requires<ProductionQueueInfo>, Requires<ScriptTriggersInfo>
{
readonly List<ProductionQueue> queues;
readonly ProductionQueue[] queues;
readonly ScriptTriggers triggers;
public ProductionQueueProperties(ScriptContext context, Actor self)
: base(context, self)
{
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToList();
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToArray();
triggers = TriggerGlobal.GetScriptTriggers(self);
}

View File

@@ -167,10 +167,10 @@ namespace OpenRA.Mods.Common.Traits
Facing = legacyFacing,
DamageModifiers = self.TraitsImplementing<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier()),
.Select(a => a.GetFirepowerModifier()).ToArray(),
InaccuracyModifiers = self.TraitsImplementing<IInaccuracyModifier>()
.Select(a => a.GetInaccuracyModifier()),
.Select(a => a.GetInaccuracyModifier()).ToArray(),
Source = muzzlePosition,
SourceActor = self,

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits
this.self = self;
var armaments = Exts.Lazy(() => self.TraitsImplementing<Armament>()
.Where(a => info.Armaments.Contains(a.Info.Name)));
.Where(a => info.Armaments.Contains(a.Info.Name)).ToArray());
getArmaments = () => armaments.Value;

View File

@@ -9,6 +9,7 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Activities;
using OpenRA.Traits;
@@ -22,12 +23,12 @@ namespace OpenRA.Mods.Common.Traits
public class AttackTurreted : AttackFollow, ITick, ISync
{
protected IEnumerable<Turreted> turrets;
protected Turreted[] turrets;
public AttackTurreted(Actor self, AttackTurretedInfo info)
: base(self, info)
{
turrets = self.TraitsImplementing<Turreted>();
turrets = self.TraitsImplementing<Turreted>().ToArray();
}
protected override bool CanAttack(Actor self, Target target)

View File

@@ -312,6 +312,7 @@ namespace OpenRA.Mods.Common.Traits
internal int TicksBeforePathing = 0;
readonly Actor self;
readonly ISpeedModifier[] speedModifiers;
public readonly MobileInfo Info;
public bool IsMoving { get; set; }
@@ -351,6 +352,8 @@ namespace OpenRA.Mods.Common.Traits
self = init.Self;
Info = info;
speedModifiers = self.TraitsImplementing<ISpeedModifier>().ToArray();
ToSubCell = FromSubCell = info.SharesCell ? init.World.Map.DefaultSubCell : SubCell.FullCell;
if (init.Contains<SubCellInit>())
FromSubCell = ToSubCell = init.Get<SubCellInit, SubCell>();
@@ -597,7 +600,7 @@ namespace OpenRA.Mods.Common.Traits
return 0;
speed *= Info.Speed;
foreach (var t in self.TraitsImplementing<ISpeedModifier>())
foreach (var t in speedModifiers)
speed *= t.GetSpeedModifier() / 100m;
return (int)(speed / 100);

View File

@@ -54,11 +54,8 @@ namespace OpenRA.Mods.Common.Traits
DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
if (info.PauseOnLowPower)
{
var disabled = self.TraitsImplementing<IDisable>();
DefaultAnimation.Paused = () => disabled.Any(d => d.Disabled)
&& DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence);
}
DefaultAnimation.Paused = () =>
self.IsDisabled() && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence);
}
public void PlayCustomAnimThen(Actor self, string name, Action a)

View File

@@ -30,13 +30,11 @@ namespace OpenRA.Mods.Common.Traits
public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold
{
readonly IEnumerable<IDisable> disabled;
readonly WithActiveAnimationInfo info;
readonly RenderBuilding renderBuilding;
public WithActiveAnimation(Actor self, WithActiveAnimationInfo info)
{
disabled = self.TraitsImplementing<IDisable>();
renderBuilding = self.Trait<RenderBuilding>();
this.info = info;
}
@@ -49,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits
if (--ticks <= 0)
{
if (!(info.PauseOnLowPower && disabled.Any(d => d.Disabled)))
if (!(info.PauseOnLowPower && self.IsDisabled()))
renderBuilding.PlayCustomAnim(self, info.Sequence);
ticks = info.Interval;
}

View File

@@ -61,7 +61,6 @@ namespace OpenRA.Mods.Common.Traits
{
var rs = self.Trait<RenderSprites>();
var body = self.Trait<IBodyOrientation>();
var disabled = self.TraitsImplementing<IDisable>();
buildComplete = !self.HasTrait<Building>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self));
@@ -70,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits
new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => IsTraitDisabled || !buildComplete,
() => info.PauseOnLowPower && disabled.Any(d => d.Disabled),
() => info.PauseOnLowPower && self.IsDisabled(),
p => WithTurret.ZOffsetFromCenter(self, p, 1)),
info.Palette, info.IsPlayerPalette);
}

View File

@@ -27,9 +27,10 @@ namespace OpenRA.Mods.Common.Traits
class WithMuzzleFlash : UpgradableTrait<WithMuzzleFlashInfo>, INotifyAttack, IRender, ITick
{
Dictionary<Barrel, bool> visible = new Dictionary<Barrel, bool>();
Dictionary<Barrel, AnimationWithOffset> anims = new Dictionary<Barrel, AnimationWithOffset>();
Func<int> getFacing;
readonly Dictionary<Barrel, bool> visible = new Dictionary<Barrel, bool>();
readonly Dictionary<Barrel, AnimationWithOffset> anims = new Dictionary<Barrel, AnimationWithOffset>();
readonly Func<int> getFacing;
readonly Armament[] armaments;
public WithMuzzleFlash(Actor self, WithMuzzleFlashInfo info)
: base(info)
@@ -37,7 +38,9 @@ namespace OpenRA.Mods.Common.Traits
var render = self.Trait<RenderSprites>();
var facing = self.TraitOrDefault<IFacing>();
foreach (var arm in self.TraitsImplementing<Armament>())
armaments = self.TraitsImplementing<Armament>().ToArray();
foreach (var arm in armaments)
{
var armClosure = arm; // closure hazard in AnimationWithOffset
@@ -87,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
{
foreach (var arm in self.TraitsImplementing<Armament>())
foreach (var arm in armaments)
{
var palette = wr.Palette(arm.Info.MuzzlePalette);
foreach (var kv in anims)

View File

@@ -27,19 +27,17 @@ namespace OpenRA.Mods.Common.Traits
public class WithRepairAnimation : INotifyRepair
{
IEnumerable<IDisable> disabled;
WithRepairAnimationInfo info;
public WithRepairAnimation(Actor self, WithRepairAnimationInfo info)
{
disabled = self.TraitsImplementing<IDisable>();
this.info = info;
}
public void Repairing(Actor self, Actor host)
{
var building = host.TraitOrDefault<RenderBuilding>();
if (building != null && !(info.PauseOnLowPower && disabled.Any(d => d.Disabled)))
if (building != null && !(info.PauseOnLowPower && self.IsDisabled()))
building.PlayCustomAnim(host, info.Sequence);
}
}

View File

@@ -44,7 +44,6 @@ namespace OpenRA.Mods.Common.Traits
{
var rs = self.Trait<RenderSprites>();
var body = self.Trait<IBodyOrientation>();
var disabled = self.TraitsImplementing<IDisable>();
buildComplete = !self.HasTrait<Building>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self));
@@ -53,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits
new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !buildComplete,
() => info.PauseOnLowPower && disabled.Any(d => d.Disabled),
() => info.PauseOnLowPower && self.IsDisabled(),
p => WithTurret.ZOffsetFromCenter(self, p, 1)),
info.Palette, info.IsPlayerPalette);
}

View File

@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits
IBodyOrientation body;
AttackBase ab;
Turreted t;
IEnumerable<Armament> arms;
Armament[] arms;
Animation anim;
public WithTurret(Actor self, WithTurretInfo info)
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
t = self.TraitsImplementing<Turreted>()
.First(tt => tt.Name == info.Turret);
arms = self.TraitsImplementing<Armament>()
.Where(w => w.Info.Turret == info.Turret);
.Where(w => w.Info.Turret == info.Turret).ToArray();
anim = new Animation(self.World, rs.GetImage(self), () => t.TurretFacing);
anim.Play(info.Sequence);

View File

@@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.Traits
{
readonly RepairableInfo info;
readonly Health health;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
public Repairable(Actor self, RepairableInfo info)
{
this.info = info;
health = self.Trait<Health>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
}
public IEnumerable<IOrderTargeter> Orders
@@ -72,10 +72,7 @@ namespace OpenRA.Mods.Common.Traits
bool CanRearm()
{
if (ammoPools != null)
return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo());
else
return false;
return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo());
}
public string VoicePhraseForOrder(Actor self, Order order)

View File

@@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits
static bool InstanceDisabled(SupportPower sp)
{
return sp.Self.TraitsImplementing<IDisable>().Any(d => d.Disabled);
return sp.Self.IsDisabled();
}
bool notifiedCharging;

View File

@@ -13,7 +13,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class TurretedInfo : ITraitInfo, UsesInit<TurretFacingInit>
public class TurretedInfo : ITraitInfo, UsesInit<TurretFacingInit>, Requires<IBodyOrientationInfo>
{
public readonly string Turret = "primary";
[Desc("Rate of Turning")]
@@ -34,6 +34,7 @@ namespace OpenRA.Mods.Common.Traits
readonly TurretedInfo info;
AttackTurreted attack;
IFacing facing;
IBodyOrientation body;
[Sync] public int QuantizedFacings = 0;
[Sync] public int TurretFacing = 0;
@@ -67,6 +68,7 @@ namespace OpenRA.Mods.Common.Traits
{
attack = self.TraitOrDefault<AttackTurreted>();
facing = self.TraitOrDefault<IFacing>();
body = self.Trait<IBodyOrientation>();
}
public virtual void Tick(Actor self)
@@ -94,7 +96,6 @@ namespace OpenRA.Mods.Common.Traits
// Turret offset in world-space
public WVec Position(Actor self)
{
var body = self.Trait<IBodyOrientation>();
var bodyOrientation = body.QuantizeOrientation(self, self.Orientation);
return body.LocalToWorld(Offset.Rotate(bodyOrientation));
}

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets
public WorldTooltipType TooltipType { get; private set; }
public IToolTip ActorTooltip { get; private set; }
public IEnumerable<IProvideTooltipInfo> ActorTooltipExtra { get; private set; }
public IProvideTooltipInfo[] ActorTooltipExtra { get; private set; }
public FrozenActor FrozenActorTooltip { get; private set; }
public int EdgeScrollThreshold = 15;
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Widgets
if (underCursor != null)
{
ActorTooltip = underCursor.TraitsImplementing<IToolTip>().First();
ActorTooltipExtra = underCursor.TraitsImplementing<IProvideTooltipInfo>();
ActorTooltipExtra = underCursor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
TooltipType = WorldTooltipType.Actor;
return;
}
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
{
FrozenActorTooltip = frozen;
if (frozen.Actor != null)
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>();
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
TooltipType = WorldTooltipType.FrozenActor;
}
}

View File

@@ -50,10 +50,10 @@ namespace OpenRA.Mods.D2k.Traits
Facing = self.World.SharedRandom.Next(-1, 255),
DamageModifiers = self.TraitsImplementing<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier()),
.Select(a => a.GetFirepowerModifier()).ToArray(),
InaccuracyModifiers = self.TraitsImplementing<IInaccuracyModifier>()
.Select(a => a.GetInaccuracyModifier()),
.Select(a => a.GetInaccuracyModifier()).ToArray(),
Source = self.CenterPosition,
SourceActor = self,

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities
{
readonly Minelayer minelayer;
readonly MinelayerInfo info;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
readonly IMove movement;
readonly string[] rearmBuildings;
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
{
minelayer = self.TraitOrDefault<Minelayer>();
info = self.Info.Traits.Get<MinelayerInfo>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
movement = self.Trait<IMove>();
rearmBuildings = info.RearmBuildings;
}