diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 175f864dd0..a01eafc669 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -322,7 +322,7 @@ namespace OpenRA.Traits WRot Orientation { get; } } - public interface IFacingInfo : ITraitInfoInterface { int GetInitialFacing(); } + public interface IFacingInfo : ITraitInfoInterface { WAngle GetInitialFacing(); } public interface ITraitInfoInterface { } diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index 2e1b2eeacd..4988c55a95 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -175,7 +175,7 @@ namespace OpenRA.Mods.Cnc.Traits { new LocationInit(destination.Value), new OwnerInit(self.Owner), - new FacingInit(info.Facing), + new FacingInit(WAngle.FromFacing(info.Facing)), new FactionInit(faction), new HealthInit((int)(health.HP * 100L / health.MaxHP)) }; diff --git a/OpenRA.Mods.Cnc/Traits/Render/WithCargo.cs b/OpenRA.Mods.Cnc/Traits/Render/WithCargo.cs index 454d7dc15c..775d96a350 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithCargo.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithCargo.cs @@ -85,7 +85,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render var passengerInits = new TypeDictionary() { new OwnerInit(p.Owner), - new DynamicFacingInit(() => body.QuantizeFacing(facing.Facing).Facing), + new DynamicFacingInit(() => body.QuantizeFacing(facing.Facing)), }; foreach (var api in p.TraitsImplementing()) diff --git a/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs b/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs index d9a494dea9..e3ac95c5a5 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.Common; using OpenRA.Mods.Common.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits.Render; @@ -34,9 +35,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render var wsb = init.Actor.TraitInfos().FirstOrDefault(); // Show the correct turret facing - var facing = WAngle.FromFacing(init.GetValue(this, t.InitialFacing)); - - var anim = new Animation(init.World, image, () => facing); + var anim = new Animation(init.World, image, Turreted.TurretFacingFromInit(init, t)); anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), wsb.Sequence)); yield return new SpriteActorPreview(anim, () => WVec.Zero, () => 0, p, rs.Scale); diff --git a/OpenRA.Mods.Cnc/Traits/SupportPowers/DropPodsPower.cs b/OpenRA.Mods.Cnc/Traits/SupportPowers/DropPodsPower.cs index f02baf607f..d8fe3716ab 100644 --- a/OpenRA.Mods.Cnc/Traits/SupportPowers/DropPodsPower.cs +++ b/OpenRA.Mods.Cnc/Traits/SupportPowers/DropPodsPower.cs @@ -91,15 +91,15 @@ namespace OpenRA.Mods.Cnc.Traits { base.Activate(self, order, manager); - SendDropPods(self, order, info.PodFacing); + SendDropPods(self, order, WAngle.FromFacing(info.PodFacing)); } - public void SendDropPods(Actor self, Order order, int podFacing) + public void SendDropPods(Actor self, Order order, WAngle facing) { var actorInfo = self.World.Map.Rules.Actors[info.UnitTypes.First().ToLowerInvariant()]; var aircraftInfo = actorInfo.TraitInfo(); var altitude = aircraftInfo.CruiseAltitude.Length; - var approachRotation = WRot.FromFacing(podFacing); + var approachRotation = WRot.FromYaw(facing); var fallsToEarthInfo = actorInfo.TraitInfo(); var delta = new WVec(0, -altitude * aircraftInfo.Speed / fallsToEarthInfo.Velocity.Length, 0).Rotate(approachRotation); @@ -140,7 +140,7 @@ namespace OpenRA.Mods.Cnc.Traits { new CenterPositionInit(location), new OwnerInit(self.Owner), - new FacingInit(podFacing) + new FacingInit(facing) }); var aircraft = pod.Trait(); diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index 2186967fd2..28de821502 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -31,11 +31,11 @@ namespace OpenRA.Mods.Cnc.Traits public override object Create(ActorInitializer init) { return new TDGunboat(init, this); } - public int GetInitialFacing() { return InitialFacing; } + public WAngle GetInitialFacing() { return WAngle.FromFacing(InitialFacing); } IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { - yield return new FacingInit(PreviewFacing); + yield return new FacingInit(WAngle.FromFacing(PreviewFacing)); } public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) @@ -98,7 +98,7 @@ namespace OpenRA.Mods.Cnc.Traits if (centerPositionInit != null) SetPosition(self, centerPositionInit.Value); - Facing = WAngle.FromFacing(init.GetValue(Info.GetInitialFacing())); + Facing = init.GetValue(Info.GetInitialFacing()); // Prevent mappers from setting bogus facings if (Facing != Left && Facing != Right) @@ -161,7 +161,7 @@ namespace OpenRA.Mods.Cnc.Traits void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { - init.Add(new FacingInit(Facing.Facing)); + init.Add(new FacingInit(Facing)); } public bool CanExistInCell(CPos cell) { return true; } @@ -232,7 +232,7 @@ namespace OpenRA.Mods.Cnc.Traits void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { if (!inits.Contains() && !inits.Contains()) - inits.Add(new DynamicFacingInit(() => Facing.Facing)); + inits.Add(new DynamicFacingInit(() => Facing)); } } } diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportTSMapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportTSMapCommand.cs index b5543cd662..fb79230464 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportTSMapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportTSMapCommand.cs @@ -542,7 +542,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands ar.Add(new HealthInit(100 * health / 256)); if (facing != 96) - ar.Add(new FacingInit(facing)); + ar.Add(new FacingInit(WAngle.FromFacing(facing))); if (isDeployed) ar.Add(new DeployStateInit(DeployState.Deployed)); diff --git a/OpenRA.Mods.Common/Activities/Transform.cs b/OpenRA.Mods.Common/Activities/Transform.cs index 2bfaa1158d..3b6c03270b 100644 --- a/OpenRA.Mods.Common/Activities/Transform.cs +++ b/OpenRA.Mods.Common/Activities/Transform.cs @@ -99,7 +99,7 @@ namespace OpenRA.Mods.Common.Activities { new LocationInit(self.Location + Offset), new OwnerInit(self.Owner), - new FacingInit(Facing.Facing), + new FacingInit(Facing), }; if (SkipMakeAnims) diff --git a/OpenRA.Mods.Common/ActorInitializer.cs b/OpenRA.Mods.Common/ActorInitializer.cs index 5a25349775..0943adb15f 100644 --- a/OpenRA.Mods.Common/ActorInitializer.cs +++ b/OpenRA.Mods.Common/ActorInitializer.cs @@ -16,9 +16,9 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common { - public class FacingInit : ValueActorInit, ISingleInstanceInit + public class FacingInit : ValueActorInit, ISingleInstanceInit { - public FacingInit(int value) + public FacingInit(WAngle value) : base(value) { } } @@ -28,9 +28,9 @@ namespace OpenRA.Mods.Common : base(value) { } } - public class DynamicFacingInit : ValueActorInit>, ISingleInstanceInit + public class DynamicFacingInit : ValueActorInit>, ISingleInstanceInit { - public DynamicFacingInit(Func value) + public DynamicFacingInit(Func value) : base(value) { } } diff --git a/OpenRA.Mods.Common/Graphics/ActorPreview.cs b/OpenRA.Mods.Common/Graphics/ActorPreview.cs index 7555c40bd9..5b24b5cb6a 100644 --- a/OpenRA.Mods.Common/Graphics/ActorPreview.cs +++ b/OpenRA.Mods.Common/Graphics/ActorPreview.cs @@ -74,13 +74,13 @@ namespace OpenRA.Mods.Common.Graphics { // TODO: Account for terrain slope var getFacing = dynamicInit.Value; - return () => WRot.FromFacing(getFacing()); + return () => WRot.FromYaw(getFacing()); } // Fall back to initial actor facing if an Init isn't available var facingInit = reference.GetOrDefault(); var facing = facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing(); - var orientation = WRot.FromFacing(facing); + var orientation = WRot.FromYaw(facing); return () => orientation; } @@ -93,14 +93,11 @@ namespace OpenRA.Mods.Common.Graphics // Dynamic facing takes priority var dynamicInit = reference.GetOrDefault(); if (dynamicInit != null) - { - var getFacing = dynamicInit.Value; - return () => WAngle.FromFacing(getFacing()); - } + return dynamicInit.Value; // Fall back to initial actor facing if an Init isn't available var facingInit = reference.GetOrDefault(); - var facing = WAngle.FromFacing(facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing()); + var facing = facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing(); return () => facing; } diff --git a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs index 5e20a2a71c..924f5e0c34 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs @@ -75,18 +75,17 @@ namespace OpenRA.Mods.Common.Scripting return init; } - // HACK: Forward compatibility for future WAngle facings + // HACK: Backward compatibility for legacy int facings var facingInit = init as FacingInit; if (facingInit != null) { - WAngle angle; - if (value.TryGetClrValue(out angle)) + int facing; + if (value.TryGetClrValue(out facing)) { - facingInit.Initialize(angle.Facing); + facingInit.Initialize(WAngle.FromFacing(facing)); + Game.Debug("Initializing Facing with integers is deprecated. Use Angle instead."); return facingInit; } - - Game.Debug("Initializing Facing with integers is deprecated. Use Angle instead."); } var initializers = initType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs index 9be6bf2f94..f6dc0546d6 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs @@ -55,11 +55,12 @@ namespace OpenRA.Mods.Common.Scripting } if (entryLocation.HasValue && nextLocation.HasValue) - initDict.Add(new FacingInit(Context.World.Map.FacingBetween(CPos.Zero, CPos.Zero + (nextLocation.Value - entryLocation.Value), WAngle.Zero).Facing)); + { + var facing = Context.World.Map.FacingBetween(CPos.Zero, CPos.Zero + (nextLocation.Value - entryLocation.Value), WAngle.Zero); + initDict.Add(new FacingInit(facing)); + } - var actor = Context.World.CreateActor(addToWorld, actorType, initDict); - - return actor; + return Context.World.CreateActor(addToWorld, actorType, initDict); } void Move(Actor actor, CPos dest) diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 64a7cd4c87..d701be1b04 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -160,14 +160,14 @@ namespace OpenRA.Mods.Common.Traits [Desc("Cursor to display when unable to land at target building.")] public readonly string EnterBlockedCursor = "enter-blocked"; - public int GetInitialFacing() { return InitialFacing; } + public WAngle GetInitialFacing() { return WAngle.FromFacing(InitialFacing); } public WDist GetCruiseAltitude() { return CruiseAltitude; } public override object Create(ActorInitializer init) { return new Aircraft(init, this); } IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { - yield return new FacingInit(PreviewFacing); + yield return new FacingInit(WAngle.FromFacing(PreviewFacing)); } public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary(); } @@ -196,13 +196,13 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IEditorActorOptions.ActorOptions(ActorInfo ai, World world) { - yield return new EditorActorSlider("Facing", EditorFacingDisplayOrder, 0, 255, 8, + yield return new EditorActorSlider("Facing", EditorFacingDisplayOrder, 0, 1024, 8, actor => { var init = actor.GetInitOrDefault(this); - return init != null ? init.Value : InitialFacing; + return (init != null ? init.Value : WAngle.FromFacing(InitialFacing)).Angle; }, - (actor, value) => actor.ReplaceInit(new FacingInit((int)value))); + (actor, value) => actor.ReplaceInit(new FacingInit(new WAngle((int)value)))); } } @@ -292,7 +292,7 @@ namespace OpenRA.Mods.Common.Traits if (centerPositionInit != null) SetPosition(self, centerPositionInit.Value); - Facing = WAngle.FromFacing(init.GetValue(Info.InitialFacing)); + Facing = init.GetValue(WAngle.FromFacing(Info.InitialFacing)); creationActivityDelay = init.GetValue(0); } @@ -709,7 +709,7 @@ namespace OpenRA.Mods.Common.Traits public void ModifyDeathActorInit(Actor self, TypeDictionary init) { - init.Add(new FacingInit(Facing.Facing)); + init.Add(new FacingInit(Facing)); } void INotifyBecomingIdle.OnBecomingIdle(Actor self) @@ -1222,7 +1222,7 @@ namespace OpenRA.Mods.Common.Traits void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { if (!inits.Contains() && !inits.Contains()) - inits.Add(new DynamicFacingInit(() => Facing.Facing)); + inits.Add(new DynamicFacingInit(() => Facing)); } Activity ICreationActivity.GetCreationActivity() diff --git a/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs b/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs index f5b258f078..ebcaf43f04 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.Common.Traits new ParentActorInit(self), new LocationInit(self.Location + Info.SpawnOffset), new OwnerInit(self.Owner), - new FacingInit(Info.Facing), + new FacingInit(WAngle.FromFacing(Info.Facing)), }); }); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/FreeActorWithDelivery.cs b/OpenRA.Mods.Common/Traits/Buildings/FreeActorWithDelivery.cs index 922175e5ff..e86a4d698d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/FreeActorWithDelivery.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/FreeActorWithDelivery.cs @@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Traits new LocationInit(location), new CenterPositionInit(spawn), new OwnerInit(self.Owner), - new FacingInit(initialFacing.Facing) + new FacingInit(initialFacing) }); // Create delivered actor diff --git a/OpenRA.Mods.Common/Traits/Buildings/ProductionAirdrop.cs b/OpenRA.Mods.Common/Traits/Buildings/ProductionAirdrop.cs index e03f3a6a74..e78c5f36f1 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/ProductionAirdrop.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/ProductionAirdrop.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits CPos startPos; CPos endPos; - int spawnFacing; + WAngle spawnFacing; if (info.BaselineSpawn && mpStart != null) { @@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Traits startPos = spawn + spawnVec * (Exts.ISqrt((bounds.Height * bounds.Height + bounds.Width * bounds.Width) / (4 * spawnVec.LengthSquared))); endPos = startPos; var spawnDirection = new WVec((self.Location - startPos).X, (self.Location - startPos).Y, 0); - spawnFacing = spawnDirection.Yaw.Facing; + spawnFacing = spawnDirection.Yaw; } else { @@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits var loc = self.Location.ToMPos(map); startPos = new MPos(loc.U + map.Bounds.Width, loc.V).ToCPos(map); endPos = new MPos(map.Bounds.Left, loc.V).ToCPos(map); - spawnFacing = info.Facing; + spawnFacing = WAngle.FromFacing(info.Facing); } // Assume a single exit point for simplicity diff --git a/OpenRA.Mods.Common/Traits/Carryall.cs b/OpenRA.Mods.Common/Traits/Carryall.cs index d4a6462072..44136d901d 100644 --- a/OpenRA.Mods.Common/Traits/Carryall.cs +++ b/OpenRA.Mods.Common/Traits/Carryall.cs @@ -225,7 +225,7 @@ namespace OpenRA.Mods.Common.Traits var carryableInits = new TypeDictionary() { new OwnerInit(Carryable.Owner), - new DynamicFacingInit(() => facing.Facing.Facing), + new DynamicFacingInit(() => facing.Facing), }; foreach (var api in Carryable.TraitsImplementing()) diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index ef4d2f5987..adb20a7637 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -27,12 +27,12 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { - yield return new FacingInit(PreviewFacing); + yield return new FacingInit(WAngle.FromFacing(PreviewFacing)); } public override object Create(ActorInitializer init) { return new Husk(init, this); } - public int GetInitialFacing() { return 128; } + public WAngle GetInitialFacing() { return WAngle.FromFacing(128); } public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { @@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits TopLeft = init.GetValue(); CenterPosition = init.GetValue(init.World.Map.CenterOfCell(TopLeft)); - Facing = WAngle.FromFacing(init.GetValue(128)); + Facing = init.GetValue(info.GetInitialFacing()); dragSpeed = init.GetValue(0); finalPosition = init.World.Map.CenterOfCell(TopLeft); @@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Traits void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { - init.Add(new FacingInit(Facing.Facing)); + init.Add(new FacingInit(Facing)); } // We return self.Owner if there's no effective owner diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index bd7f25b1cc..b1a4ac81b2 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { - yield return new FacingInit(PreviewFacing); + yield return new FacingInit(WAngle.FromFacing(PreviewFacing)); } public override object Create(ActorInitializer init) { return new Mobile(init, this); } @@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Traits base.RulesetLoaded(rules, ai); } - public int GetInitialFacing() { return InitialFacing; } + public WAngle GetInitialFacing() { return WAngle.FromFacing(InitialFacing); } // initialized and used by CanEnterCell Locomotor locomotor; @@ -130,30 +130,13 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IEditorActorOptions.ActorOptions(ActorInfo ai, World world) { - yield return new EditorActorSlider("Facing", EditorFacingDisplayOrder, 0, 255, 8, + yield return new EditorActorSlider("Facing", EditorFacingDisplayOrder, 0, 1023, 8, actor => { var init = actor.GetInitOrDefault(this); - return init != null ? init.Value : InitialFacing; + return (init != null ? init.Value : WAngle.FromFacing(InitialFacing)).Angle; }, - (actor, value) => - { - // TODO: This can all go away once turrets are properly defined as a relative facing - var facingInit = actor.GetInitOrDefault(); - - var oldFacing = facingInit != null ? facingInit.Value : InitialFacing; - var newFacing = (int)value; - - var turretInits = actor.GetInits().ToList(); - actor.RemoveInits(); - foreach (var turretInit in turretInits) - { - var newTurretFacing = (turretInit.Value + newFacing - oldFacing + 255) % 255; - actor.AddInit(new TurretFacingInit(turretInit.InstanceName, newTurretFacing)); - } - - actor.ReplaceInit(new FacingInit(newFacing)); - }); + (actor, value) => actor.ReplaceInit(new FacingInit(new WAngle((int)value)))); } } @@ -282,7 +265,7 @@ namespace OpenRA.Mods.Common.Traits SetVisualPosition(self, init.World.Map.CenterOfSubCell(FromCell, FromSubCell)); } - Facing = oldFacing = WAngle.FromFacing(init.GetValue(info.InitialFacing)); + Facing = oldFacing = init.GetValue(WAngle.FromFacing(info.InitialFacing)); // Sets the initial visual position // Unit will move into the cell grid (defined by LocationInit) as its initial activity @@ -848,12 +831,12 @@ namespace OpenRA.Mods.Common.Traits void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { if (!inits.Contains() && !inits.Contains()) - inits.Add(new DynamicFacingInit(() => Facing.Facing)); + inits.Add(new DynamicFacingInit(() => Facing)); } void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { - init.Add(new FacingInit(Facing.Facing)); + init.Add(new FacingInit(Facing)); // Allows the husk to drag to its final position if (CanEnterCell(self.Location, self, BlockedByActor.Stationary)) diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index 209af80eb3..878776d4f2 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -56,17 +56,17 @@ namespace OpenRA.Mods.Common.Traits var spawn = self.CenterPosition + exitinfo.SpawnOffset; var to = self.World.Map.CenterOfCell(exit); - var initialFacing = exitinfo.Facing; + var initialFacing = WAngle.FromFacing(exitinfo.Facing); if (exitinfo.Facing < 0) { var delta = to - spawn; if (delta.HorizontalLengthSquared == 0) { var fi = producee.TraitInfoOrDefault(); - initialFacing = fi != null ? fi.GetInitialFacing() : 0; + initialFacing = fi != null ? fi.GetInitialFacing() : WAngle.Zero; } else - initialFacing = delta.Yaw.Facing; + initialFacing = delta.Yaw; } exitLocations = rp.Value != null && rp.Value.Path.Count > 0 ? rp.Value.Path : new List { exit }; diff --git a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs index ee6773f7e4..57139b30df 100644 --- a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs +++ b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs @@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits td.Add(new LocationInit(location.Value)); td.Add(new CenterPositionInit(pos)); - td.Add(new FacingInit(initialFacing.Facing)); + td.Add(new FacingInit(initialFacing)); var newUnit = self.World.CreateActor(producee.Name, td); diff --git a/OpenRA.Mods.Common/Traits/ProductionParadrop.cs b/OpenRA.Mods.Common/Traits/ProductionParadrop.cs index 3d073ca749..c381072fa9 100644 --- a/OpenRA.Mods.Common/Traits/ProductionParadrop.cs +++ b/OpenRA.Mods.Common/Traits/ProductionParadrop.cs @@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Traits { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)), new OwnerInit(owner), - new FacingInit(64) + new FacingInit(new WAngle(256)), }); actor.QueueActivity(new Fly(actor, Target.FromCell(w, dropPos))); @@ -124,7 +124,7 @@ namespace OpenRA.Mods.Common.Traits var spawn = self.World.Map.CenterOfCell(exit) + new WVec(WDist.Zero, WDist.Zero, altitude); var to = self.World.Map.CenterOfCell(exit); - var initialFacing = exitinfo == null || exitinfo.Facing < 0 ? (to - spawn).Yaw.Facing : exitinfo.Facing; + var initialFacing = exitinfo == null || exitinfo.Facing < 0 ? (to - spawn).Yaw : WAngle.FromFacing(exitinfo.Facing); exitLocations = rp.Value != null && rp.Value.Path.Count > 0 ? rp.Value.Path : new List { exit }; diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index b7a7956ab9..67210ba481 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -51,13 +51,10 @@ namespace OpenRA.Mods.Common.Traits.Render Func facing; var dynamicfacingInit = init.GetOrDefault(); if (dynamicfacingInit != null) - { - var getFacing = dynamicfacingInit.Value; - facing = () => WAngle.FromFacing(getFacing()); - } + facing = dynamicfacingInit.Value; else { - var f = WAngle.FromFacing(init.GetValue(0)); + var f = init.GetValue(WAngle.Zero); facing = () => f; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs index f52913fb86..c76d9edc84 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs @@ -77,13 +77,13 @@ namespace OpenRA.Mods.Common.Traits.Render if (Palette != null) p = init.WorldRenderer.Palette(Palette); - Func facing; + Func facing; var dynamicfacingInit = init.GetOrDefault(); if (dynamicfacingInit != null) facing = dynamicfacingInit.Value; else { - var f = init.GetValue(0); + var f = init.GetValue(WAngle.Zero); facing = () => f; } @@ -91,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits.Render anim.PlayThen(OpeningSequence, () => anim.PlayRepeating(Sequence)); var body = init.Actor.TraitInfo(); - Func orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings); + Func orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings); Func offset = () => body.LocalToWorld(Offset.Rotate(orientation())); Func zOffset = () => { diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs index 3b3b86eb0f..4bc282d7e1 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs @@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits.Render .First(tt => tt.Turret == armament.Turret); var turretFacing = Turreted.TurretFacingFromInit(init, t); - var anim = new Animation(init.World, image, () => WAngle.FromFacing(turretFacing())); + var anim = new Animation(init.World, image, turretFacing); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); var facing = init.GetFacing(); diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs index 1bc1371419..25112f1c38 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits.Render .First(tt => tt.Turret == Turret); var turretFacing = Turreted.TurretFacingFromInit(init, t); - var anim = new Animation(init.World, image, () => WAngle.FromFacing(turretFacing())); + var anim = new Animation(init.World, image, turretFacing); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); var facing = init.GetFacing(); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs index 91002af780..187db92b95 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs @@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits.Render var model = init.World.ModelCache.GetModelSequence(image, Sequence); var turretFacing = Turreted.TurretFacingFromInit(init, t); - Func turretOrientation = () => body.QuantizeOrientation(WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw), facings); + Func turretOrientation = () => body.QuantizeOrientation(WRot.FromYaw(turretFacing() - orientation().Yaw), facings); Func quantizedTurret = () => body.QuantizeOrientation(turretOrientation(), facings); Func quantizedBody = () => body.QuantizeOrientation(orientation(), facings); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs index 1623a0bdf0..6e5678d0e5 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits.Render Func turretOffset = () => body.LocalToWorld(t.Offset.Rotate(orientation())); var turretFacing = Turreted.TurretFacingFromInit(init, t); - Func turretBodyOrientation = () => WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw); + Func turretBodyOrientation = () => WRot.FromYaw(turretFacing() - orientation().Yaw); yield return new ModelAnimation(model, turretOffset, () => new[] { turretBodyOrientation(), body.QuantizeOrientation(orientation(), facings) }, () => false, () => 0, ShowShadow); } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs index e29252ce2c..9076124973 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs @@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Traits { new CenterPositionInit(startEdge + spawnOffset), new OwnerInit(self.Owner), - new FacingInit(facing.Value.Facing), + new FacingInit(facing.Value), }); aircraft.Add(a); diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs index 36b3216658..12e01b5160 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/ParatroopersPower.cs @@ -185,7 +185,7 @@ namespace OpenRA.Mods.Common.Traits { new CenterPositionInit(startEdge + spawnOffset), new OwnerInit(self.Owner), - new FacingInit(facing.Value.Facing), + new FacingInit(facing.Value), })); } diff --git a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs index 38814c98bc..f8f2db1405 100644 --- a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs +++ b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs @@ -57,6 +57,7 @@ namespace OpenRA.Mods.Common.Traits WAngle facing; WAngle rotation; + int direction; public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info) { @@ -66,20 +67,22 @@ namespace OpenRA.Mods.Common.Traits // TODO: Carry orientation over from the parent instead of just facing var dynamicFacingInit = init.GetOrDefault(); - var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue(0); - facing = WAngle.FromFacing(Turreted.TurretFacingFromInit(init, info, 0)()); + var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue(WAngle.Zero); + facing = Turreted.TurretFacingFromInit(init, info, WAngle.Zero)(); // Calculate final position - var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); + var throwRotation = WRot.FromYaw(new WAngle(Game.CosmeticRandom.Next(1024))); var throwDistance = Game.CosmeticRandom.Next(info.MinThrowRange.Length, info.MaxThrowRange.Length); - initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); + initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromYaw(bodyFacing))); finalPos = initialPos + new WVec(throwDistance, 0, 0).Rotate(throwRotation); angle = new WAngle(Game.CosmeticRandom.Next(info.MinThrowAngle.Angle, info.MaxThrowAngle.Angle)); length = (finalPos - initialPos).Length / info.Velocity; - // Facing rotation - rotation = WAngle.FromFacing(WDist.FromPDF(Game.CosmeticRandom, 2).Length * info.TurnSpeed / 1024); + // WAngle requires positive inputs, so track the speed and direction separately + var rotationSpeed = WDist.FromPDF(Game.CosmeticRandom, 2).Length * info.TurnSpeed / 1024; + direction = rotationSpeed < 0 ? -1 : 1; + rotation = WAngle.FromFacing(Math.Abs(rotationSpeed)); var anim = new Animation(init.World, rs.GetImage(self), () => facing); anim.PlayRepeating(info.Anim); @@ -94,7 +97,7 @@ namespace OpenRA.Mods.Common.Traits pos = WVec.LerpQuadratic(initialPos, finalPos, angle, tick++, length); // Spin the particle - facing += rotation; + facing += new WAngle(direction * rotation.Angle); rotation = new WAngle(rotation.Angle * 90 / 100); } } diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs index d26281ac2c..58f4ff9243 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -30,33 +30,26 @@ namespace OpenRA.Mods.Common.Traits [Desc("Muzzle position relative to turret or body. (forward, right, up) triples")] public readonly WVec Offset = WVec.Zero; - [Desc("Facing to use for actor previews (map editor, color picker, etc)")] - public readonly int PreviewFacing = 96; - [Desc("Display order for the turret facing slider in the map editor")] public readonly int EditorTurretFacingDisplayOrder = 4; IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { - yield return new TurretFacingInit(this, PreviewFacing); + yield return new TurretFacingInit(this, WAngle.FromFacing(InitialFacing)); } IEnumerable IEditorActorOptions.ActorOptions(ActorInfo ai, World world) { - yield return new EditorActorSlider("Turret", EditorTurretFacingDisplayOrder, 0, 255, 8, + yield return new EditorActorSlider("Turret", EditorTurretFacingDisplayOrder, 0, 1023, 8, actor => { var init = actor.GetInitOrDefault(this); if (init != null) - return init.Value; + return init.Value.Angle; - var facingInit = actor.GetInitOrDefault(this); - if (facingInit != null) - return facingInit.Value; - - return InitialFacing; + return WAngle.FromFacing(InitialFacing).Angle; }, - (actor, value) => actor.ReplaceInit(new TurretFacingInit(this, (int)value), this)); + (actor, value) => actor.ReplaceInit(new TurretFacingInit(this, new WAngle((int)value)), this)); } public override object Create(ActorInitializer init) { return new Turreted(init, this); } @@ -83,38 +76,41 @@ namespace OpenRA.Mods.Common.Traits public WVec Offset { get { return Info.Offset + localOffset; } } public string Name { get { return Info.Turret; } } - public static Func TurretFacingFromInit(IActorInitializer init, TurretedInfo info) + public static Func TurretFacingFromInit(IActorInitializer init, TurretedInfo info) { - return TurretFacingFromInit(init, info, info.InitialFacing); + return TurretFacingFromInit(init, info, WAngle.FromFacing(info.InitialFacing)); } - public static Func TurretFacingFromInit(IActorInitializer init, TraitInfo info, int defaultFacing) + public static Func TurretFacingFromInit(IActorInitializer init, TraitInfo info, WAngle defaultFacing) { - var turretFacingInit = init.GetOrDefault(info); - if (turretFacingInit != null) - { - var facing = turretFacingInit.Value; - return () => facing; - } - - var dynamicFacingInit = init.GetOrDefault(); - if (dynamicFacingInit != null) - return dynamicFacingInit.Value; - + // (Dynamic)TurretFacingInit is specified relative to the actor body. + // We need to add the body facing to return an absolute world angle. + Func bodyFacing = null; var facingInit = init.GetOrDefault(); if (facingInit != null) { var facing = facingInit.Value; - return () => facing; + bodyFacing = () => facing; } - return () => defaultFacing; + var turretFacingInit = init.GetOrDefault(info); + if (turretFacingInit != null) + { + var facing = turretFacingInit.Value; + return bodyFacing != null ? (Func)(() => bodyFacing() + facing) : () => facing; + } + + var dynamicFacingInit = init.GetOrDefault(); + if (dynamicFacingInit != null) + return bodyFacing != null ? () => bodyFacing() + dynamicFacingInit.Value() : dynamicFacingInit.Value; + + return bodyFacing ?? (Func)(() => defaultFacing); } public Turreted(ActorInitializer init, TurretedInfo info) : base(info) { - TurretFacing = TurretFacingFromInit(init, Info)(); + TurretFacing = TurretFacingFromInit(init, Info)().Facing; } protected override void Created(Actor self) @@ -203,12 +199,16 @@ namespace OpenRA.Mods.Common.Traits public void ModifyDeathActorInit(Actor self, TypeDictionary init) { - init.Add(new TurretFacingInit(Info, TurretFacing)); + var turretFacing = WAngle.FromFacing(TurretFacing); + if (facing != null) + turretFacing -= facing.Facing; + + init.Add(new TurretFacingInit(Info, turretFacing)); } void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { - Func bodyFacing = () => facing.Facing.Facing; + Func bodyFacing = () => facing.Facing; var dynamicFacing = inits.GetOrDefault(); var staticFacing = inits.GetOrDefault(); if (dynamicFacing != null) @@ -217,7 +217,7 @@ namespace OpenRA.Mods.Common.Traits bodyFacing = () => staticFacing.Value; // Freeze the relative turret facing to its current value - var facingOffset = TurretFacing - bodyFacing(); + var facingOffset = WAngle.FromFacing(TurretFacing) - bodyFacing(); inits.Add(new DynamicTurretFacingInit(Info, () => bodyFacing() + facingOffset)); } @@ -228,21 +228,21 @@ namespace OpenRA.Mods.Common.Traits } } - public class TurretFacingInit : ValueActorInit + public class TurretFacingInit : ValueActorInit { - public TurretFacingInit(TraitInfo info, int value) + public TurretFacingInit(TraitInfo info, WAngle value) : base(info, value) { } - public TurretFacingInit(string instanceName, int value) + public TurretFacingInit(string instanceName, WAngle value) : base(instanceName, value) { } - public TurretFacingInit(int value) + public TurretFacingInit(WAngle value) : base(value) { } } - public class DynamicTurretFacingInit : ValueActorInit> + public class DynamicTurretFacingInit : ValueActorInit> { - public DynamicTurretFacingInit(TraitInfo info, Func value) + public DynamicTurretFacingInit(TraitInfo info, Func value) : base(info, value) { } } } diff --git a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs index d991c1d180..293be25084 100644 --- a/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs +++ b/OpenRA.Mods.Common/Traits/World/CrateSpawner.cs @@ -141,8 +141,8 @@ namespace OpenRA.Mods.Common.Traits if (info.DeliveryAircraft != null) { var crate = w.CreateActor(false, crateActor, new TypeDictionary { new OwnerInit(w.WorldActor.Owner) }); - var dropFacing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings; - var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(dropFacing)); + var dropFacing = WAngle.FromFacing(256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings); + var delta = new WVec(0, -1024, 0).Rotate(WRot.FromYaw(dropFacing)); var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo().CruiseAltitude.Length; var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude); diff --git a/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs index 0078e7b7e4..9b113fdce1 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs @@ -194,10 +194,7 @@ namespace OpenRA.Mods.Common.Traits } if (actor.HasTraitInfo()) - reference.Add(new FacingInit(info.PreviewFacing)); - - if (actor.HasTraitInfo()) - reference.Add(new TurretFacingInit(info.PreviewFacing)); + reference.Add(new FacingInit(WAngle.FromFacing(info.PreviewFacing))); Type = EditorCursorType.Actor; Actor = new EditorActorPreview(wr, null, reference, owner); diff --git a/OpenRA.Mods.Common/Traits/World/SpawnMPUnits.cs b/OpenRA.Mods.Common/Traits/World/SpawnMPUnits.cs index 950c8d7bcb..ad31efeeac 100644 --- a/OpenRA.Mods.Common/Traits/World/SpawnMPUnits.cs +++ b/OpenRA.Mods.Common/Traits/World/SpawnMPUnits.cs @@ -85,12 +85,13 @@ namespace OpenRA.Mods.Common.Traits if (unitGroup.BaseActor != null) { + var facing = unitGroup.BaseActorFacing < 0 ? new WAngle(w.SharedRandom.Next(1024)) : WAngle.FromFacing(unitGroup.BaseActorFacing); w.CreateActor(unitGroup.BaseActor.ToLowerInvariant(), new TypeDictionary { new LocationInit(sp + unitGroup.BaseActorOffset), new OwnerInit(p), new SkipMakeAnimsInit(), - new FacingInit(unitGroup.BaseActorFacing < 0 ? w.SharedRandom.Next(256) : unitGroup.BaseActorFacing), + new FacingInit(facing), }); } @@ -112,13 +113,14 @@ namespace OpenRA.Mods.Common.Traits } var subCell = ip.SharesCell ? w.ActorMap.FreeSubCell(validCell) : 0; + var facing = unitGroup.SupportActorsFacing < 0 ? new WAngle(w.SharedRandom.Next(1024)) : WAngle.FromFacing(unitGroup.SupportActorsFacing); w.CreateActor(s.ToLowerInvariant(), new TypeDictionary { new OwnerInit(p), new LocationInit(validCell), new SubCellInit(subCell), - new FacingInit(unitGroup.SupportActorsFacing < 0 ? w.SharedRandom.Next(256) : unitGroup.SupportActorsFacing) + new FacingInit(facing), }); } } diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index b9338a847d..513e2ae1ad 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -413,7 +413,7 @@ namespace OpenRA.Mods.Common.UtilityCommands if (health != 100) actor.Add(new HealthInit(health)); if (facing != 0) - actor.Add(new FacingInit(255 - facing)); + actor.Add(new FacingInit(new WAngle(1024 - 4 * facing))); if (section == "INFANTRY") actor.Add(new SubCellInit((SubCell)Exts.ParseByte(parts[4])));