Convert (Dynamic)FacingInit, (Dynamic)TurretFacingInit to WAngle.

This commit is contained in:
Paul Chote
2020-06-26 00:33:08 +01:00
committed by abcdefg30
parent e8f443f4a9
commit a2269e7ee7
36 changed files with 133 additions and 155 deletions

View File

@@ -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 { }

View File

@@ -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))
};

View File

@@ -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<IActorPreviewInitModifier>())

View File

@@ -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<WithSpriteBodyInfo>().FirstOrDefault();
// Show the correct turret facing
var facing = WAngle.FromFacing(init.GetValue<TurretFacingInit, int>(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);

View File

@@ -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<AircraftInfo>();
var altitude = aircraftInfo.CruiseAltitude.Length;
var approachRotation = WRot.FromFacing(podFacing);
var approachRotation = WRot.FromYaw(facing);
var fallsToEarthInfo = actorInfo.TraitInfo<FallsToEarthInfo>();
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<Aircraft>();

View File

@@ -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<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)
{
yield return new FacingInit(PreviewFacing);
yield return new FacingInit(WAngle.FromFacing(PreviewFacing));
}
public IReadOnlyDictionary<CPos, SubCell> 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<FacingInit, int>(Info.GetInitialFacing()));
Facing = init.GetValue<FacingInit, WAngle>(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<DynamicFacingInit>() && !inits.Contains<FacingInit>())
inits.Add(new DynamicFacingInit(() => Facing.Facing));
inits.Add(new DynamicFacingInit(() => Facing));
}
}
}

View File

@@ -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));

View File

@@ -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)

View File

@@ -16,9 +16,9 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common
{
public class FacingInit : ValueActorInit<int>, ISingleInstanceInit
public class FacingInit : ValueActorInit<WAngle>, 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<Func<int>>, ISingleInstanceInit
public class DynamicFacingInit : ValueActorInit<Func<WAngle>>, ISingleInstanceInit
{
public DynamicFacingInit(Func<int> value)
public DynamicFacingInit(Func<WAngle> value)
: base(value) { }
}

View File

@@ -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<FacingInit>();
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<DynamicFacingInit>();
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<FacingInit>();
var facing = WAngle.FromFacing(facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing());
var facing = facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing();
return () => facing;
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)
{
yield return new FacingInit(PreviewFacing);
yield return new FacingInit(WAngle.FromFacing(PreviewFacing));
}
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
@@ -196,13 +196,13 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<EditorActorOption> 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<FacingInit>(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<FacingInit, int>(Info.InitialFacing));
Facing = init.GetValue<FacingInit, WAngle>(WAngle.FromFacing(Info.InitialFacing));
creationActivityDelay = init.GetValue<CreationActivityDelayInit, int>(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<DynamicFacingInit>() && !inits.Contains<FacingInit>())
inits.Add(new DynamicFacingInit(() => Facing.Facing));
inits.Add(new DynamicFacingInit(() => Facing));
}
Activity ICreationActivity.GetCreationActivity()

View File

@@ -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)),
});
});
}

View File

@@ -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

View File

@@ -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

View File

@@ -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<IActorPreviewInitModifier>())

View File

@@ -27,12 +27,12 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<ActorInit> 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<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any)
{
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
TopLeft = init.GetValue<LocationInit, CPos>();
CenterPosition = init.GetValue<CenterPositionInit, WPos>(init.World.Map.CenterOfCell(TopLeft));
Facing = WAngle.FromFacing(init.GetValue<FacingInit, int>(128));
Facing = init.GetValue<FacingInit, WAngle>(info.GetInitialFacing());
dragSpeed = init.GetValue<HuskSpeedInit, int>(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

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<ActorInit> 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<EditorActorOption> 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<FacingInit>(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<FacingInit>();
var oldFacing = facingInit != null ? facingInit.Value : InitialFacing;
var newFacing = (int)value;
var turretInits = actor.GetInits<TurretFacingInit>().ToList();
actor.RemoveInits<TurretFacingInit>();
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<FacingInit, int>(info.InitialFacing));
Facing = oldFacing = init.GetValue<FacingInit, WAngle>(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<DynamicFacingInit>() && !inits.Contains<FacingInit>())
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))

View File

@@ -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<IFacingInfo>();
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<CPos> { exit };

View File

@@ -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);

View File

@@ -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<CPos> { exit };

View File

@@ -51,13 +51,10 @@ namespace OpenRA.Mods.Common.Traits.Render
Func<WAngle> facing;
var dynamicfacingInit = init.GetOrDefault<DynamicFacingInit>();
if (dynamicfacingInit != null)
{
var getFacing = dynamicfacingInit.Value;
facing = () => WAngle.FromFacing(getFacing());
}
facing = dynamicfacingInit.Value;
else
{
var f = WAngle.FromFacing(init.GetValue<FacingInit, int>(0));
var f = init.GetValue<FacingInit, WAngle>(WAngle.Zero);
facing = () => f;
}

View File

@@ -77,13 +77,13 @@ namespace OpenRA.Mods.Common.Traits.Render
if (Palette != null)
p = init.WorldRenderer.Palette(Palette);
Func<int> facing;
Func<WAngle> facing;
var dynamicfacingInit = init.GetOrDefault<DynamicFacingInit>();
if (dynamicfacingInit != null)
facing = dynamicfacingInit.Value;
else
{
var f = init.GetValue<FacingInit, int>(0);
var f = init.GetValue<FacingInit, WAngle>(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<BodyOrientationInfo>();
Func<WRot> orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings);
Func<WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings);
Func<WVec> offset = () => body.LocalToWorld(Offset.Rotate(orientation()));
Func<int> zOffset = () =>
{

View File

@@ -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();

View File

@@ -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();

View File

@@ -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<WRot> turretOrientation = () => body.QuantizeOrientation(WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw), facings);
Func<WRot> turretOrientation = () => body.QuantizeOrientation(WRot.FromYaw(turretFacing() - orientation().Yaw), facings);
Func<WRot> quantizedTurret = () => body.QuantizeOrientation(turretOrientation(), facings);
Func<WRot> quantizedBody = () => body.QuantizeOrientation(orientation(), facings);

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits.Render
Func<WVec> turretOffset = () => body.LocalToWorld(t.Offset.Rotate(orientation()));
var turretFacing = Turreted.TurretFacingFromInit(init, t);
Func<WRot> turretBodyOrientation = () => WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw);
Func<WRot> turretBodyOrientation = () => WRot.FromYaw(turretFacing() - orientation().Yaw);
yield return new ModelAnimation(model, turretOffset,
() => new[] { turretBodyOrientation(), body.QuantizeOrientation(orientation(), facings) }, () => false, () => 0, ShowShadow);
}

View File

@@ -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);

View File

@@ -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),
}));
}

View File

@@ -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<DynamicFacingInit>();
var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue<FacingInit, int>(0);
facing = WAngle.FromFacing(Turreted.TurretFacingFromInit(init, info, 0)());
var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue<FacingInit, WAngle>(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);
}
}

View File

@@ -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<ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type)
{
yield return new TurretFacingInit(this, PreviewFacing);
yield return new TurretFacingInit(this, WAngle.FromFacing(InitialFacing));
}
IEnumerable<EditorActorOption> 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<TurretFacingInit>(this);
if (init != null)
return init.Value;
return init.Value.Angle;
var facingInit = actor.GetInitOrDefault<FacingInit>(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<int> TurretFacingFromInit(IActorInitializer init, TurretedInfo info)
public static Func<WAngle> TurretFacingFromInit(IActorInitializer init, TurretedInfo info)
{
return TurretFacingFromInit(init, info, info.InitialFacing);
return TurretFacingFromInit(init, info, WAngle.FromFacing(info.InitialFacing));
}
public static Func<int> TurretFacingFromInit(IActorInitializer init, TraitInfo info, int defaultFacing)
public static Func<WAngle> TurretFacingFromInit(IActorInitializer init, TraitInfo info, WAngle defaultFacing)
{
var turretFacingInit = init.GetOrDefault<TurretFacingInit>(info);
if (turretFacingInit != null)
{
var facing = turretFacingInit.Value;
return () => facing;
}
var dynamicFacingInit = init.GetOrDefault<DynamicFacingInit>();
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<WAngle> bodyFacing = null;
var facingInit = init.GetOrDefault<FacingInit>();
if (facingInit != null)
{
var facing = facingInit.Value;
return () => facing;
bodyFacing = () => facing;
}
return () => defaultFacing;
var turretFacingInit = init.GetOrDefault<TurretFacingInit>(info);
if (turretFacingInit != null)
{
var facing = turretFacingInit.Value;
return bodyFacing != null ? (Func<WAngle>)(() => bodyFacing() + facing) : () => facing;
}
var dynamicFacingInit = init.GetOrDefault<DynamicFacingInit>();
if (dynamicFacingInit != null)
return bodyFacing != null ? () => bodyFacing() + dynamicFacingInit.Value() : dynamicFacingInit.Value;
return bodyFacing ?? (Func<WAngle>)(() => 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<int> bodyFacing = () => facing.Facing.Facing;
Func<WAngle> bodyFacing = () => facing.Facing;
var dynamicFacing = inits.GetOrDefault<DynamicFacingInit>();
var staticFacing = inits.GetOrDefault<FacingInit>();
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<int>
public class TurretFacingInit : ValueActorInit<WAngle>
{
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<Func<int>>
public class DynamicTurretFacingInit : ValueActorInit<Func<WAngle>>
{
public DynamicTurretFacingInit(TraitInfo info, Func<int> value)
public DynamicTurretFacingInit(TraitInfo info, Func<WAngle> value)
: base(info, value) { }
}
}

View File

@@ -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<AircraftInfo>().CruiseAltitude.Length;
var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude);

View File

@@ -194,10 +194,7 @@ namespace OpenRA.Mods.Common.Traits
}
if (actor.HasTraitInfo<IFacingInfo>())
reference.Add(new FacingInit(info.PreviewFacing));
if (actor.HasTraitInfo<TurretedInfo>())
reference.Add(new TurretFacingInit(info.PreviewFacing));
reference.Add(new FacingInit(WAngle.FromFacing(info.PreviewFacing)));
Type = EditorCursorType.Actor;
Actor = new EditorActorPreview(wr, null, reference, owner);

View File

@@ -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),
});
}
}

View File

@@ -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])));