diff --git a/OpenRA.Game/Map/ActorInitializer.cs b/OpenRA.Game/Map/ActorInitializer.cs index 1cb9eb938b..cec08ff113 100644 --- a/OpenRA.Game/Map/ActorInitializer.cs +++ b/OpenRA.Game/Map/ActorInitializer.cs @@ -14,7 +14,15 @@ using OpenRA.Traits; namespace OpenRA { - public class ActorInitializer + public interface IActorInitializer + { + World World { get; } + T Get() where T : IActorInit; + U Get() where T : IActorInit; + bool Contains() where T : IActorInit; + } + + public class ActorInitializer : IActorInitializer { public readonly Actor Self; public World World { get { return Self.World; } } @@ -47,14 +55,6 @@ namespace OpenRA public int Value(World world) { return value; } } - public class TurretFacingInit : IActorInit - { - [FieldFromYamlKey] readonly int value = 128; - public TurretFacingInit() { } - public TurretFacingInit(int init) { value = init; } - public int Value(World world) { return value; } - } - public class LocationInit : IActorInit { [FieldFromYamlKey] readonly CPos value = CPos.Zero; diff --git a/OpenRA.Mods.Common/Graphics/ActorPreview.cs b/OpenRA.Mods.Common/Graphics/ActorPreview.cs index 5a66f84b3e..8891bcf688 100644 --- a/OpenRA.Mods.Common/Graphics/ActorPreview.cs +++ b/OpenRA.Mods.Common/Graphics/ActorPreview.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Graphics IEnumerable Render(WorldRenderer wr, WPos pos); } - public class ActorPreviewInitializer + public class ActorPreviewInitializer : IActorInitializer { public readonly ActorInfo Actor; public readonly WorldRenderer WorldRenderer; diff --git a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs index ec0d35555a..e5089c1f13 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits var ifacing = init.Actor.TraitInfoOrDefault(); var bodyFacing = ifacing != null ? init.Contains() ? init.Get() : ifacing.GetInitialFacing() : 0; - var turretFacing = init.Contains() ? init.Get() : t.InitialFacing; + var turretFacing = Turreted.GetInitialTurretFacing(init, t.InitialFacing, Turret); var anim = new Animation(init.World, image, () => turretFacing); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs index 0424309237..b944bdb5fb 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits var voxel = VoxelProvider.GetVoxel(image, Sequence); - var turretFacing = init.Contains() ? init.Get() : t.InitialFacing; + var turretFacing = Turreted.GetInitialTurretFacing(init, t.InitialFacing, t.Turret); var turretOrientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(turretFacing) - orientation.Yaw), facings); var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation)); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs index 123d9abd79..3dd37e9ec1 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits var voxel = VoxelProvider.GetVoxel(image, Sequence); var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation)); - var turretFacing = init.Contains() ? init.Get() : t.InitialFacing; + var turretFacing = Turreted.GetInitialTurretFacing(init, t.InitialFacing, Turret); var turretBodyOrientation = new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(turretFacing) - orientation.Yaw); var turretOrientation = new[] { turretBodyOrientation, body.QuantizeOrientation(orientation, facings) }; yield return new VoxelAnimation(voxel, () => turretOffset, () => turretOrientation, () => false, () => 0); diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs index a2c6302265..58df1e7e2b 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -47,8 +48,15 @@ namespace OpenRA.Mods.Common.Traits public WVec Offset { get { return info.Offset + localOffset; } } public string Name { get { return info.Turret; } } - public static int GetInitialTurretFacing(ActorInitializer init, int def) + public static int GetInitialTurretFacing(IActorInitializer init, int def, string turret = null) { + if (turret != null && init.Contains()) + { + int facing; + if (init.Get>().TryGetValue(turret, out facing)) + return facing; + } + if (init.Contains()) return init.Get(); @@ -61,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits public Turreted(ActorInitializer init, TurretedInfo info) { this.info = info; - TurretFacing = GetInitialTurretFacing(init, info.InitialFacing); + TurretFacing = GetInitialTurretFacing(init, info.InitialFacing, info.Turret); } public void Created(Actor self) @@ -128,4 +136,21 @@ namespace OpenRA.Mods.Common.Traits return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); } } + + public class TurretFacingInit : IActorInit + { + [FieldFromYamlKey] readonly int value = 128; + public TurretFacingInit() { } + public TurretFacingInit(int init) { value = init; } + public int Value(World world) { return value; } + } + + public class TurretFacingsInit : IActorInit> + { + [DictionaryFromYamlKey] + readonly Dictionary value = new Dictionary(); + public TurretFacingsInit() { } + public TurretFacingsInit(Dictionary init) { value = init; } + public Dictionary Value(World world) { return value; } + } } diff --git a/OpenRA.Mods.RA/Traits/SpawnActorOnDeath.cs b/OpenRA.Mods.RA/Traits/SpawnActorOnDeath.cs index ea97ee0875..24a1b7e8b2 100644 --- a/OpenRA.Mods.RA/Traits/SpawnActorOnDeath.cs +++ b/OpenRA.Mods.RA/Traits/SpawnActorOnDeath.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Warheads; @@ -107,11 +108,14 @@ namespace OpenRA.Mods.RA.Traits if (facing != null) td.Add(new FacingInit(facing.Facing)); - // TODO: This will only take the first turret if there are multiple - // This isn't a problem with the current units, but may be a problem for mods - var turreted = self.TraitsImplementing().FirstOrDefault(); - if (turreted != null) - td.Add(new TurretFacingInit(turreted.TurretFacing)); + var turreted = self.TraitsImplementing(); + if (turreted.Any()) + { + var turretFacings = new Dictionary(); + foreach (var t in turreted) + turretFacings.Add(t.Name, t.TurretFacing); + td.Add(new TurretFacingsInit(turretFacings)); + } // TODO: untie this and move to Mods.Common var chronoshiftable = self.TraitOrDefault();