diff --git a/OpenRA.Editor/RenderUtils.cs b/OpenRA.Editor/RenderUtils.cs index 6b29709bfc..01d8fd2f0f 100644 --- a/OpenRA.Editor/RenderUtils.cs +++ b/OpenRA.Editor/RenderUtils.cs @@ -45,7 +45,7 @@ namespace OpenRA.Editor public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, Palette p) { - var image = RenderSimple.GetImage(info); + var image = RenderSprites.GetImage(info); using (var s = FileSystem.OpenWithExts(image, tileset.Extensions)) { diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index d8e247431f..b2e84114ce 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -41,7 +41,6 @@ namespace OpenRA.Graphics IRenderable WithZOffset(int newOffset); IRenderable WithPos(WPos pos); void Render(WorldRenderer wr); - WVec Size(WorldRenderer wr); } public struct SpriteRenderable : IRenderable @@ -84,11 +83,5 @@ namespace OpenRA.Graphics { sprite.DrawAt(wr.ScreenPxPosition(pos) - pxCenter, palette.Index, scale); } - - public WVec Size(WorldRenderer wr) - { - var size = (scale*sprite.size).ToInt2(); - return new WVec(size.X, size.Y, size.Y); - } } } diff --git a/OpenRA.Game/Graphics/Sequence.cs b/OpenRA.Game/Graphics/Sequence.cs index c4ce07357c..22cf781893 100644 --- a/OpenRA.Game/Graphics/Sequence.cs +++ b/OpenRA.Game/Graphics/Sequence.cs @@ -19,6 +19,7 @@ namespace OpenRA.Graphics { readonly Sprite[] sprites; readonly int start, length, stride, facings, tick; + readonly bool reverseFacings, transpose; public readonly string Name; public int Start { get { return start; } } @@ -49,16 +50,23 @@ namespace OpenRA.Graphics else stride = length; - if(d.ContainsKey("Facings")) - facings = int.Parse(d["Facings"].Value); + if (d.ContainsKey("Facings")) + { + var f = int.Parse(d["Facings"].Value); + facings = Math.Abs(f); + reverseFacings = f < 0; + } else facings = 1; - if(d.ContainsKey("Tick")) + if (d.ContainsKey("Tick")) tick = int.Parse(d["Tick"].Value); else tick = 40; + if (d.ContainsKey("Transpose")) + transpose = bool.Parse(d["Transpose"].Value); + if (length > stride) throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= stride" @@ -71,15 +79,22 @@ namespace OpenRA.Graphics info.Nodes[0].Location)); } - public Sprite GetSprite( int frame ) + public Sprite GetSprite(int frame) { - return GetSprite( frame, 0 ); + return GetSprite(frame, 0); } public Sprite GetSprite(int frame, int facing) { - var f = Traits.Util.QuantizeFacing( facing, facings ); - return sprites[ (f * stride) + ( frame % length ) + start ]; + var f = Traits.Util.QuantizeFacing(facing, facings); + + if (reverseFacings) + f = (facings - f) % facings; + + int i = transpose ? (frame % length) * facings + f : + (f * stride) + (frame % length); + + return sprites[start + i]; } } } diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 29cf8054bf..ce040adc49 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -225,6 +225,8 @@ + + diff --git a/OpenRA.Game/Traits/BodyOrientation.cs b/OpenRA.Game/Traits/BodyOrientation.cs new file mode 100755 index 0000000000..653030a6da --- /dev/null +++ b/OpenRA.Game/Traits/BodyOrientation.cs @@ -0,0 +1,58 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Graphics; +using OpenRA.FileFormats; + +namespace OpenRA.Traits +{ + public class BodyOrientationInfo : ITraitInfo, IBodyOrientationInfo + { + [Desc("Camera pitch for rotation calculations")] + public readonly WAngle CameraPitch = WAngle.FromDegrees(40); + public object Create(ActorInitializer init) { return new BodyOrientation(init.self, this); } + } + + public class BodyOrientation : IBodyOrientation + { + [Sync] public int QuantizedFacings { get; set; } + BodyOrientationInfo Info; + + public BodyOrientation(Actor self, BodyOrientationInfo info) + { + Info = info; + } + + public WAngle CameraPitch { get { return Info.CameraPitch; } } + + public WVec LocalToWorld(WVec vec) + { + // RA's 2d perspective doesn't correspond to an orthonormal 3D + // coordinate system, so fudge the y axis to make things look good + return new WVec(vec.Y, -Info.CameraPitch.Sin()*vec.X/1024, vec.Z); + } + + public WRot QuantizeOrientation(Actor self, WRot orientation) + { + // Quantization disabled + if (QuantizedFacings == 0) + return orientation; + + // Map yaw to the closest facing + var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings); + + // Roll and pitch are always zero if yaw is quantized + return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); + } + } +} diff --git a/OpenRA.Game/Traits/Render/RenderSimple.cs b/OpenRA.Game/Traits/Render/RenderSimple.cs index f26e73ea2a..36716979b1 100755 --- a/OpenRA.Game/Traits/Render/RenderSimple.cs +++ b/OpenRA.Game/Traits/Render/RenderSimple.cs @@ -16,23 +16,9 @@ using OpenRA.FileFormats; namespace OpenRA.Traits { - public class RenderSimpleInfo : ITraitInfo, LocalCoordinatesModelInfo + public class RenderSimpleInfo : RenderSpritesInfo, Requires { - [Desc("Defaults to the actor name.")] - public readonly string Image = null; - [Desc("custom palette name")] - public readonly string Palette = null; - [Desc("custom PlayerColorPalette: BaseName")] - public readonly string PlayerPalette = "player"; - [Desc("Change the sprite image size.")] - public readonly float Scale = 1f; - - [Desc("Number of facings for gameplay calculations. -1 indiciates auto-detection from sequence")] - public readonly int QuantizedFacings = -1; - - [Desc("Camera pitch the sprite was rendered with. Used to determine rotation ellipses")] - public readonly WAngle CameraPitch = WAngle.FromDegrees(40); - public virtual object Create(ActorInitializer init) { return new RenderSimple(init.self); } + public override object Create(ActorInitializer init) { return new RenderSimple(init.self); } public virtual IEnumerable RenderPreview(ActorInfo ai, PaletteReference pr) { @@ -43,73 +29,22 @@ namespace OpenRA.Traits } } - public class RenderSimple : IRender, ILocalCoordinatesModel, IAutoSelectionSize, ITick, INotifyOwnerChanged + public class RenderSimple : RenderSprites, IAutoSelectionSize { - public Dictionary anims = new Dictionary(); - - public static Func MakeFacingFunc(Actor self) - { - var facing = self.TraitOrDefault(); - if (facing == null) return () => 0; - return () => facing.Facing; - } - - public Animation anim - { - get { return anims[""].Animation; } - protected set { anims[""] = new AnimationWithOffset(value, - anims[""].OffsetFunc, anims[""].DisableFunc, anims[""].ZOffset); } - } - - public static string GetImage(ActorInfo actor) - { - var Info = actor.Traits.Get(); - return Info.Image ?? actor.Name; - } - - public string GetImage(Actor self) - { - if (cachedImage != null) - return cachedImage; - - return cachedImage = GetImage(self.Info); - } - RenderSimpleInfo Info; - string cachedImage = null; - bool initializePalette = true; - protected PaletteReference palette; public RenderSimple(Actor self, Func baseFacing) + : base(self, baseFacing) { anims.Add("", new Animation(GetImage(self), baseFacing)); Info = self.Info.Traits.Get(); } - public RenderSimple(Actor self) : this( self, MakeFacingFunc(self) ) + public RenderSimple(Actor self) + : this(self, MakeFacingFunc(self)) { anim.PlayRepeating("idle"); - } - - protected virtual string PaletteName(Actor self) - { - return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName; - } - - protected void UpdatePalette() { initializePalette = true; } - public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); } - - public virtual IEnumerable Render(Actor self, WorldRenderer wr) - { - if (initializePalette) - { - palette = wr.Palette(PaletteName(self)); - initializePalette = false; - } - - foreach (var a in anims.Values) - if (a.DisableFunc == null || !a.DisableFunc()) - yield return a.Image(self, wr, palette, Info.Scale); + self.Trait().QuantizedFacings = anim.CurrentSequence.Facings; } public int2 SelectionSize(Actor self) @@ -120,12 +55,6 @@ namespace OpenRA.Traits .FirstOrDefault(); } - public virtual void Tick(Actor self) - { - foreach (var a in anims.Values) - a.Animation.Tick(); - } - protected virtual string NormalizeSequence(Actor self, string baseSequence) { string damageState = self.GetDamageState() >= DamageState.Heavy ? "damaged-" : ""; @@ -141,22 +70,5 @@ namespace OpenRA.Traits anim.PlayThen(NormalizeSequence(self, name), () => anim.PlayRepeating(NormalizeSequence(self, "idle"))); } - - public WVec LocalToWorld(WVec vec) - { - // RA's 2d perspective doesn't correspond to an orthonormal 3D - // coordinate system, so fudge the y axis to make things look good - return new WVec(vec.Y, -Info.CameraPitch.Sin()*vec.X/1024, vec.Z); - } - - public WRot QuantizeOrientation(Actor self, WRot orientation) - { - // Map yaw to the closest facing - var numDirs = Info.QuantizedFacings == -1 ? anim.CurrentSequence.Facings : Info.QuantizedFacings; - var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, numDirs) * (256 / numDirs); - - // Roll and pitch are always zero - return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); - } } } diff --git a/OpenRA.Game/Traits/Render/RenderSprites.cs b/OpenRA.Game/Traits/Render/RenderSprites.cs new file mode 100755 index 0000000000..9e6fd1a429 --- /dev/null +++ b/OpenRA.Game/Traits/Render/RenderSprites.cs @@ -0,0 +1,107 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Graphics; +using OpenRA.FileFormats; + +namespace OpenRA.Traits +{ + public class RenderSpritesInfo : ITraitInfo + { + [Desc("Defaults to the actor name.")] + public readonly string Image = null; + + [Desc("Custom palette name")] + public readonly string Palette = null; + [Desc("Custom PlayerColorPalette: BaseName")] + public readonly string PlayerPalette = "player"; + [Desc("Change the sprite image size.")] + public readonly float Scale = 1f; + + public virtual object Create(ActorInitializer init) { return new RenderSprites(init.self); } + } + + public class RenderSprites : IRender, ITick, INotifyOwnerChanged + { + public Dictionary anims = new Dictionary(); + + public static Func MakeFacingFunc(Actor self) + { + var facing = self.TraitOrDefault(); + if (facing == null) return () => 0; + return () => facing.Facing; + } + + public Animation anim + { + get { return anims[""].Animation; } + protected set { anims[""] = new AnimationWithOffset(value, + anims[""].OffsetFunc, anims[""].DisableFunc, anims[""].ZOffset); } + } + + RenderSpritesInfo Info; + string cachedImage = null; + bool initializePalette = true; + protected PaletteReference palette; + + public RenderSprites(Actor self, Func baseFacing) + { + Info = self.Info.Traits.Get(); + } + + public RenderSprites(Actor self) + : this(self, MakeFacingFunc(self)) {} + + public static string GetImage(ActorInfo actor) + { + var Info = actor.Traits.Get(); + return Info.Image ?? actor.Name; + } + + public string GetImage(Actor self) + { + if (cachedImage != null) + return cachedImage; + + return cachedImage = GetImage(self.Info); + } + + protected virtual string PaletteName(Actor self) + { + return Info.Palette ?? Info.PlayerPalette + self.Owner.InternalName; + } + + protected void UpdatePalette() { initializePalette = true; } + public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) { UpdatePalette(); } + + public virtual IEnumerable Render(Actor self, WorldRenderer wr) + { + if (initializePalette) + { + palette = wr.Palette(PaletteName(self)); + initializePalette = false; + } + + foreach (var a in anims.Values) + if (a.DisableFunc == null || !a.DisableFunc()) + yield return a.Image(self, wr, palette, Info.Scale); + } + + public virtual void Tick(Actor self) + { + foreach (var a in anims.Values) + a.Animation.Tick(); + } + + } +} diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 5b59961b38..4361998394 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -187,12 +187,14 @@ namespace OpenRA.Traits public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr); } public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); } public interface IRenderAsTerrain { IEnumerable RenderAsTerrain(WorldRenderer wr, Actor self); } - public interface ILocalCoordinatesModel + public interface IBodyOrientation { + WAngle CameraPitch { get; } + int QuantizedFacings { get; set; } WVec LocalToWorld(WVec vec); WRot QuantizeOrientation(Actor self, WRot orientation); } - public interface LocalCoordinatesModelInfo {} + public interface IBodyOrientationInfo {} public interface ITargetable { diff --git a/OpenRA.Mods.Cnc/RenderGunboat.cs b/OpenRA.Mods.Cnc/RenderGunboat.cs index 0b9c047c82..1e8a29fa34 100644 --- a/OpenRA.Mods.Cnc/RenderGunboat.cs +++ b/OpenRA.Mods.Cnc/RenderGunboat.cs @@ -15,7 +15,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - class RenderGunboatInfo : RenderUnitInfo + class RenderGunboatInfo : RenderSimpleInfo { public override object Create(ActorInitializer init) { return new RenderGunboat(init.self); } } @@ -26,8 +26,13 @@ namespace OpenRA.Mods.RA.Render string lastDir = "left"; string lastDamage = ""; + static Func TurretFacingFunc(Actor self) + { + return () => self.HasTrait() ? self.TraitsImplementing().First().turretFacing : 0; + } + public RenderGunboat(Actor self) - : base(self, () => self.HasTrait() ? self.TraitsImplementing().First().turretFacing : 0) + : base(self, TurretFacingFunc(self)) { facing = self.Trait(); anim.Play("left"); @@ -40,6 +45,8 @@ namespace OpenRA.Mods.RA.Render anims.Add("wake", new AnimationWithOffset(wake, () => anims["wake"].Animation.CurrentSequence.Name == "left-wake" ? leftOffset : rightOffset, () => false, -87)); + + self.Trait().QuantizedFacings = anim.CurrentSequence.Facings; } public override void Tick(Actor self) diff --git a/OpenRA.Mods.Cnc/WithCargo.cs b/OpenRA.Mods.Cnc/WithCargo.cs index 906e00db52..9fdd3258ba 100644 --- a/OpenRA.Mods.Cnc/WithCargo.cs +++ b/OpenRA.Mods.Cnc/WithCargo.cs @@ -18,7 +18,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { - public class WithCargoInfo : ITraitInfo, Requires, Requires + public class WithCargoInfo : ITraitInfo, Requires, Requires { [Desc("Cargo position relative to turret or body. (forward, right, up) triples")] public readonly WRange[] LocalOffset = {}; @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Cnc IFacing facing; WithCargoInfo Info; WVec[] positions; - ILocalCoordinatesModel coords; + IBodyOrientation body; public WithCargo(Actor self, WithCargoInfo info) { @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Cnc facing = self.TraitOrDefault(); Info = info; - coords = self.Trait(); + body = self.Trait(); if (info.LocalOffset.Length % 3 != 0) throw new InvalidOperationException("Invalid LocalOffset array length"); @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Cnc foreach (var rr in r) yield return rr; - var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation); + var bodyOrientation = body.QuantizeOrientation(self, self.Orientation); var pos = self.CenterPosition; int i = 0; foreach (var c in cargo.Passengers) @@ -68,7 +68,7 @@ namespace OpenRA.Mods.Cnc var cargoPassenger = c.Trait(); if (Info.DisplayTypes.Contains(cargoPassenger.info.CargoType)) { - var offset = pos - c.CenterPosition + coords.LocalToWorld(positions[i++ % positions.Length].Rotate(bodyOrientation)); + var offset = pos - c.CenterPosition + body.LocalToWorld(positions[i++ % positions.Length].Rotate(bodyOrientation)); foreach (var cr in c.Render(wr)) yield return cr.WithPos(cr.Pos + offset).WithZOffset(1); } diff --git a/OpenRA.Mods.Cnc/WithFire.cs b/OpenRA.Mods.Cnc/WithFire.cs index d273cd23e1..1550f04196 100644 --- a/OpenRA.Mods.Cnc/WithFire.cs +++ b/OpenRA.Mods.Cnc/WithFire.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { - class WithFireInfo : ITraitInfo, Requires + class WithFireInfo : ITraitInfo, Requires { public readonly WVec Offset = new WVec(299,-640,0); @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Cnc { public WithFire(Actor self, WithFireInfo info) { - var rs = self.Trait(); + var rs = self.Trait(); var roof = new Animation(rs.GetImage(self)); roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop")); diff --git a/OpenRA.Mods.Cnc/WithRoof.cs b/OpenRA.Mods.Cnc/WithRoof.cs index 0e22ab2b62..44eb4021da 100644 --- a/OpenRA.Mods.Cnc/WithRoof.cs +++ b/OpenRA.Mods.Cnc/WithRoof.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { - public class WithRoofInfo : ITraitInfo, Requires + public class WithRoofInfo : ITraitInfo, Requires { public object Create(ActorInitializer init) { return new WithRoof(init.self); } } @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Cnc { public WithRoof(Actor self) { - var rs = self.Trait(); + var rs = self.Trait(); var roof = new Animation(rs.GetImage(self), () => self.Trait().Facing); roof.Play("roof"); rs.anims.Add("roof", new AnimationWithOffset(roof, null, null, 1024)); diff --git a/OpenRA.Mods.RA/Armament.cs b/OpenRA.Mods.RA/Armament.cs index f73727bab5..95482d0bf9 100755 --- a/OpenRA.Mods.RA/Armament.cs +++ b/OpenRA.Mods.RA/Armament.cs @@ -54,7 +54,7 @@ namespace OpenRA.Mods.RA public readonly WeaponInfo Weapon; public readonly Barrel[] Barrels; Lazy Turret; - Lazy Coords; + Lazy Coords; public WRange Recoil; public int FireDelay { get; private set; } @@ -66,7 +66,7 @@ namespace OpenRA.Mods.RA // We can't resolve these until runtime Turret = Lazy.New(() => self.TraitsImplementing().FirstOrDefault(t => t.Name == info.Turret)); - Coords = Lazy.New(() => self.Trait()); + Coords = Lazy.New(() => self.Trait()); Weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()]; Burst = Weapon.Burst; diff --git a/OpenRA.Mods.RA/BelowUnits.cs b/OpenRA.Mods.RA/BelowUnits.cs index 64c5c36bc2..73c6fe4616 100644 --- a/OpenRA.Mods.RA/BelowUnits.cs +++ b/OpenRA.Mods.RA/BelowUnits.cs @@ -11,17 +11,30 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; namespace OpenRA.Mods.RA { - class BelowUnitsInfo : TraitInfo { } + class BelowUnitsInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new BelowUnits(init.self); } + } class BelowUnits : IRenderModifier { + int offset; + + public BelowUnits(Actor self) + { + // Offset effective position to the top of the northernmost occupied cell + var bi = self.Info.Traits.GetOrDefault(); + offset = (bi != null) ? -FootprintUtils.CenterOffset(bi).Y : -512; + } + public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) { - return r.Select(a => a.WithZOffset(-a.Size(wr).Z)); + return r.Select(a => a.WithZOffset(offset)); } } } diff --git a/OpenRA.Mods.RA/Buildings/DeadBuildingState.cs b/OpenRA.Mods.RA/Buildings/DeadBuildingState.cs index 8c3792ae4c..a584fae188 100644 --- a/OpenRA.Mods.RA/Buildings/DeadBuildingState.cs +++ b/OpenRA.Mods.RA/Buildings/DeadBuildingState.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { - class DeadBuildingStateInfo : ITraitInfo, Requires, Requires + class DeadBuildingStateInfo : ITraitInfo, Requires, Requires { public readonly int LingerTime = 20; @@ -23,12 +23,12 @@ namespace OpenRA.Mods.Cnc class DeadBuildingState : INotifyKilled { DeadBuildingStateInfo info; - RenderSimple rs; + RenderSprites rs; public DeadBuildingState(Actor self, DeadBuildingStateInfo info) { this.info = info; - rs = self.Trait(); + rs = self.Trait(); self.Trait().RemoveOnDeath = !rs.anim.HasSequence("dead"); } diff --git a/OpenRA.Mods.RA/Burns.cs b/OpenRA.Mods.RA/Burns.cs index 2e0dd35cea..ece4d23566 100644 --- a/OpenRA.Mods.RA/Burns.cs +++ b/OpenRA.Mods.RA/Burns.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class BurnsInfo : ITraitInfo, Requires + class BurnsInfo : ITraitInfo, Requires { public readonly string Anim = "1"; public readonly int Damage = 1; @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA var anim = new Animation("fire", () => 0); anim.PlayRepeating(Info.Anim); - self.Trait().anims.Add("fire", + self.Trait().anims.Add("fire", new AnimationWithOffset(anim, () => info.Offset, null)); } diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index d806990f59..e1a2c87041 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -16,7 +16,7 @@ using OpenRA.Mods.RA.Buildings; namespace OpenRA.Mods.RA { - class CrateInfo : ITraitInfo, Requires + class CrateInfo : ITraitInfo, Requires { public readonly int Lifetime = 5; // Seconds public readonly string[] TerrainTypes = { }; @@ -116,7 +116,7 @@ namespace OpenRA.Mods.RA PxPosition = Util.CenterOfCell(cell); var seq = self.World.GetTerrainInfo(cell).IsWater ? "water" : "land"; - var rs = self.Trait(); + var rs = self.Trait(); if (seq != rs.anim.CurrentSequence.Name) rs.anim.PlayRepeating(seq); diff --git a/OpenRA.Mods.RA/Effects/Contrail.cs b/OpenRA.Mods.RA/Effects/Contrail.cs index aad81bd457..17f15b49e2 100755 --- a/OpenRA.Mods.RA/Effects/Contrail.cs +++ b/OpenRA.Mods.RA/Effects/Contrail.cs @@ -16,7 +16,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class ContrailInfo : ITraitInfo, Requires + class ContrailInfo : ITraitInfo, Requires { [Desc("Position relative to body")] public readonly WVec Offset = WVec.Zero; @@ -32,7 +32,7 @@ namespace OpenRA.Mods.RA { ContrailInfo info; ContrailHistory history; - ILocalCoordinatesModel coords; + IBodyOrientation body; public Contrail(Actor self, ContrailInfo info) { @@ -40,13 +40,13 @@ namespace OpenRA.Mods.RA history = new ContrailHistory(info.TrailLength, info.UsePlayerColor ? ContrailHistory.ChooseColor(self) : info.Color); - coords = self.Trait(); + body = self.Trait(); } public void Tick(Actor self) { - var local = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation)); - history.Tick(self.CenterPosition + coords.LocalToWorld(local)); + var local = info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation)); + history.Tick(self.CenterPosition + body.LocalToWorld(local)); } public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(wr, self); } diff --git a/OpenRA.Mods.RA/Render/RenderBuilding.cs b/OpenRA.Mods.RA/Render/RenderBuilding.cs index 7fd16390df..d5cb08f4d6 100755 --- a/OpenRA.Mods.RA/Render/RenderBuilding.cs +++ b/OpenRA.Mods.RA/Render/RenderBuilding.cs @@ -57,6 +57,7 @@ namespace OpenRA.Mods.RA.Render var self = init.self; // Work around a bogus crash anim.PlayRepeating( NormalizeSequence(self, "idle") ); + self.Trait().QuantizedFacings = anim.CurrentSequence.Facings; // Can't call Complete() directly from ctor because other traits haven't been inited yet if (self.Info.Traits.Get().HasMakeAnimation && !init.Contains()) diff --git a/OpenRA.Mods.RA/Render/RenderBuildingTurreted.cs b/OpenRA.Mods.RA/Render/RenderBuildingTurreted.cs index daeeb3d00b..c2bc6b420a 100644 --- a/OpenRA.Mods.RA/Render/RenderBuildingTurreted.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingTurreted.cs @@ -22,8 +22,7 @@ namespace OpenRA.Mods.RA.Render class RenderBuildingTurreted : RenderBuilding { - public RenderBuildingTurreted( ActorInitializer init, RenderBuildingInfo info ) - : base(init, info, MakeTurretFacingFunc(init.self)) { } + Turreted t; static Func MakeTurretFacingFunc(Actor self) { @@ -31,5 +30,18 @@ namespace OpenRA.Mods.RA.Render var turreted = self.TraitsImplementing().FirstOrDefault(); return () => turreted.turretFacing; } + + public RenderBuildingTurreted(ActorInitializer init, RenderBuildingInfo info) + : base(init, info, MakeTurretFacingFunc(init.self)) + { + t = init.self.TraitsImplementing().FirstOrDefault(); + t.QuantizedFacings = anim.CurrentSequence.Facings; + } + + public override void DamageStateChanged(Actor self, AttackInfo e) + { + base.DamageStateChanged(self, e); + t.QuantizedFacings = anim.CurrentSequence.Facings; + } } } diff --git a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs index 14e5ee2eb4..087a9076da 100755 --- a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs @@ -32,7 +32,7 @@ namespace OpenRA.Mods.RA.Render foreach (var r in p) yield return r; - var anim = new Animation(RenderSimple.GetImage(building), () => 0); + var anim = new Animation(RenderSprites.GetImage(building), () => 0); anim.PlayRepeating("idle-top"); yield return new SpriteRenderable(anim.Image, WPos.Zero + Origin, 0, pr, 1f); } diff --git a/OpenRA.Mods.RA/Render/RenderInfantry.cs b/OpenRA.Mods.RA/Render/RenderInfantry.cs index d81ab8cdf2..c23055f3a6 100644 --- a/OpenRA.Mods.RA/Render/RenderInfantry.cs +++ b/OpenRA.Mods.RA/Render/RenderInfantry.cs @@ -55,12 +55,14 @@ namespace OpenRA.Mods.RA.Render public AnimationState State { get; private set; } public RenderInfantry(Actor self, RenderInfantryInfo info) - : base(self, RenderSimple.MakeFacingFunc(self)) + : base(self, MakeFacingFunc(self)) { Info = info; anim.PlayFetchIndex(NormalizeInfantrySequence(self, "stand"), () => 0); State = AnimationState.Waiting; mobile = self.Trait(); + + self.Trait().QuantizedFacings = anim.CurrentSequence.Facings; } public void Attacking(Actor self, Target target) diff --git a/OpenRA.Mods.RA/Render/RenderUnit.cs b/OpenRA.Mods.RA/Render/RenderUnit.cs index d280ab04c1..1efdd5c6a2 100644 --- a/OpenRA.Mods.RA/Render/RenderUnit.cs +++ b/OpenRA.Mods.RA/Render/RenderUnit.cs @@ -22,10 +22,7 @@ namespace OpenRA.Mods.RA.Render public class RenderUnit : RenderSimple { public RenderUnit(Actor self) - : base(self, RenderSimple.MakeFacingFunc(self)) - { - anim.PlayRepeating("idle"); - } + : base(self) { } public void PlayCustomAnimation(Actor self, string newAnim, Action after) { diff --git a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs index 6886cf8e02..7e4cc7afc3 100644 --- a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs @@ -17,7 +17,7 @@ using OpenRA.Mods.RA; namespace OpenRA.Mods.RA.Render { - class WithMuzzleFlashInfo : ITraitInfo, Requires, Requires + class WithMuzzleFlashInfo : ITraitInfo, Requires, Requires { public object Create(ActorInitializer init) { return new WithMuzzleFlash(init.self); } } @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Render public WithMuzzleFlash(Actor self) { - var render = self.Trait(); + var render = self.Trait(); var facing = self.TraitOrDefault(); var arms = self.TraitsImplementing(); diff --git a/OpenRA.Mods.RA/Render/WithRotor.cs b/OpenRA.Mods.RA/Render/WithRotor.cs index eea9c0dd77..2da92ea359 100755 --- a/OpenRA.Mods.RA/Render/WithRotor.cs +++ b/OpenRA.Mods.RA/Render/WithRotor.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class WithRotorInfo : ITraitInfo, Requires + public class WithRotorInfo : ITraitInfo, Requires, Requires { [Desc("Position relative to body")] public readonly WVec Offset = WVec.Zero; @@ -28,12 +28,13 @@ namespace OpenRA.Mods.RA.Render public Animation rotorAnim; public WithRotor(Actor self, WithRotorInfo info) { - var rs = self.Trait(); + var rs = self.Trait(); + var body = self.Trait(); rotorAnim = new Animation(rs.GetImage(self)); rotorAnim.PlayRepeating("rotor"); rs.anims.Add(info.Id, new AnimationWithOffset(rotorAnim, - () => rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation))), + () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), null, p => WithTurret.ZOffsetFromCenter(self, p, 1))); } diff --git a/OpenRA.Mods.RA/Render/WithSmoke.cs b/OpenRA.Mods.RA/Render/WithSmoke.cs index c35c27dbda..d4dc2915a5 100644 --- a/OpenRA.Mods.RA/Render/WithSmoke.cs +++ b/OpenRA.Mods.RA/Render/WithSmoke.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class WithSmokeInfo : ITraitInfo, Requires + public class WithSmokeInfo : ITraitInfo, Requires { public object Create(ActorInitializer init) { return new WithSmoke(init.self); } } @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Render public WithSmoke(Actor self) { - var rs = self.Trait(); + var rs = self.Trait(); anim = new Animation("smoke_m"); rs.anims.Add("smoke", new AnimationWithOffset(anim, null, () => !isSmoking)); diff --git a/OpenRA.Mods.RA/Render/WithSpinner.cs b/OpenRA.Mods.RA/Render/WithSpinner.cs index c9a1eaf44e..68e003d42b 100755 --- a/OpenRA.Mods.RA/Render/WithSpinner.cs +++ b/OpenRA.Mods.RA/Render/WithSpinner.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - class WithSpinnerInfo : ITraitInfo, Requires + class WithSpinnerInfo : ITraitInfo, Requires, Requires { [Desc("Sequence name to use")] public readonly string Sequence = "spinner"; @@ -29,11 +29,13 @@ namespace OpenRA.Mods.RA.Render { public WithSpinner(Actor self, WithSpinnerInfo info) { - var rs = self.Trait(); + var rs = self.Trait(); + var body = self.Trait(); + var spinner = new Animation(rs.GetImage(self)); spinner.PlayRepeating(info.Sequence); rs.anims.Add("spinner_{0}".F(info.Sequence), new AnimationWithOffset(spinner, - () => rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation))), + () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), null, p => WithTurret.ZOffsetFromCenter(self, p, 1))); } } diff --git a/OpenRA.Mods.RA/Render/WithTurret.cs b/OpenRA.Mods.RA/Render/WithTurret.cs index b0981325ce..fdca26d491 100755 --- a/OpenRA.Mods.RA/Render/WithTurret.cs +++ b/OpenRA.Mods.RA/Render/WithTurret.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made @@ -17,7 +17,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - class WithTurretInfo : ITraitInfo, Requires, Requires + class WithTurretInfo : ITraitInfo, Requires, Requires, Requires { [Desc("Sequence name to use")] public readonly string Sequence = "turret"; @@ -28,13 +28,17 @@ namespace OpenRA.Mods.RA.Render [Desc("Turreted 'Turret' key to display")] public readonly string Turret = "primary"; + [Desc("Render recoil")] + public readonly bool Recoils = true; + public object Create(ActorInitializer init) { return new WithTurret(init.self, this); } } class WithTurret : ITick { WithTurretInfo info; - RenderSimple rs; + RenderSprites rs; + IBodyOrientation body; AttackBase ab; Turreted t; IEnumerable arms; @@ -43,7 +47,9 @@ namespace OpenRA.Mods.RA.Render public WithTurret(Actor self, WithTurretInfo info) { this.info = info; - rs = self.Trait(); + rs = self.Trait(); + body = self.Trait(); + ab = self.TraitOrDefault(); t = self.TraitsImplementing() .First(tt => tt.Name == info.Turret); @@ -54,15 +60,21 @@ namespace OpenRA.Mods.RA.Render anim.Play(info.Sequence); rs.anims.Add("turret_{0}".F(info.Turret), new AnimationWithOffset( anim, () => TurretOffset(self), null, p => ZOffsetFromCenter(self, p, 1))); + + // Restrict turret facings to match the sprite + t.QuantizedFacings = anim.CurrentSequence.Facings; } WVec TurretOffset(Actor self) { + if (!info.Recoils) + return t.Position(self); + var recoil = arms.Aggregate(WRange.Zero, (a,b) => a + b.Recoil); var localOffset = new WVec(-recoil, WRange.Zero, WRange.Zero); - var bodyOrientation = rs.QuantizeOrientation(self, self.Orientation); - var turretOrientation = rs.QuantizeOrientation(self, t.LocalOrientation(self)); - return t.Position(self) + rs.LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation)); + var bodyOrientation = body.QuantizeOrientation(self, self.Orientation); + var turretOrientation = body.QuantizeOrientation(self, t.LocalOrientation(self)); + return t.Position(self) + body.LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation)); } public void Tick(Actor self) diff --git a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs index fcb5c871fc..787d1249a5 100644 --- a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs +++ b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class SmokeTrailWhenDamagedInfo : ITraitInfo, Requires + class SmokeTrailWhenDamagedInfo : ITraitInfo, Requires { [Desc("Position relative to body")] public readonly WVec Offset = WVec.Zero; @@ -26,14 +26,14 @@ namespace OpenRA.Mods.RA class SmokeTrailWhenDamaged : ITick { - ILocalCoordinatesModel coords; + IBodyOrientation body; SmokeTrailWhenDamagedInfo info; int ticks; public SmokeTrailWhenDamaged(Actor self, SmokeTrailWhenDamagedInfo info) { this.info = info; - coords = self.Trait(); + body = self.Trait(); } public void Tick(Actor self) @@ -44,8 +44,8 @@ namespace OpenRA.Mods.RA if (position.Z > 0 && self.GetDamageState() >= DamageState.Heavy && !self.World.FogObscures(new CPos(position))) { - var offset = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation)); - var pos = position + coords.LocalToWorld(offset); + var offset = info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation)); + var pos = position + body.LocalToWorld(offset); self.World.AddFrameEndTask(w => w.Add(new Smoke(w, pos, info.Sprite))); } diff --git a/OpenRA.Mods.RA/Spy.cs b/OpenRA.Mods.RA/Spy.cs index a381444d1a..aa3651c59b 100644 --- a/OpenRA.Mods.RA/Spy.cs +++ b/OpenRA.Mods.RA/Spy.cs @@ -126,7 +126,7 @@ namespace OpenRA.Mods.RA var tooltip = target.TraitsImplementing().FirstOrDefault(); disguisedAsName = tooltip.Name(); disguisedAsPlayer = tooltip.Owner(); - disguisedAsSprite = target.Trait().GetImage(target); + disguisedAsSprite = target.Trait().GetImage(target); } void DropDisguise() diff --git a/OpenRA.Mods.RA/SupportPowers/NukePower.cs b/OpenRA.Mods.RA/SupportPowers/NukePower.cs index cb7b9b5ea7..5e7d88b5fc 100755 --- a/OpenRA.Mods.RA/SupportPowers/NukePower.cs +++ b/OpenRA.Mods.RA/SupportPowers/NukePower.cs @@ -14,7 +14,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class NukePowerInfo : SupportPowerInfo + class NukePowerInfo : SupportPowerInfo, Requires { [WeaponReference] public readonly string MissileWeapon = ""; @@ -25,7 +25,14 @@ namespace OpenRA.Mods.RA class NukePower : SupportPower { - public NukePower(Actor self, NukePowerInfo info) : base(self, info) { } + IBodyOrientation body; + + public NukePower(Actor self, NukePowerInfo info) + : base(self, info) + { + body = self.Trait(); + } + public override IOrderGenerator OrderGenerator(string order, SupportPowerManager manager) { Sound.PlayToPlayer(manager.self.Owner, Info.SelectTargetSound); @@ -42,7 +49,7 @@ namespace OpenRA.Mods.RA var rb = self.Trait(); rb.PlayCustomAnim(self, "active"); self.World.AddFrameEndTask(w => w.Add( - new NukeLaunch(self.Owner, self, npi.MissileWeapon, self.CenterPosition + rb.LocalToWorld(npi.SpawnOffset), order.TargetLocation))); + new NukeLaunch(self.Owner, self, npi.MissileWeapon, self.CenterPosition + body.LocalToWorld(npi.SpawnOffset), order.TargetLocation))); } } } diff --git a/OpenRA.Mods.RA/ThrowsParticle.cs b/OpenRA.Mods.RA/ThrowsParticle.cs index f6bb3a3842..076000e37f 100644 --- a/OpenRA.Mods.RA/ThrowsParticle.cs +++ b/OpenRA.Mods.RA/ThrowsParticle.cs @@ -15,7 +15,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class ThrowsParticleInfo : ITraitInfo, Requires + class ThrowsParticleInfo : ITraitInfo, Requires, Requires { public readonly string Anim = null; @@ -54,6 +54,7 @@ namespace OpenRA.Mods.RA var self = init.self; var rs = self.Trait(); + var body = self.Trait(); // TODO: Carry orientation over from the parent instead of just facing var bodyFacing = init.Contains() ? init.Get() : 0; @@ -63,7 +64,7 @@ namespace OpenRA.Mods.RA var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); var throwOffset = new WVec((int)(Game.CosmeticRandom.Gauss1D(1)*info.ThrowRange.Range), 0, 0).Rotate(throwRotation); - initialPos = pos = info.Offset.Rotate(rs.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); + initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); finalPos = initialPos + throwOffset; // Facing rotation diff --git a/OpenRA.Mods.RA/Turreted.cs b/OpenRA.Mods.RA/Turreted.cs index 0040377b81..d863bf90af 100755 --- a/OpenRA.Mods.RA/Turreted.cs +++ b/OpenRA.Mods.RA/Turreted.cs @@ -33,6 +33,7 @@ namespace OpenRA.Mods.RA public class Turreted : ITick, ISync, IResolveOrder { + [Sync] public int QuantizedFacings = 0; [Sync] public int turretFacing = 0; public int? desiredFacing; TurretedInfo info; @@ -83,16 +84,25 @@ namespace OpenRA.Mods.RA // Turret offset in world-space public WVec Position(Actor self) { - var coords = self.Trait(); - var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation); - return coords.LocalToWorld(Offset.Rotate(bodyOrientation)); + var body = self.Trait(); + var bodyOrientation = body.QuantizeOrientation(self, self.Orientation); + return body.LocalToWorld(Offset.Rotate(bodyOrientation)); } // Orientation in unit-space public WRot LocalOrientation(Actor self) { + // Hack: turretFacing is relative to the world, so subtract the body yaw - return WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw); + var local = WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw); + + if (QuantizedFacings == 0) + return local; + + // Quantize orientation to match a rendered sprite + // Implies no pitch or yaw + var facing = Traits.Util.QuantizeFacing(local.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings); + return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); } } } diff --git a/mods/cnc/rules/civilian.yaml b/mods/cnc/rules/civilian.yaml index 28b5e86d9d..7981d04c29 100644 --- a/mods/cnc/rules/civilian.yaml +++ b/mods/cnc/rules/civilian.yaml @@ -445,3 +445,4 @@ VICE: AttackWander: RenderUnit: WithMuzzleFlash: + BodyOrientation: diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 1f3e58336b..9d7e226c61 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -33,6 +33,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Tank: AppearsOnRadar: @@ -72,6 +73,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Helicopter: AppearsOnRadar: @@ -97,6 +99,7 @@ Weapon: HeliExplode EmptyWeapon: HeliExplode DebugMuzzlePositions: + BodyOrientation: ^Infantry: AppearsOnRadar: @@ -149,6 +152,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^CivInfantry: Inherits: ^Infantry @@ -197,6 +201,7 @@ DrawLineToTarget: ActorLostNotification: DebugMuzzlePositions: + BodyOrientation: ^Ship: AppearsOnRadar: @@ -218,6 +223,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Building: AppearsOnRadar: @@ -266,6 +272,7 @@ DebugMuzzlePositions: Guardable: Range: 3 + BodyOrientation: ^CivBuilding: Inherits: ^Building @@ -296,6 +303,7 @@ RelativeToTopLeft: yes Tooltip: Name: Civilian Building (Destroyed) + BodyOrientation: ^TechBuilding: Inherits: ^CivBuilding @@ -326,6 +334,7 @@ Tooltip: Name: Field (Destroyed) BelowUnits: + BodyOrientation: ^Wall: AppearsOnRadar: @@ -354,6 +363,7 @@ AutoTargetIgnore: Sellable: Guardable: + BodyOrientation: ^Tree: Tooltip: @@ -374,6 +384,7 @@ Armor: Type: Wood AutoTargetIgnore: + BodyOrientation: ^Rock: Tooltip: @@ -388,6 +399,7 @@ Terrain: Tree EditorAppearance: RelativeToTopLeft: yes + BodyOrientation: ^Husk: Health: @@ -403,6 +415,7 @@ TransformOnCapture: ForceHealthPercentage: 25 BelowUnits: + BodyOrientation: # Capturable: # Type: husk # AllowAllies: true @@ -420,3 +433,4 @@ SoundOnDamageTransition: DamagedSound: xplos.aud DestroyedSound: xplobig4.aud + BodyOrientation: diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 991dd0e609..1445012741 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -351,11 +351,14 @@ CRATE: Unit: mcv RenderSimple: BelowUnits: + BodyOrientation: mpspawn: Waypoint: RenderEditorOnly: + BodyOrientation: waypoint: Waypoint: RenderEditorOnly: + BodyOrientation: diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 41f594ac2b..d506700057 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -33,6 +33,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Tank: AppearsOnRadar: @@ -69,6 +70,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Husk: Health: @@ -84,6 +86,7 @@ Types:Husk Tooltip: Name: Destroyed Tank + BodyOrientation: ^TowerHusk: Health: @@ -101,6 +104,7 @@ Name: Destroyed Tower ProximityCaptor: Types:Husk + BodyOrientation: ^Infantry: AppearsOnRadar: @@ -149,6 +153,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Plane: AppearsOnRadar: @@ -168,6 +173,7 @@ Types:Plane GivesBounty: DebugMuzzlePositions: + BodyOrientation: ^Helicopter: Inherits: ^Plane @@ -216,3 +222,4 @@ Bib: Guardable: Range: 3 + BodyOrientation: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 534591b790..452078c14c 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -372,6 +372,7 @@ WALL: Types:Wall Sellable: Guardable: + BodyOrientation: GUNTOWER: Inherits: ^Building diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 22a0faaf9a..11ec28e4c1 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -481,14 +481,17 @@ CRATE: ProximityCaptor: Types:Crate Passenger: + BodyOrientation: mpspawn: Waypoint: RenderEditorOnly: + BodyOrientation: waypoint: Waypoint: RenderEditorOnly: + BodyOrientation: SPICEBLOOM: RenderBuilding: @@ -508,6 +511,7 @@ SPICEBLOOM: Interval: 75 RadarColorFromTerrain: Terrain: Spice + BodyOrientation: #SANDWORM: # Buildable: diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index d67bdfe017..1f9d8a6413 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -36,6 +36,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Tank: AppearsOnRadar: @@ -75,6 +76,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Infantry: AppearsOnRadar: @@ -126,6 +128,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Ship: AppearsOnRadar: @@ -157,6 +160,7 @@ DebugMuzzlePositions: Guard: Guardable: + BodyOrientation: ^Plane: AppearsOnRadar: @@ -183,6 +187,7 @@ String:Plane UpdatesPlayerStatistics: DebugMuzzlePositions: + BodyOrientation: ^Helicopter: Inherits: ^Plane @@ -229,6 +234,7 @@ Guardable: Range: 3 AutoTargetIgnore: + BodyOrientation: ^Wall: AppearsOnRadar: @@ -263,6 +269,7 @@ Sellable: UpdatesPlayerStatistics: Guardable: + BodyOrientation: ^TechBuilding: Inherits: ^Building @@ -344,6 +351,7 @@ Armor: Type: Wood AutoTargetIgnore: + BodyOrientation: ^Husk: Husk: @@ -358,6 +366,7 @@ ProximityCaptor: Types:Husk BelowUnits: + BodyOrientation: ^Bridge: Tooltip: @@ -373,6 +382,7 @@ ProximityCaptor: Types:Bridge AutoTargetIgnore: + BodyOrientation: #Temperate Terrain Expansion ^SVBridge: @@ -389,6 +399,7 @@ ProximityCaptor: Types:Bridge AutoTargetIgnore: + BodyOrientation: ^SHBridge: Tooltip: @@ -404,6 +415,7 @@ ProximityCaptor: Types:Bridge AutoTargetIgnore: + BodyOrientation: ^STDBridge: Tooltip: @@ -419,6 +431,7 @@ ProximityCaptor: Types:Bridge AutoTargetIgnore: + BodyOrientation: #Desert Terrain Expansion: ^Rock: @@ -437,6 +450,7 @@ UseTerrainPalette: true ProximityCaptor: Types:Tree + BodyOrientation: ^DesertCivBuilding: Inherits: ^CivBuilding diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index d96879b3cf..34f027f938 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -670,6 +670,7 @@ MINP: Types: Mine TargetableUnit: TargetTypes: Ground + BodyOrientation: MINV: Mine: @@ -695,6 +696,7 @@ MINV: Types: Mine TargetableUnit: TargetTypes: Ground + BodyOrientation: CRATE: Tooltip: @@ -757,6 +759,7 @@ CRATE: ProximityCaptor: Types:Crate Passenger: + BodyOrientation: CAMERA: Aircraft: @@ -766,6 +769,7 @@ CAMERA: Range: 10 ProximityCaptor: Types:Camera + BodyOrientation: FLARE: Aircraft: @@ -780,6 +784,7 @@ FLARE: Name: Flare ProximityCaptor: Types: Flare + BodyOrientation: powerproxy.parabombs: AirstrikePower: @@ -805,7 +810,9 @@ powerproxy.sonarpulse: mpspawn: Waypoint: RenderEditorOnly: + BodyOrientation: waypoint: Waypoint: RenderEditorOnly: + BodyOrientation: