Merge pull request #9189 from reaperrr/bye-rendersimple3

Remove RenderBuilding
This commit is contained in:
Pavel Penev
2015-09-02 19:21:01 +03:00
53 changed files with 559 additions and 408 deletions

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class RefineryInfo : ITraitInfo
public class RefineryInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Actual harvester facing when docking, 0-255 counter-clock-wise.")]
public readonly int DockAngle = 0;
@@ -47,6 +47,7 @@ namespace OpenRA.Mods.Common.Traits
{
readonly Actor self;
readonly RefineryInfo info;
readonly WithSpriteBody wsb;
PlayerResources playerResources;
int currentDisplayTick = 0;
@@ -69,6 +70,7 @@ namespace OpenRA.Mods.Common.Traits
this.info = info;
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
currentDisplayTick = info.TickRate;
wsb = self.Trait<WithSpriteBody>();
}
public virtual Activity DockSequence(Actor harv, Actor self)
@@ -105,7 +107,7 @@ namespace OpenRA.Mods.Common.Traits
// Harvester was killed while unloading
if (dockedHarv != null && dockedHarv.IsDead)
{
self.Trait<RenderBuilding>().CancelCustomAnim(self);
wsb.PlayCustomAnimation(self, wsb.Info.Sequence);
dockedHarv = null;
}

View File

@@ -8,15 +8,17 @@
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Effects;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Allows the player to execute build orders.", " Attach this to the player actor.")]
public class PlaceBuildingInfo : ITraitInfo
public class PlaceBuildingInfo : ITraitInfo, IPlaceBuildingDecoration
{
[Desc("Palette to use for rendering the placement sprite.")]
[PaletteReference] public readonly string Palette = "terrain";
@@ -28,6 +30,16 @@ namespace OpenRA.Mods.Common.Traits
public readonly string NewOptionsNotification = "NewOptions";
public object Create(ActorInitializer init) { return new PlaceBuilding(this); }
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
{
if (!ai.Traits.Get<BuildingInfo>().RequiresBaseProvider)
yield break;
foreach (var a in w.ActorsWithTrait<BaseProvider>())
foreach (var r in a.Trait.RenderAfterWorld(wr))
yield return r;
}
}
public class PlaceBuilding : IResolveOrder

View File

@@ -1,91 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Render trait for stationary objects that can be placed from the build palette.")]
public class RenderBuildingInfo : RenderSimpleInfo, Requires<BuildingInfo>, IPlaceBuildingDecoration
{
public readonly bool PauseOnLowPower = false;
public override object Create(ActorInitializer init) { return new RenderBuilding(init, this); }
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
{
if (!ai.Traits.Get<BuildingInfo>().RequiresBaseProvider)
yield break;
foreach (var a in w.ActorsWithTrait<BaseProvider>())
foreach (var r in a.Trait.RenderAfterWorld(wr))
yield return r;
}
}
public class RenderBuilding : RenderSimple, INotifyDamageStateChanged, INotifyBuildComplete
{
RenderBuildingInfo info;
public RenderBuilding(ActorInitializer init, RenderBuildingInfo info)
: this(init, info, () => 0) { }
public RenderBuilding(ActorInitializer init, RenderBuildingInfo info, Func<int> baseFacing)
: base(init, info, baseFacing)
{
var self = init.Self;
this.info = info;
DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
}
public virtual void BuildingComplete(Actor self)
{
DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
if (info.PauseOnLowPower)
DefaultAnimation.Paused = () =>
self.IsDisabled() && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence);
}
public void PlayCustomAnimThen(Actor self, string name, Action a)
{
DefaultAnimation.PlayThen(NormalizeSequence(self, name),
() => { DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence)); a(); });
}
public void PlayCustomAnimRepeating(Actor self, string name)
{
DefaultAnimation.PlayThen(NormalizeSequence(self, name),
() => PlayCustomAnimRepeating(self, name));
}
public void PlayCustomAnimBackwards(Actor self, string name, Action a)
{
DefaultAnimation.PlayBackwardsThen(NormalizeSequence(self, name),
() => { DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence)); a(); });
}
public void CancelCustomAnim(Actor self)
{
DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
}
public virtual void DamageStateChanged(Actor self, AttackInfo e)
{
if (DefaultAnimation.CurrentSequence != null)
DefaultAnimation.ReplaceAnim(NormalizeSequence(self, DefaultAnimation.CurrentSequence.Name));
}
}
}

View File

@@ -1,39 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Used for tesla coil and obelisk.")]
public class RenderBuildingChargeInfo : RenderBuildingInfo
{
[Desc("Sequence to use for building charge animation.")]
[SequenceReference] public readonly string ChargeSequence = "active";
public override object Create(ActorInitializer init) { return new RenderBuildingCharge(init, this); }
}
public class RenderBuildingCharge : RenderBuilding, INotifyCharging
{
RenderBuildingChargeInfo info;
public RenderBuildingCharge(ActorInitializer init, RenderBuildingChargeInfo info)
: base(init, info)
{
this.info = info;
}
public void Charging(Actor self, Target target)
{
PlayCustomAnim(self, info.ChargeSequence);
}
}
}

View File

@@ -1,61 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Render trait for buildings that change the sprite according to the remaining resource storage capacity across all depots.")]
class RenderBuildingSiloInfo : RenderBuildingInfo
{
public override object Create(ActorInitializer init) { return new RenderBuildingSilo(init, this); }
public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
{
// Show a static frame instead of animating all of the fullness states
var anim = new Animation(init.World, image, () => 0);
anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence), () => 0);
yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale);
}
}
class RenderBuildingSilo : RenderBuilding, INotifyBuildComplete, INotifyOwnerChanged
{
readonly RenderBuildingSiloInfo info;
PlayerResources playerResources;
public RenderBuildingSilo(ActorInitializer init, RenderBuildingSiloInfo info)
: base(init, info)
{
this.info = info;
playerResources = init.Self.Owner.PlayerActor.Trait<PlayerResources>();
}
public override void BuildingComplete(Actor self)
{
var animation = RenderSprites.NormalizeSequence(DefaultAnimation, self.GetDamageState(), info.Sequence);
DefaultAnimation.PlayFetchIndex(animation,
() => playerResources.ResourceCapacity != 0
? ((10 * DefaultAnimation.CurrentSequence.Length - 1) * playerResources.Resources) / (10 * playerResources.ResourceCapacity)
: 0);
}
public override void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
base.OnOwnerChanged(self, oldOwner, newOwner);
}
}
}

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Replaces the idle animation of a building.")]
public class WithActiveAnimationInfo : ITraitInfo, Requires<RenderBuildingInfo>
public class WithActiveAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "active";
@@ -31,11 +31,11 @@ namespace OpenRA.Mods.Common.Traits
public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold
{
readonly WithActiveAnimationInfo info;
readonly RenderBuilding renderBuilding;
readonly WithSpriteBody wsb;
public WithActiveAnimation(Actor self, WithActiveAnimationInfo info)
{
renderBuilding = self.Trait<RenderBuilding>();
wsb = self.Trait<WithSpriteBody>();
this.info = info;
}
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
if (--ticks <= 0)
{
if (!(info.PauseOnLowPower && self.IsDisabled()))
renderBuilding.PlayCustomAnim(self, info.Sequence);
wsb.PlayCustomAnimation(self, info.Sequence);
ticks = info.Interval;
}
}

View File

@@ -13,10 +13,10 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Changes the animation when the actor constructed a building.")]
public class WithBuildingPlacedAnimationInfo : ITraitInfo, Requires<RenderSimpleInfo>
public class WithBuildingPlacedAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "build";
[Desc("Sequence name to use"), SequenceReference]
public readonly string Sequence = "build";
public object Create(ActorInitializer init) { return new WithBuildingPlacedAnimation(init.Self, this); }
}
@@ -24,13 +24,13 @@ namespace OpenRA.Mods.Common.Traits
public class WithBuildingPlacedAnimation : INotifyBuildingPlaced, INotifyBuildComplete
{
readonly WithBuildingPlacedAnimationInfo info;
readonly RenderSimple renderSimple;
readonly WithSpriteBody wsb;
bool buildComplete;
public WithBuildingPlacedAnimation(Actor self, WithBuildingPlacedAnimationInfo info)
{
this.info = info;
renderSimple = self.Trait<RenderSimple>();
wsb = self.Trait<WithSpriteBody>();
buildComplete = !self.HasTrait<Building>();
}
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
public void BuildingPlaced(Actor self)
{
if (buildComplete)
renderSimple.PlayCustomAnim(self, info.Sequence);
wsb.PlayCustomAnimation(self, info.Sequence, () => wsb.CancelCustomAnimation(self));
}
}
}

View File

@@ -0,0 +1,40 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor displays a charge-up animation before firing.")]
public class WithChargeAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>, Requires<RenderSpritesInfo>
{
[Desc("Sequence to use for charge animation.")]
[SequenceReference] public readonly string ChargeSequence = "active";
public object Create(ActorInitializer init) { return new WithChargeAnimation(init, this); }
}
public class WithChargeAnimation : INotifyCharging
{
readonly WithChargeAnimationInfo info;
readonly WithSpriteBody wsb;
public WithChargeAnimation(ActorInitializer init, WithChargeAnimationInfo info)
{
this.info = info;
wsb = init.Self.Trait<WithSpriteBody>();
}
public void Charging(Actor self, Target target)
{
wsb.PlayCustomAnimation(self, info.ChargeSequence);
}
}
}

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Replaces the sprite during construction.")]
public class WithMakeAnimationInfo : ITraitInfo, Requires<BuildingInfo>, Requires<RenderBuildingInfo>
public class WithMakeAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "make";
@@ -29,18 +29,18 @@ namespace OpenRA.Mods.Common.Traits
public class WithMakeAnimation
{
readonly WithMakeAnimationInfo info;
readonly RenderBuilding renderBuilding;
readonly WithSpriteBody wsb;
public WithMakeAnimation(ActorInitializer init, WithMakeAnimationInfo info)
{
this.info = info;
var self = init.Self;
renderBuilding = self.Trait<RenderBuilding>();
wsb = self.Trait<WithSpriteBody>();
var building = self.Trait<Building>();
if (!building.SkipMakeAnimation)
var building = self.TraitOrDefault<Building>();
if (building != null && !building.SkipMakeAnimation)
{
renderBuilding.PlayCustomAnimThen(self, info.Sequence, () =>
wsb.PlayCustomAnimation(self, info.Sequence, () =>
{
building.NotifyBuildingComplete(self);
});
@@ -49,10 +49,10 @@ namespace OpenRA.Mods.Common.Traits
public void Reverse(Actor self, Activity activity, bool queued = true)
{
renderBuilding.PlayCustomAnimBackwards(self, info.Sequence, () =>
wsb.PlayCustomAnimationBackwards(self, info.Sequence, () =>
{
// avoids visual glitches as we wait for the actor to get destroyed
renderBuilding.DefaultAnimation.PlayFetchIndex(info.Sequence, () => 0);
wsb.DefaultAnimation.PlayFetchIndex(info.Sequence, () => 0);
self.QueueActivity(queued, activity);
});
}

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Replaces the building animation when it repairs a unit.")]
public class WithRepairAnimationInfo : ITraitInfo, Requires<RenderBuildingInfo>
public class WithRepairAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "active";
@@ -36,9 +36,9 @@ namespace OpenRA.Mods.Common.Traits
public void Repairing(Actor self, Actor host)
{
var building = host.TraitOrDefault<RenderBuilding>();
if (building != null && !(info.PauseOnLowPower && self.IsDisabled()))
building.PlayCustomAnim(host, info.Sequence);
var spriteBody = host.TraitOrDefault<WithSpriteBody>();
if (spriteBody != null && !(info.PauseOnLowPower && self.IsDisabled()))
spriteBody.PlayCustomAnimation(host, info.Sequence);
}
}
}

View File

@@ -14,7 +14,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Displays the fill status of PlayerResources with an extra sprite overlay on the actor.")]
class WithResourcesInfo : ITraitInfo, Requires<RenderSimpleInfo>
class WithResourcesInfo : ITraitInfo, Requires<WithSpriteBodyInfo>, Requires<RenderSpritesInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "resources";
@@ -26,7 +26,8 @@ namespace OpenRA.Mods.Common.Traits
{
readonly WithResourcesInfo info;
readonly AnimationWithOffset anim;
readonly RenderSimple rs;
readonly RenderSprites rs;
readonly WithSpriteBody wsb;
PlayerResources playerResources;
bool buildComplete;
@@ -34,7 +35,8 @@ namespace OpenRA.Mods.Common.Traits
public WithResources(Actor self, WithResourcesInfo info)
{
this.info = info;
rs = self.Trait<RenderSimple>();
rs = self.Trait<RenderSprites>();
wsb = self.Trait<WithSpriteBody>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
var a = new Animation(self.World, rs.GetImage(self));
@@ -55,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
public void DamageStateChanged(Actor self, AttackInfo e)
{
if (anim.Animation.CurrentSequence != null)
anim.Animation.ReplaceAnim(rs.NormalizeSequence(self, info.Sequence));
anim.Animation.ReplaceAnim(wsb.NormalizeSequence(self, info.Sequence));
}
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)

View File

@@ -0,0 +1,55 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Render trait for buildings that change the sprite according to the remaining resource storage capacity across all depots.")]
class WithSiloAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>, Requires<RenderSpritesInfo>
{
public readonly int Stages = 10;
public object Create(ActorInitializer init) { return new WithSiloAnimation(init, this); }
}
class WithSiloAnimation : INotifyBuildComplete, INotifyOwnerChanged
{
readonly WithSiloAnimationInfo info;
readonly WithSpriteBody wsb;
PlayerResources playerResources;
public WithSiloAnimation(ActorInitializer init, WithSiloAnimationInfo info)
{
this.info = info;
wsb = init.Self.Trait<WithSpriteBody>();
playerResources = init.Self.Owner.PlayerActor.Trait<PlayerResources>();
}
public void BuildingComplete(Actor self)
{
var animation = wsb.NormalizeSequence(self, wsb.Info.Sequence);
wsb.DefaultAnimation.PlayFetchIndex(animation,
() => playerResources.ResourceCapacity != 0
? ((info.Stages * wsb.DefaultAnimation.CurrentSequence.Length - 1) * playerResources.Resources) / (info.Stages * playerResources.ResourceCapacity)
: 0);
}
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
OnOwnerChanged(self, oldOwner, newOwner);
}
}
}

View File

@@ -19,11 +19,14 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Default trait for rendering sprite-based actors.")]
public class WithSpriteBodyInfo : UpgradableTraitInfo, IRenderActorPreviewSpritesInfo, Requires<RenderSpritesInfo>
{
[Desc("Animation to play when the actor is created.")]
[SequenceReference] public readonly string StartSequence = null;
[Desc("Animation to play when the actor is created."), SequenceReference]
public readonly string StartSequence = null;
[Desc("Animation to play when the actor is idle.")]
[SequenceReference] public readonly string Sequence = "idle";
[Desc("Animation to play when the actor is idle."), SequenceReference]
public readonly string Sequence = "idle";
[Desc("Pause animation when actor is disabled.")]
public readonly bool PauseAnimationWhenDisabled = false;
public override object Create(ActorInitializer init) { return new WithSpriteBody(init, this); }
@@ -36,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
}
}
public class WithSpriteBody : UpgradableTrait<WithSpriteBodyInfo>, ISpriteBody, INotifyDamageStateChanged
public class WithSpriteBody : UpgradableTrait<WithSpriteBodyInfo>, ISpriteBody, INotifyDamageStateChanged, INotifyBuildComplete
{
public readonly Animation DefaultAnimation;
@@ -56,6 +59,10 @@ namespace OpenRA.Mods.Common.Traits
() => PlayCustomAnimationRepeating(init.Self, info.Sequence));
else
DefaultAnimation.PlayRepeating(NormalizeSequence(init.Self, info.Sequence));
if (info.PauseAnimationWhenDisabled)
DefaultAnimation.Paused = () =>
init.Self.IsDisabled() && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(init.Self, Info.Sequence);
}
public string NormalizeSequence(Actor self, string sequence)
@@ -63,6 +70,12 @@ namespace OpenRA.Mods.Common.Traits
return RenderSprites.NormalizeSequence(DefaultAnimation, self.GetDamageState(), sequence);
}
// TODO: Get rid of INotifyBuildComplete in favor of using the upgrade system
public virtual void BuildingComplete(Actor self)
{
DefaultAnimation.PlayRepeating(NormalizeSequence(self, Info.Sequence));
}
public void PlayCustomAnimation(Actor self, string name, Action after = null)
{
DefaultAnimation.PlayThen(NormalizeSequence(self, name), () =>

View File

@@ -17,24 +17,25 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
class RenderBuildingTurretedInfo : RenderBuildingInfo, Requires<TurretedInfo>
[Desc("This actor has turret art with facings baked into the sprite.")]
public class WithTurretedSpriteBodyInfo : WithSpriteBodyInfo, Requires<TurretedInfo>, Requires<IBodyOrientationInfo>
{
public override object Create(ActorInitializer init) { return new RenderBuildingTurreted(init, this); }
public override object Create(ActorInitializer init) { return new WithTurretedSpriteBody(init, this); }
public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
{
var t = init.Actor.Traits.WithInterface<TurretedInfo>()
.FirstOrDefault();
var t = init.Actor.Traits.WithInterface<TurretedInfo>().FirstOrDefault();
var wsb = init.Actor.Traits.WithInterface<WithSpriteBodyInfo>().FirstOrDefault();
// Show the correct turret facing
var anim = new Animation(init.World, image, () => t.InitialFacing);
anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));
anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), wsb.Sequence));
yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale);
}
}
class RenderBuildingTurreted : RenderBuilding
public class WithTurretedSpriteBody : WithSpriteBody
{
readonly Turreted turreted;
@@ -45,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits
return () => turreted.TurretFacing;
}
public RenderBuildingTurreted(ActorInitializer init, RenderBuildingInfo info)
public WithTurretedSpriteBody(ActorInitializer init, WithSpriteBodyInfo info)
: base(init, info, MakeTurretFacingFunc(init.Self))
{
turreted = init.Self.TraitsImplementing<Turreted>().FirstOrDefault();

View File

@@ -17,11 +17,11 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Render trait for actors that change sprites if neighbors with the same trait are present.")]
class RenderBuildingWallInfo : RenderBuildingInfo
class WithWallSpriteBodyInfo : WithSpriteBodyInfo
{
public readonly string Type = "wall";
public override object Create(ActorInitializer init) { return new RenderBuildingWall(init, this); }
public override object Create(ActorInitializer init) { return new WithWallSpriteBody(init, this); }
public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
{
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
var haveNeighbour = false;
foreach (var n in kv.Value)
{
var rb = init.World.Map.Rules.Actors[n].Traits.GetOrDefault<RenderBuildingWallInfo>();
var rb = init.World.Map.Rules.Actors[n].Traits.GetOrDefault<WithWallSpriteBodyInfo>();
if (rb != null && rb.Type == Type)
{
haveNeighbour = true;
@@ -68,33 +68,26 @@ namespace OpenRA.Mods.Common.Traits
}
}
class RenderBuildingWall : RenderBuilding, INotifyAddedToWorld, INotifyRemovedFromWorld
class WithWallSpriteBody : WithSpriteBody, INotifyAddedToWorld, INotifyRemovedFromWorld, ITick
{
readonly RenderBuildingWallInfo info;
readonly WithWallSpriteBodyInfo wallInfo;
int adjacent = 0;
bool dirty = true;
public RenderBuildingWall(ActorInitializer init, RenderBuildingWallInfo info)
: base(init, info)
public WithWallSpriteBody(ActorInitializer init, WithWallSpriteBodyInfo info)
: base(init, info, () => 0)
{
this.info = info;
}
public override void BuildingComplete(Actor self)
{
DefaultAnimation.PlayFetchIndex(info.Sequence, () => adjacent);
UpdateNeighbours(self);
wallInfo = info;
DefaultAnimation.PlayFetchIndex(NormalizeSequence(init.Self, Info.Sequence), () => adjacent);
}
public override void DamageStateChanged(Actor self, AttackInfo e)
{
DefaultAnimation.PlayFetchIndex(NormalizeSequence(DefaultAnimation, e.DamageState, info.Sequence), () => adjacent);
DefaultAnimation.PlayFetchIndex(NormalizeSequence(self, Info.Sequence), () => adjacent);
}
public override void Tick(Actor self)
public void Tick(Actor self)
{
base.Tick(self);
if (!dirty)
return;
@@ -105,8 +98,8 @@ namespace OpenRA.Mods.Common.Traits
adjacent = 0;
foreach (var a in adjacentActors)
{
var rb = a.TraitOrDefault<RenderBuildingWall>();
if (rb == null || rb.info.Type != info.Type)
var rb = a.TraitOrDefault<WithWallSpriteBody>();
if (rb == null || rb.wallInfo.Type != wallInfo.Type)
continue;
var location = self.Location;
@@ -129,7 +122,7 @@ namespace OpenRA.Mods.Common.Traits
{
var adjacentActors = CVec.Directions.SelectMany(dir =>
self.World.ActorMap.GetUnitsAt(self.Location + dir))
.Select(a => a.TraitOrDefault<RenderBuildingWall>())
.Select(a => a.TraitOrDefault<WithWallSpriteBody>())
.Where(a => a != null);
foreach (var rb in adjacentActors)
@@ -138,6 +131,7 @@ namespace OpenRA.Mods.Common.Traits
public void AddedToWorld(Actor self)
{
DefaultAnimation.PlayFetchIndex(NormalizeSequence(self, Info.Sequence), () => adjacent);
UpdateNeighbours(self);
}

View File

@@ -30,6 +30,9 @@ namespace OpenRA.Mods.Common.Traits
public readonly int Range = 1;
public readonly string GrantUpgradeSound = "ironcur9.aud";
[Desc("Sequence to play for granting actor when activated."), SequenceReference]
public readonly string GrantUpgradeSequence = "active";
public override object Create(ActorInitializer init) { return new GrantUpgradePower(init.Self, this); }
}
@@ -53,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits
{
base.Activate(self, order, manager);
self.Trait<RenderBuilding>().PlayCustomAnim(self, "active");
self.Trait<WithSpriteBody>().PlayCustomAnimation(self, info.GrantUpgradeSequence);
Sound.Play(info.GrantUpgradeSound, self.World.Map.CenterOfCell(order.TargetLocation));

View File

@@ -47,6 +47,10 @@ namespace OpenRA.Mods.Common.Traits
public readonly string FlashType = null;
[SequenceReference]
[Desc("Sequence the launching actor should play when activating this power.")]
public readonly string ActivationSequence = "active";
public override object Create(ActorInitializer init) { return new NukePower(init.Self, this); }
}
@@ -71,8 +75,11 @@ namespace OpenRA.Mods.Common.Traits
else
Sound.Play(Info.IncomingSound);
var rb = self.Trait<RenderSimple>();
rb.PlayCustomAnim(self, "active");
if (!string.IsNullOrEmpty(info.ActivationSequence))
{
var wsb = self.Trait<WithSpriteBody>();
wsb.PlayCustomAnimation(self, info.ActivationSequence);
}
var targetPosition = self.World.Map.CenterOfCell(order.TargetLocation);
var missile = new NukeLaunch(self.Owner, info.MissileWeapon,