From 00a214629950a52670cc74da12540ceb192a9fe6 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 9 Jul 2014 18:44:25 +1200 Subject: [PATCH] Adjust GetImage plumbing in preparation for race-specific sequences. --- OpenRA.Editor/Form1.cs | 4 ++- OpenRA.Editor/RenderUtils.cs | 4 +-- OpenRA.Game/Map/ActorInitializer.cs | 10 +++++++ OpenRA.Game/Traits/BodyOrientation.cs | 8 +++--- OpenRA.Game/Traits/TraitsInterfaces.cs | 4 +-- .../Traits/Render/RenderGunboat.cs | 2 +- .../Player/ProvidesCustomPrerequisite.cs | 10 ------- .../Traits/Render/RenderInfantry.cs | 4 +-- .../Traits/Render/RenderSimple.cs | 6 ++--- .../Traits/Render/RenderSprites.cs | 26 ++++++++++--------- .../Widgets/ObserverProductionIconsWidget.cs | 4 ++- .../Widgets/ProductionPaletteWidget.cs | 5 +++- OpenRA.Mods.D2k/Traits/AutoCarryall.cs | 3 ++- .../Traits/Buildings/ClonesProducedUnits.cs | 10 ++++--- OpenRA.Mods.TS/Traits/Render/RenderVoxels.cs | 4 +-- OpenRA.Mods.TS/Traits/Render/WithVoxelBody.cs | 2 +- .../Traits/Render/WithVoxelUnloadBody.cs | 2 +- .../Traits/Render/WithVoxelWalkerBody.cs | 2 +- 18 files changed, 62 insertions(+), 48 deletions(-) diff --git a/OpenRA.Editor/Form1.cs b/OpenRA.Editor/Form1.cs index 9e63ef1bee..c52f39e8e1 100644 --- a/OpenRA.Editor/Form1.cs +++ b/OpenRA.Editor/Form1.cs @@ -238,7 +238,9 @@ namespace OpenRA.Editor if (rsi != null && rsi.EditorPalette != null && rsi.EditorPalette.Contains("terrain")) templatePalette = palette; - var template = RenderUtils.RenderActor(info, tileset, templatePalette); + var race = Program.Rules.Actors["world"].Traits.WithInterface().First().Race; + var sequenceProvider = Program.Rules.Sequences[tileset.Id]; + var template = RenderUtils.RenderActor(info, sequenceProvider, tileset, templatePalette, race); var ibox = new PictureBox { Image = template.Bitmap, diff --git a/OpenRA.Editor/RenderUtils.cs b/OpenRA.Editor/RenderUtils.cs index 1111b4bd53..45b77c135a 100644 --- a/OpenRA.Editor/RenderUtils.cs +++ b/OpenRA.Editor/RenderUtils.cs @@ -46,9 +46,9 @@ namespace OpenRA.Editor return bitmap; } - public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, IPalette p) + public static ActorTemplate RenderActor(ActorInfo info, SequenceProvider sequenceProvider, TileSet tileset, IPalette p, string race) { - var image = info.Traits.Get().EditorImage(info); + var image = info.Traits.Get().EditorImage(info, sequenceProvider, race); using (var s = GlobalFileSystem.OpenWithExts(image, tileset.Extensions)) { var shp = new ShpTDSprite(s); diff --git a/OpenRA.Game/Map/ActorInitializer.cs b/OpenRA.Game/Map/ActorInitializer.cs index 5e88aec442..3e68491065 100755 --- a/OpenRA.Game/Map/ActorInitializer.cs +++ b/OpenRA.Game/Map/ActorInitializer.cs @@ -102,4 +102,14 @@ namespace OpenRA return world.Players.First(x => x.InternalName == PlayerName); } } + + // Allows maps / transformations to specify the race variant of an actor. + public class RaceInit : IActorInit + { + [FieldFromYamlKey] public readonly string Race; + + public RaceInit() { } + public RaceInit(string race) { Race = race; } + public string Value(World world) { return Race; } + } } diff --git a/OpenRA.Game/Traits/BodyOrientation.cs b/OpenRA.Game/Traits/BodyOrientation.cs index 2bf98ac4d9..98a33e87fb 100644 --- a/OpenRA.Game/Traits/BodyOrientation.cs +++ b/OpenRA.Game/Traits/BodyOrientation.cs @@ -40,7 +40,7 @@ namespace OpenRA.Traits return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); } - public object Create(ActorInitializer init) { return new BodyOrientation(init.Self, this); } + public object Create(ActorInitializer init) { return new BodyOrientation(init, this); } } public class BodyOrientation : IBodyOrientation @@ -50,9 +50,11 @@ namespace OpenRA.Traits [Sync] public int QuantizedFacings { get { return quantizedFacings.Value; } } - public BodyOrientation(Actor self, BodyOrientationInfo info) + public BodyOrientation(ActorInitializer init, BodyOrientationInfo info) { this.info = info; + var self = init.Self; + var race = init.Contains() ? init.Get() : self.Owner.Country.Race; quantizedFacings = Exts.Lazy(() => { @@ -64,7 +66,7 @@ namespace OpenRA.Traits if (qboi == null) throw new InvalidOperationException("Actor type '" + self.Info.Name + "' does not define a quantized body orientation."); - return qboi.QuantizedBodyFacings(self.World.Map.SequenceProvider, self.Info); + return qboi.QuantizedBodyFacings(self.Info, self.World.Map.SequenceProvider, race); }); } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 9edb9b8932..748de195d8 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -289,7 +289,7 @@ namespace OpenRA.Traits WRot QuantizeOrientation(WRot orientation, int facings); } - public interface IQuantizeBodyOrientationInfo { int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai); } + public interface IQuantizeBodyOrientationInfo { int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race); } public interface ITargetableInfo { @@ -334,6 +334,6 @@ namespace OpenRA.Traits public interface ILegacyEditorRenderInfo { string EditorPalette { get; } - string EditorImage(ActorInfo actor); + string EditorImage(ActorInfo actor, SequenceProvider sequenceProvider, string race); } } diff --git a/OpenRA.Mods.Cnc/Traits/Render/RenderGunboat.cs b/OpenRA.Mods.Cnc/Traits/Render/RenderGunboat.cs index 33fa9c7991..2d57522e13 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/RenderGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/RenderGunboat.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Cnc.Traits public override object Create(ActorInitializer init) { return new RenderGunboat(init, this); } - public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) + public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return 2; } diff --git a/OpenRA.Mods.Common/Traits/Player/ProvidesCustomPrerequisite.cs b/OpenRA.Mods.Common/Traits/Player/ProvidesCustomPrerequisite.cs index 5c1c4b2758..ee601256e0 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProvidesCustomPrerequisite.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProvidesCustomPrerequisite.cs @@ -74,14 +74,4 @@ namespace OpenRA.Mods.Common.Traits enabled = owner.PlayerActor.Trait().HasPrerequisites(info.RequiresPrerequisites); } } - - // Allows maps / transformations to specify the race variant of an actor. - public class RaceInit : IActorInit - { - [FieldFromYamlKey] public readonly string Race; - - public RaceInit() { } - public RaceInit(string race) { Race = race; } - public string Value(World world) { return Race; } - } } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderInfantry.cs b/OpenRA.Mods.Common/Traits/Render/RenderInfantry.cs index 8d26f34c76..c1ee3ac157 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderInfantry.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderInfantry.cs @@ -39,9 +39,9 @@ namespace OpenRA.Mods.Common.Traits yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale); } - public override int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) + public override int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { - return sequenceProvider.GetSequence(RenderSprites.GetImage(ai), StandAnimations.First()).Facings; + return sequenceProvider.GetSequence(GetImage(ai, sequenceProvider, race), StandAnimations.First()).Facings; } } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderSimple.cs b/OpenRA.Mods.Common/Traits/Render/RenderSimple.cs index ae58ea382a..36f876263d 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSimple.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSimple.cs @@ -30,13 +30,13 @@ namespace OpenRA.Mods.Common.Traits yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale); } - public virtual int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) + public virtual int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { - return sequenceProvider.GetSequence(RenderSprites.GetImage(ai), "idle").Facings; + return sequenceProvider.GetSequence(GetImage(ai, sequenceProvider, race), "idle").Facings; } public string EditorPalette { get { return Palette; } } - public string EditorImage(ActorInfo actor) { return RenderSimple.GetImage(actor); } + public string EditorImage(ActorInfo actor, SequenceProvider sequenceProvider, string race) { return GetImage(actor, sequenceProvider, race); } } public class RenderSimple : RenderSprites, IAutoSelectionSize diff --git a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs index 1dc38c7677..160b6edd5f 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs @@ -37,18 +37,24 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable RenderPreview(ActorPreviewInitializer init) { var sequenceProvider = init.World.Map.SequenceProvider; - var image = RenderSprites.GetImage(init.Actor); - var palette = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null)); + var race = init.Contains() ? init.Get() : init.Owner.Country.Race; + var image = GetImage(init.Actor, sequenceProvider, race); + var palette = init.WorldRenderer.Palette(Palette ?? PlayerPalette + init.Owner.InternalName); var facings = 0; var body = init.Actor.Traits.GetOrDefault(); if (body != null) - facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings; + facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get().QuantizedBodyFacings(init.Actor, sequenceProvider, init.Owner.Country.Race) : body.QuantizedFacings; foreach (var spi in init.Actor.Traits.WithInterface()) foreach (var preview in spi.RenderPreviewSprites(init, this, image, facings, palette)) yield return preview; } + + public string GetImage(ActorInfo actor, SequenceProvider sequenceProvider, string race) + { + return (Image ?? actor.Name).ToLowerInvariant(); + } } public class RenderSprites : IRender, ITick, INotifyOwnerChanged, INotifyEffectiveOwnerChanged @@ -88,9 +94,10 @@ namespace OpenRA.Mods.Common.Traits } } + readonly string race; readonly RenderSpritesInfo info; - string cachedImage = null; - Dictionary anims = new Dictionary(); + readonly Dictionary anims = new Dictionary(); + string cachedImage; public static Func MakeFacingFunc(Actor self) { @@ -102,12 +109,7 @@ namespace OpenRA.Mods.Common.Traits public RenderSprites(ActorInitializer init, RenderSpritesInfo info) { this.info = info; - } - - public static string GetImage(ActorInfo actor) - { - var info = actor.Traits.Get(); - return (info.Image ?? actor.Name).ToLowerInvariant(); + race = init.Contains() ? init.Get() : init.Self.Owner.Country.Race; } public string GetImage(Actor self) @@ -115,7 +117,7 @@ namespace OpenRA.Mods.Common.Traits if (cachedImage != null) return cachedImage; - return cachedImage = GetImage(self.Info); + return cachedImage = info.GetImage(self.Info, self.World.Map.SequenceProvider, race); } protected void UpdatePalette() diff --git a/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs b/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs index 1eff05759f..941ea90b37 100644 --- a/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ObserverProductionIconsWidget.cs @@ -67,11 +67,13 @@ namespace OpenRA.Mods.Common.Widgets if (current == null) continue; + var race = queue.Trait.Actor.Owner.Country.Race; var actor = queue.Trait.AllItems().FirstOrDefault(a => a.Name == current.Item); if (actor == null) continue; - var icon = new Animation(world, RenderSimple.GetImage(actor)); + var rsi = actor.Traits.Get(); + var icon = new Animation(world, rsi.GetImage(actor, world.Map.SequenceProvider, race)); icon.Play(actor.Traits.Get().Icon); var location = new float2(RenderBounds.Location) + new float2(queue.i * (IconWidth + IconSpacing), 0); WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer, 0.5f); diff --git a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs index 162464df2f..43bccc5603 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs @@ -268,13 +268,16 @@ namespace OpenRA.Mods.Common.Widgets var ks = Game.Settings.Keys; var rb = RenderBounds; + var race = CurrentQueue.Actor.Owner.Country.Race; foreach (var item in AllBuildables.Skip(IconRowOffset * Columns).Take(MaxIconRowOffset * Columns)) { var x = DisplayedIconCount % Columns; var y = DisplayedIconCount / Columns; var rect = new Rectangle(rb.X + x * (IconSize.X + IconMargin.X), rb.Y + y * (IconSize.Y + IconMargin.Y), IconSize.X, IconSize.Y); - var icon = new Animation(World, RenderSimple.GetImage(item)); + + var rsi = item.Traits.Get(); + var icon = new Animation(World, rsi.GetImage(item, World.Map.SequenceProvider, race)); icon.Play(item.Traits.Get().Icon); var pi = new ProductionIcon() diff --git a/OpenRA.Mods.D2k/Traits/AutoCarryall.cs b/OpenRA.Mods.D2k/Traits/AutoCarryall.cs index ad273dfe14..7952689267 100644 --- a/OpenRA.Mods.D2k/Traits/AutoCarryall.cs +++ b/OpenRA.Mods.D2k/Traits/AutoCarryall.cs @@ -152,7 +152,8 @@ namespace OpenRA.Mods.D2k.Traits isCarrying = true; // Create a new animation for our carryable unit - anim = new Animation(self.World, RenderSprites.GetImage(carryable.Info), RenderSprites.MakeFacingFunc(self)); + var rs = carryable.Trait(); + anim = new Animation(self.World, rs.GetImage(carryable), RenderSprites.MakeFacingFunc(self)); anim.PlayRepeating("idle"); anim.IsDecoration = true; } diff --git a/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs b/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs index c083f7ca54..3dc1e0ba8d 100644 --- a/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs +++ b/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs @@ -21,18 +21,20 @@ namespace OpenRA.Mods.RA.Traits [Desc("Uses the \"Cloneable\" trait to determine whether or not we should clone a produced unit.")] public readonly string[] CloneableTypes = { }; - public object Create(ActorInitializer init) { return new ClonesProducedUnits(init.Self, this); } + public object Create(ActorInitializer init) { return new ClonesProducedUnits(init, this); } } public class ClonesProducedUnits : INotifyOtherProduction { readonly ClonesProducedUnitsInfo info; readonly Production production; + readonly string race; - public ClonesProducedUnits(Actor self, ClonesProducedUnitsInfo info) + public ClonesProducedUnits(ActorInitializer init, ClonesProducedUnitsInfo info) { this.info = info; - production = self.Trait(); + production = init.Self.Trait(); + race = init.Contains() ? init.Get() : init.Self.Owner.Country.Race; } public void UnitProducedByOther(Actor self, Actor producer, Actor produced) @@ -45,7 +47,7 @@ namespace OpenRA.Mods.RA.Traits if (ci == null || !info.CloneableTypes.Intersect(ci.Types).Any()) return; - production.Produce(self, produced.Info, self.Owner.Country.Race); + production.Produce(self, produced.Info, race); } } } diff --git a/OpenRA.Mods.TS/Traits/Render/RenderVoxels.cs b/OpenRA.Mods.TS/Traits/Render/RenderVoxels.cs index d60c9b6909..e3dccf5c21 100644 --- a/OpenRA.Mods.TS/Traits/Render/RenderVoxels.cs +++ b/OpenRA.Mods.TS/Traits/Render/RenderVoxels.cs @@ -46,8 +46,8 @@ namespace OpenRA.Mods.TS.Traits var body = init.Actor.Traits.Get(); var sequenceProvider = init.World.Map.SequenceProvider; var image = Image ?? init.Actor.Name; - var facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings; - var palette = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null)); + var facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get().QuantizedBodyFacings(init.Actor, sequenceProvider, init.Owner.Country.Race) : body.QuantizedFacings; + var palette = init.WorldRenderer.Palette(Palette ?? PlayerPalette + init.Owner.InternalName); var ifacing = init.Actor.Traits.GetOrDefault(); var facing = ifacing != null ? init.Contains() ? init.Get() : ifacing.GetInitialFacing() : 0; diff --git a/OpenRA.Mods.TS/Traits/Render/WithVoxelBody.cs b/OpenRA.Mods.TS/Traits/Render/WithVoxelBody.cs index 7850ef2ae8..3364d8cca2 100644 --- a/OpenRA.Mods.TS/Traits/Render/WithVoxelBody.cs +++ b/OpenRA.Mods.TS/Traits/Render/WithVoxelBody.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.TS.Traits () => false, () => 0); } - public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return 0; } + public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return 0; } } public class WithVoxelBody : IAutoSelectionSize diff --git a/OpenRA.Mods.TS/Traits/Render/WithVoxelUnloadBody.cs b/OpenRA.Mods.TS/Traits/Render/WithVoxelUnloadBody.cs index e25d8ded06..47239227cd 100644 --- a/OpenRA.Mods.TS/Traits/Render/WithVoxelUnloadBody.cs +++ b/OpenRA.Mods.TS/Traits/Render/WithVoxelUnloadBody.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.TS.Traits () => false, () => 0); } - public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return 0; } + public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return 0; } } public class WithVoxelUnloadBody : IAutoSelectionSize diff --git a/OpenRA.Mods.TS/Traits/Render/WithVoxelWalkerBody.cs b/OpenRA.Mods.TS/Traits/Render/WithVoxelWalkerBody.cs index d4862ffadb..f386512c99 100644 --- a/OpenRA.Mods.TS/Traits/Render/WithVoxelWalkerBody.cs +++ b/OpenRA.Mods.TS/Traits/Render/WithVoxelWalkerBody.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.TS.Traits public readonly int TickRate = 5; public object Create(ActorInitializer init) { return new WithVoxelWalkerBody(init.Self, this); } - public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return 0; } + public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return 0; } } public class WithVoxelWalkerBody : IAutoSelectionSize, ITick