diff --git a/OpenRA.FileFormats/WPos.cs b/OpenRA.FileFormats/WPos.cs index 6b0c0ec7bd..7800ef8508 100644 --- a/OpenRA.FileFormats/WPos.cs +++ b/OpenRA.FileFormats/WPos.cs @@ -34,6 +34,28 @@ namespace OpenRA public static bool operator ==(WPos me, WPos other) { return (me.X == other.X && me.Y == other.Y && me.Z == other.Z); } public static bool operator !=(WPos me, WPos other) { return !(me == other); } + public static WPos Average(params WPos[] list) + { + if (list == null || list.Length == 0) + return WPos.Zero; + + var x = 0; + var y = 0; + var z = 0; + foreach(var pos in list) + { + x += pos.X; + y += pos.Y; + z += pos.Z; + } + + x /= list.Length; + y /= list.Length; + z /= list.Length; + + return new WPos(x,y,z); + } + public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); } public override bool Equals(object obj) diff --git a/OpenRA.FileFormats/WVec.cs b/OpenRA.FileFormats/WVec.cs index 0140a78616..4eab6e15d1 100644 --- a/OpenRA.FileFormats/WVec.cs +++ b/OpenRA.FileFormats/WVec.cs @@ -26,8 +26,11 @@ namespace OpenRA public static readonly WVec Zero = new WVec(0, 0, 0); public static WVec operator +(WVec a, WVec b) { return new WVec(a.X + b.X, a.Y + b.Y, a.Z + b.Z); } - public static WVec operator -(WVec a, WVec b) { return new WVec(a.X - b.X, a.Y - b.Y, a.Y - b.Y); } + public static WVec operator -(WVec a, WVec b) { return new WVec(a.X - b.X, a.Y - b.Y, a.Z - b.Z); } public static WVec operator -(WVec a) { return new WVec(-a.X, -a.Y, -a.Z); } + public static WVec operator /(WVec a, int b) { return new WVec(a.X / b, a.Y / b, a.Z / b); } + public static WVec operator *(int a, WVec b) { return new WVec(a * b.X, a * b.Y, a * b.Z); } + public static WVec operator *(WVec a, int b) { return b*a; } public static bool operator ==(WVec me, WVec other) { return (me.X == other.X && me.Y == other.Y && me.Z == other.Z); } public static bool operator !=(WVec me, WVec other) { return !(me == other); } @@ -48,6 +51,8 @@ namespace OpenRA (int)((lx * mtx[2] + ly*mtx[6] + lz*mtx[10]) / mtx[15])); } + public static WVec Lerp(WVec a, WVec b, int mul, int div) { return a + (b - a) * mul / div; } + public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); } public override bool Equals(object obj) diff --git a/OpenRA.Game/CPos.cs b/OpenRA.Game/CPos.cs index 2743ca021a..832aab7998 100644 --- a/OpenRA.Game/CPos.cs +++ b/OpenRA.Game/CPos.cs @@ -21,6 +21,7 @@ namespace OpenRA public readonly int X, Y; public CPos(int x, int y) { X = x; Y = y; } + public CPos(WPos a) { X = a.X / 1024; Y = a.Y / 1024; } public static readonly CPos Zero = new CPos(0, 0); diff --git a/OpenRA.Game/Graphics/AnimationWithOffset.cs b/OpenRA.Game/Graphics/AnimationWithOffset.cs index c048f5c8fd..8691c91c6e 100644 --- a/OpenRA.Game/Graphics/AnimationWithOffset.cs +++ b/OpenRA.Game/Graphics/AnimationWithOffset.cs @@ -16,7 +16,7 @@ namespace OpenRA.Graphics public class AnimationWithOffset { public Animation Animation; - public Func OffsetFunc; + public Func OffsetFunc; public Func DisableFunc; public int ZOffset; @@ -25,18 +25,18 @@ namespace OpenRA.Graphics { } - public AnimationWithOffset(Animation a, Func o, Func d) + public AnimationWithOffset(Animation a, Func o, Func d) { this.Animation = a; this.OffsetFunc = o; this.DisableFunc = d; } - public Renderable Image(Actor self, PaletteReference pal) + public Renderable Image(Actor self, WorldRenderer wr, PaletteReference pal) { var p = self.CenterLocation; var loc = p.ToFloat2() - 0.5f * Animation.Image.size - + (OffsetFunc != null ? OffsetFunc() : float2.Zero); + + (OffsetFunc != null ? OffsetFunc(wr) : float2.Zero); var r = new Renderable(Animation.Image, loc, pal, p.Y); return ZOffset != 0 ? r.WithZOffset(ZOffset) : r; diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index af87f627ed..885060c2ce 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -165,7 +165,7 @@ namespace OpenRA.Graphics var avgPos = actors .Select(a => (PVecInt)a.CenterLocation) .Aggregate((a, b) => a + b) / actors.Count(); - scrollPosition = NormalizeScrollPosition(((PVecFloat)avgPos - (PVecFloat)(1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2()); + scrollPosition = NormalizeScrollPosition((avgPos.ToFloat2() - (1f / (2 * Zoom) * screenSize.ToFloat2())).ToInt2()); } // Rectangle (in viewport coords) that contains things to be drawn diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 0b2270705c..aee543cc52 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -221,11 +221,15 @@ namespace OpenRA.Graphics public int2 ScreenPxPosition(WPos pos) { - var c = Game.CellSize/1024f; - return new int2((int)(c*pos.X), (int)(c*(pos.Y - pos.Z))); + return new int2(Game.CellSize*pos.X/1024, Game.CellSize*(pos.Y - pos.Z)/1024); } public float ScreenZOffset(WPos pos) { return pos.Z*Game.CellSize/1024f; } + public int2 ScreenPxOffset(WVec vec) + { + return new int2(Game.CellSize*vec.X/1024, Game.CellSize*(vec.Y - vec.Z)/1024); + } + public float[] ScreenOffset(WVec vec) { var c = Game.CellSize/1024f; diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj old mode 100755 new mode 100644 index e1d4cc465c..ac7aae5bb2 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -84,7 +84,6 @@ - diff --git a/OpenRA.Game/PPos.cs b/OpenRA.Game/PPos.cs index 2703986419..4a3f45b350 100644 --- a/OpenRA.Game/PPos.cs +++ b/OpenRA.Game/PPos.cs @@ -39,7 +39,6 @@ namespace OpenRA public static explicit operator PPos(int2 a) { return new PPos(a.X, a.Y); } public static explicit operator PVecInt(PPos a) { return new PVecInt(a.X, a.Y); } - public static explicit operator PVecFloat(PPos a) { return new PVecFloat(a.X, a.Y); } public static PPos operator +(PPos a, PVecInt b) { return new PPos(a.X + b.X, a.Y + b.Y); } public static PVecInt operator -(PPos a, PPos b) { return new PVecInt(a.X - b.X, a.Y - b.Y); } diff --git a/OpenRA.Game/PSubPos.cs b/OpenRA.Game/PSubPos.cs index 8894012c92..7bd193565a 100644 --- a/OpenRA.Game/PSubPos.cs +++ b/OpenRA.Game/PSubPos.cs @@ -29,7 +29,6 @@ namespace OpenRA public static explicit operator PSubPos(int2 a) { return new PSubPos(a.X, a.Y); } public static explicit operator PSubVec(PSubPos a) { return new PSubVec(a.X, a.Y); } - public static explicit operator PVecFloat(PSubPos a) { return new PVecFloat(a.X, a.Y); } public static PSubPos operator +(PSubPos a, PSubVec b) { return new PSubPos(a.X + b.X, a.Y + b.Y); } public static PSubVec operator -(PSubPos a, PSubPos b) { return new PSubVec(a.X - b.X, a.Y - b.Y); } diff --git a/OpenRA.Game/PSubVec.cs b/OpenRA.Game/PSubVec.cs index 44c9b92837..d461ec6333 100644 --- a/OpenRA.Game/PSubVec.cs +++ b/OpenRA.Game/PSubVec.cs @@ -94,10 +94,5 @@ namespace OpenRA { return new PSubVec((vec.X * PSubPos.PerPx), (vec.Y * PSubPos.PerPx)); } - - public static PSubVec ToPSubVec(this PVecFloat vec) - { - return new PSubVec((int)(vec.X * PSubPos.PerPx), (int)(vec.Y * PSubPos.PerPx)); - } } } diff --git a/OpenRA.Game/PVecFloat.cs b/OpenRA.Game/PVecFloat.cs deleted file mode 100644 index be463763d4..0000000000 --- a/OpenRA.Game/PVecFloat.cs +++ /dev/null @@ -1,97 +0,0 @@ -#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.Drawing; - -namespace OpenRA -{ - /// - /// Pixel coordinate vector (fine; float) - /// - public struct PVecFloat - { - public readonly float X, Y; - - public PVecFloat(float x, float y) { X = x; Y = y; } - public PVecFloat(Size p) { X = p.Width; Y = p.Height; } - - public static readonly PVecFloat Zero = new PVecFloat(0, 0); - - public static explicit operator PVecInt(PVecFloat a) { return new PVecInt((int)a.X, (int)a.Y); } - public static explicit operator PVecFloat(float2 a) { return new PVecFloat(a.X, a.Y); } - - public static PVecFloat operator +(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X + b.X, a.Y + b.Y); } - public static PVecFloat operator -(PVecFloat a, PVecFloat b) { return new PVecFloat(a.X - b.X, a.Y - b.Y); } - public static PVecFloat operator *(float a, PVecFloat b) { return new PVecFloat(a * b.X, a * b.Y); } - public static PVecFloat operator *(PVecFloat b, float a) { return new PVecFloat(a * b.X, a * b.Y); } - public static PVecFloat operator /(PVecFloat a, float b) { return new PVecFloat(a.X / b, a.Y / b); } - - public static PVecFloat operator -(PVecFloat a) { return new PVecFloat(-a.X, -a.Y); } - - public static bool operator ==(PVecFloat me, PVecFloat other) { return (me.X == other.X && me.Y == other.Y); } - public static bool operator !=(PVecFloat me, PVecFloat other) { return !(me == other); } - - public static PVecFloat Max(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y)); } - public static PVecFloat Min(PVecFloat a, PVecFloat b) { return new PVecFloat(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); } - - public static float Dot(PVecFloat a, PVecFloat b) { return a.X * b.X + a.Y * b.Y; } - - public static PVecFloat FromAngle(float a) { return new PVecFloat((float)Math.Sin(a), (float)Math.Cos(a)); } - - public static PVecFloat Lerp(PVecFloat a, PVecFloat b, float t) - { - return new PVecFloat( - float2.Lerp(a.X, b.X, t), - float2.Lerp(a.Y, b.Y, t) - ); - } - - public static PVecFloat Lerp(PVecFloat a, PVecFloat b, PVecFloat t) - { - return new PVecFloat( - float2.Lerp(a.X, b.X, t.X), - float2.Lerp(a.Y, b.Y, t.Y) - ); - } - - public PVecFloat Sign() { return new PVecFloat(Math.Sign(X), Math.Sign(Y)); } - public PVecFloat Abs() { return new PVecFloat(Math.Abs(X), Math.Abs(Y)); } - public PVecFloat Round() { return new PVecFloat((float)Math.Round(X), (float)Math.Round(Y)); } - public float LengthSquared { get { return X * X + Y * Y; } } - public float Length { get { return (float)Math.Sqrt(LengthSquared); } } - - public float2 ToFloat2() { return new float2(X, Y); } - public int2 ToInt2() { return new int2((int)X, (int)Y); } - - static float Constrain(float x, float a, float b) { return x < a ? a : x > b ? b : x; } - - public PVecFloat Constrain(PVecFloat min, PVecFloat max) - { - return new PVecFloat( - Constrain(X, min.X, max.X), - Constrain(Y, min.Y, max.Y) - ); - } - - public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); } - - public override bool Equals(object obj) - { - if (obj == null) - return false; - - PVecFloat o = (PVecFloat)obj; - return o == this; - } - - public override string ToString() { return "({0},{1})".F(X, Y); } - } -} diff --git a/OpenRA.Game/PVecInt.cs b/OpenRA.Game/PVecInt.cs index a98ea9fc5a..aed7981228 100644 --- a/OpenRA.Game/PVecInt.cs +++ b/OpenRA.Game/PVecInt.cs @@ -26,7 +26,6 @@ namespace OpenRA public static readonly PVecInt Zero = new PVecInt(0, 0); public static PVecInt OneCell { get { return new PVecInt(Game.CellSize, Game.CellSize); } } - public static implicit operator PVecFloat(PVecInt a) { return new PVecFloat((float)a.X, (float)a.Y); } public static explicit operator PVecInt(int2 a) { return new PVecInt(a.X, a.Y); } public static PVecInt FromRadius(int r) { return new PVecInt(r, r); } diff --git a/OpenRA.Game/Traits/Render/RenderSimple.cs b/OpenRA.Game/Traits/Render/RenderSimple.cs index 6b8b900204..eec13f8683 100755 --- a/OpenRA.Game/Traits/Render/RenderSimple.cs +++ b/OpenRA.Game/Traits/Render/RenderSimple.cs @@ -16,7 +16,7 @@ using OpenRA.FileFormats; namespace OpenRA.Traits { - public class RenderSimpleInfo : ITraitInfo + public class RenderSimpleInfo : ITraitInfo, LocalCoordinatesModelInfo { [Desc("Defaults to the actor name.")] public readonly string Image = null; @@ -108,7 +108,7 @@ namespace OpenRA.Traits foreach (var a in anims.Values) if (a.DisableFunc == null || !a.DisableFunc()) { - Renderable ret = a.Image(self, palette); + Renderable ret = a.Image(self, wr, palette); if (Info.Scale != 1f) ret = ret.WithScale(Info.Scale).WithPos(ret.Pos + 0.5f * ret.Sprite.size * (1 - Info.Scale)); yield return ret; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 6550938016..42b75205ab 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -216,6 +216,7 @@ namespace OpenRA.Traits WVec LocalToWorld(WVec vec); WRot QuantizeOrientation(Actor self, WRot orientation); } + public interface LocalCoordinatesModelInfo {} public interface ITargetable { diff --git a/OpenRA.Mods.Cnc/RenderBuildingRefinery.cs b/OpenRA.Mods.Cnc/RenderBuildingRefinery.cs index 105dd9934e..819f02cf53 100755 --- a/OpenRA.Mods.Cnc/RenderBuildingRefinery.cs +++ b/OpenRA.Mods.Cnc/RenderBuildingRefinery.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc : 0); var offset = new float2(-32,-21); - anims.Add("lights", new AnimationWithOffset( lights, () => offset, () => !buildComplete ) + anims.Add("lights", new AnimationWithOffset( lights, wr => offset, () => !buildComplete ) { ZOffset = 24 }); } diff --git a/OpenRA.Mods.Cnc/RenderGunboat.cs b/OpenRA.Mods.Cnc/RenderGunboat.cs index 708d29a405..9bb6be9d3d 100644 --- a/OpenRA.Mods.Cnc/RenderGunboat.cs +++ b/OpenRA.Mods.Cnc/RenderGunboat.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Render var wake = new Animation(anim.Name); wake.Play("left-wake"); - Func offset = () => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2); + Func offset = wr => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2); anims.Add( "wake", new AnimationWithOffset( wake, offset, () => false ) { ZOffset = -2 } ); } diff --git a/OpenRA.Mods.Cnc/WithFire.cs b/OpenRA.Mods.Cnc/WithFire.cs index d94c8922a4..85ee48ca0b 100644 --- a/OpenRA.Mods.Cnc/WithFire.cs +++ b/OpenRA.Mods.Cnc/WithFire.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc var rs = self.Trait(); var roof = new Animation(rs.GetImage(self)); roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop")); - rs.anims.Add( "fire", new AnimationWithOffset( roof, () => new float2(7,-15), null ) { ZOffset = 24 } ); + rs.anims.Add( "fire", new AnimationWithOffset( roof, wr => new float2(7,-15), null ) { ZOffset = 24 } ); } } } diff --git a/OpenRA.Mods.RA/Burns.cs b/OpenRA.Mods.RA/Burns.cs index bc39d33ef8..34c3db5528 100644 --- a/OpenRA.Mods.RA/Burns.cs +++ b/OpenRA.Mods.RA/Burns.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA var anim = new Animation("fire", () => 0); anim.PlayRepeating(Info.Anim); rs.anims.Add("fire", - new AnimationWithOffset(anim, () => new float2(0, -3), null)); + new AnimationWithOffset(anim, wr => new float2(0, -3), null)); } public void Tick(Actor self) diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index 0aa706e911..5939ed008a 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -128,7 +128,10 @@ namespace OpenRA.Mods.RA.Effects } if (Trail != null) - Trail.Tick((PPos)highPos.ToInt2()); + { + var alt = (Info.High || Info.Angle > 0) ? GetAltitude() : 0; + Trail.Tick(new PPos((int)pos.X, (int)pos.Y).ToWPos((int)alt)); + } } if (!Info.High) // check for hitting a wall @@ -175,7 +178,7 @@ namespace OpenRA.Mods.RA.Effects } if (Trail != null) - Trail.Render(Args.firedBy); + Trail.Render(wr, Args.firedBy); } void Explode( World world ) diff --git a/OpenRA.Mods.RA/Effects/Contrail.cs b/OpenRA.Mods.RA/Effects/Contrail.cs index 046d5d5ffc..4c0b3ffb4a 100755 --- a/OpenRA.Mods.RA/Effects/Contrail.cs +++ b/OpenRA.Mods.RA/Effects/Contrail.cs @@ -16,9 +16,10 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class ContrailInfo : ITraitInfo + class ContrailInfo : ITraitInfo, Requires { - public readonly int[] ContrailOffset = {0, 0}; + [Desc("Position relative to body")] + public readonly WVec Offset = WVec.Zero; public readonly int TrailLength = 25; public readonly Color Color = Color.White; @@ -29,31 +30,31 @@ namespace OpenRA.Mods.RA class Contrail : ITick, IPostRender { - Turret contrailTurret = null; + ContrailInfo info; ContrailHistory history; - IFacing facing; - IMove move; + ILocalCoordinatesModel coords; public Contrail(Actor self, ContrailInfo info) { - contrailTurret = new Turret(info.ContrailOffset); + this.info = info; history = new ContrailHistory(info.TrailLength, info.UsePlayerColor ? ContrailHistory.ChooseColor(self) : info.Color); - facing = self.Trait(); - move = self.Trait(); + + coords = self.Trait(); } public void Tick(Actor self) { - history.Tick(self.CenterLocation - new PVecInt(0, move.Altitude) - (PVecInt)contrailTurret.PxPosition(self, facing).ToInt2()); + var local = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation)); + history.Tick(self.CenterPosition + coords.LocalToWorld(local)); } - public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(self); } + public void RenderAfterWorld(WorldRenderer wr, Actor self) { history.Render(wr, self); } } class ContrailHistory { - List positions = new List(); + List positions = new List(); readonly int TrailLength; readonly Color Color; readonly int StartSkip; @@ -74,27 +75,28 @@ namespace OpenRA.Mods.RA this.StartSkip = startSkip; } - public void Tick(PPos currentPos) + public void Tick(WPos currentPos) { positions.Add(currentPos); if (positions.Count >= TrailLength) positions.RemoveAt(0); } - public void Render(Actor self) + public void Render(WorldRenderer wr, Actor self) { Color trailStart = Color; Color trailEnd = Color.FromArgb(trailStart.A - 255 / TrailLength, trailStart.R, trailStart.G, trailStart.B); for (int i = positions.Count - 1 - StartSkip; i >= 4; --i) { - var conPos = PPos.Average(positions[i], positions[i-1], positions[i-2], positions[i-3]); - var nextPos = PPos.Average(positions[i-1], positions[i-2], positions[i-3], positions[i-4]); + // World positions + var conPos = WPos.Average(positions[i], positions[i-1], positions[i-2], positions[i-3]); + var nextPos = WPos.Average(positions[i-1], positions[i-2], positions[i-3], positions[i-4]); - if (self.World.RenderedShroud.IsVisible(conPos.ToCPos()) || - self.World.RenderedShroud.IsVisible(nextPos.ToCPos())) + if (self.World.RenderedShroud.IsVisible(new CPos(conPos)) || + self.World.RenderedShroud.IsVisible(new CPos(nextPos))) { - Game.Renderer.WorldLineRenderer.DrawLine(conPos.ToFloat2(), nextPos.ToFloat2(), trailStart, trailEnd); + Game.Renderer.WorldLineRenderer.DrawLine(wr.ScreenPosition(conPos), wr.ScreenPosition(nextPos), trailStart, trailEnd); trailStart = trailEnd; trailEnd = Color.FromArgb(trailStart.A - 255 / positions.Count, trailStart.R, trailStart.G, trailStart.B); diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 06047a09f9..f04ec2cecd 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA.Effects } if (Trail != null) - Trail.Tick(PxPosition - new PVecInt(0, Altitude)); + Trail.Tick(PxPosition.ToWPos(Altitude)); } void Explode(World world) @@ -163,7 +163,7 @@ namespace OpenRA.Mods.RA.Effects wr.Palette(Args.weapon.Underwater ? "shadow" : "effect"), PxPosition.Y); if (Trail != null) - Trail.Render(Args.firedBy); + Trail.Render(wr, Args.firedBy); } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 4ee2c5f1d8..cc99b3e14d 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -317,7 +317,6 @@ - @@ -423,6 +422,7 @@ + diff --git a/OpenRA.Mods.RA/Render/RenderBuildingSeparateTurret.cs b/OpenRA.Mods.RA/Render/RenderBuildingSeparateTurret.cs index 4266355f55..d8589ea50e 100644 --- a/OpenRA.Mods.RA/Render/RenderBuildingSeparateTurret.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingSeparateTurret.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Render anim.Play("turret"); anims.Add("turret_{0}".F(i++), new AnimationWithOffset(anim, - () => PPos.FromWPosHackZ(WPos.Zero + t.Position(self)).ToFloat2(), null)); + wr => wr.ScreenPxOffset(t.Position(self)), null)); } } } diff --git a/OpenRA.Mods.RA/Render/RenderUnitSpinner.cs b/OpenRA.Mods.RA/Render/RenderUnitSpinner.cs deleted file mode 100755 index 7089f599a3..0000000000 --- a/OpenRA.Mods.RA/Render/RenderUnitSpinner.cs +++ /dev/null @@ -1,41 +0,0 @@ -#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 OpenRA.Graphics; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA.Render -{ - class RenderUnitSpinnerInfo : RenderUnitInfo - { - public readonly int[] Offset = { 0, 0 }; - public override object Create(ActorInitializer init) { return new RenderUnitSpinner(init.self); } - } - - class RenderUnitSpinner : RenderUnit - { - public RenderUnitSpinner(Actor self) - : base(self) - { - var info = self.Info.Traits.Get(); - - var spinnerAnim = new Animation(GetImage(self)); - var facing = self.Trait(); - - spinnerAnim.PlayRepeating("spinner"); - - var turret = new Turret(info.Offset); - anims.Add("spinner", new AnimationWithOffset( - spinnerAnim, - () => turret.PxPosition(self, facing).ToFloat2(), - null ) { ZOffset = 1 } ); - } - } -} diff --git a/OpenRA.Mods.RA/Render/RenderUnitTurreted.cs b/OpenRA.Mods.RA/Render/RenderUnitTurreted.cs index 7bc2a6987c..740bf97075 100755 --- a/OpenRA.Mods.RA/Render/RenderUnitTurreted.cs +++ b/OpenRA.Mods.RA/Render/RenderUnitTurreted.cs @@ -37,11 +37,11 @@ namespace OpenRA.Mods.RA.Render anim.Play("turret"); anims.Add("turret_{0}".F(i++), new AnimationWithOffset(anim, - () => TurretPosition(self, turret, facing), null)); + wr => TurretPosition(self, wr, turret, facing), null)); } } - float2 TurretPosition(Actor self, Turreted t, IFacing facing) + float2 TurretPosition(Actor self, WorldRenderer wr, Turreted t, IFacing facing) { var recoil = self.TraitsImplementing() .Where(w => w.Info.Turret == t.Name) @@ -50,9 +50,9 @@ namespace OpenRA.Mods.RA.Render var localOffset = new WVec(-recoil, WRange.Zero, WRange.Zero); var bodyOrientation = QuantizeOrientation(self, self.Orientation); var turretOrientation = QuantizeOrientation(self, t.LocalOrientation(self)); - var worldPos = WPos.Zero + t.Position(self) + LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation)); + var worldPos = t.Position(self) + LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation)); - return PPos.FromWPosHackZ(worldPos).ToFloat2(); + return wr.ScreenPxOffset(worldPos); } } } diff --git a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs index eb917643d2..07282bfaf8 100644 --- a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Render muzzleFlashes.Add("muzzle{0}".F(muzzleFlashes.Count), new AnimationWithOffset( muzzleFlash, - () => PPos.FromWPosHackZ(WPos.Zero + a.MuzzleOffset(self, barrel)).ToFloat2(), + wr => wr.ScreenPxOffset(a.MuzzleOffset(self, barrel)), () => !isShowing)); } } @@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Render { foreach (var a in muzzleFlashes.Values) if (a.DisableFunc == null || !a.DisableFunc()) - yield return a.Image(self, wr.Palette("effect")); + yield return a.Image(self, wr, wr.Palette("effect")); } public void Tick(Actor self) diff --git a/OpenRA.Mods.RA/Render/WithRotor.cs b/OpenRA.Mods.RA/Render/WithRotor.cs index e394e6b884..7a5c6a0bb0 100755 --- a/OpenRA.Mods.RA/Render/WithRotor.cs +++ b/OpenRA.Mods.RA/Render/WithRotor.cs @@ -8,6 +8,7 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Traits; @@ -15,8 +16,10 @@ namespace OpenRA.Mods.RA.Render { public class WithRotorInfo : ITraitInfo, Requires { + [Desc("Position relative to body")] + public readonly WVec Offset = WVec.Zero; + public readonly string Id = "rotor"; - public readonly int[] Offset = { 0, 0 }; public object Create(ActorInitializer init) { return new WithRotor(init.self, this); } } @@ -26,14 +29,12 @@ namespace OpenRA.Mods.RA.Render public WithRotor(Actor self, WithRotorInfo info) { var rs = self.Trait(); - var facing = self.Trait(); rotorAnim = new Animation(rs.GetImage(self)); rotorAnim.PlayRepeating("rotor"); - var turret = new Turret(info.Offset); rs.anims.Add(info.Id, new AnimationWithOffset( rotorAnim, - () => turret.PxPosition(self, facing).ToFloat2(), + wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))), null ) { ZOffset = 1 } ); } diff --git a/OpenRA.Mods.RA/Render/WithSpinner.cs b/OpenRA.Mods.RA/Render/WithSpinner.cs new file mode 100755 index 0000000000..4b98452759 --- /dev/null +++ b/OpenRA.Mods.RA/Render/WithSpinner.cs @@ -0,0 +1,39 @@ +#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 OpenRA.FileFormats; +using OpenRA.Graphics; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Render +{ + class WithSpinnerInfo : ITraitInfo, Requires + { + public readonly string Name = "spinner"; + [Desc("Position relative to body")] + public readonly WVec Offset = WVec.Zero; + + public object Create(ActorInitializer init) { return new WithSpinner(init.self, this); } + } + + class WithSpinner + { + public WithSpinner(Actor self, WithSpinnerInfo info) + { + var rs = self.Trait(); + var spinner = new Animation(rs.GetImage(self)); + spinner.PlayRepeating("spinner"); + rs.anims.Add(info.Name, new AnimationWithOffset( + spinner, + wr => wr.ScreenPxOffset(rs.LocalToWorld(info.Offset.Rotate(rs.QuantizeOrientation(self, self.Orientation)))), + null ) { ZOffset = 1 } ); + } + } +} diff --git a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs index 9e2dd66a21..229b329f59 100644 --- a/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs +++ b/OpenRA.Mods.RA/SmokeTrailWhenDamaged.cs @@ -8,14 +8,16 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Mods.RA.Effects; using OpenRA.Traits; namespace OpenRA.Mods.RA { - class SmokeTrailWhenDamagedInfo : ITraitInfo + class SmokeTrailWhenDamagedInfo : ITraitInfo, Requires { - public readonly int[] Offset = { 0, 0 }; + [Desc("Position relative to body")] + public readonly WVec Offset = WVec.Zero; public readonly int Interval = 3; public object Create(ActorInitializer init) { return new SmokeTrailWhenDamaged(init.self, this); } @@ -23,34 +25,30 @@ namespace OpenRA.Mods.RA class SmokeTrailWhenDamaged : ITick { - Turret smokeTurret; - PPos position; - int interval; + ILocalCoordinatesModel coords; + SmokeTrailWhenDamagedInfo info; int ticks; public SmokeTrailWhenDamaged(Actor self, SmokeTrailWhenDamagedInfo info) { - smokeTurret = new Turret(info.Offset); - interval = info.Interval; + this.info = info; + coords = self.Trait(); } public void Tick(Actor self) { if (--ticks <= 0) { - var move = self.Trait(); - if (move.Altitude > 0 && self.GetDamageState() >= DamageState.Heavy) + var position = self.CenterPosition; + if (position.Z > 0 && self.GetDamageState() >= DamageState.Heavy && + self.World.RenderedShroud.IsVisible(new CPos(position))) { - var facing = self.Trait(); - var altitude = new PVecInt(0, move.Altitude); - position = (self.CenterLocation - (PVecInt)smokeTurret.PxPosition(self, facing).ToInt2()); - - if (self.World.RenderedShroud.IsVisible(position.ToCPos())) - self.World.AddFrameEndTask( - w => w.Add(new Smoke(w, position - altitude, "smokey"))); + var offset = info.Offset.Rotate(coords.QuantizeOrientation(self, self.Orientation)); + var pos = PPos.FromWPosHackZ(position + coords.LocalToWorld(offset)); + self.World.AddFrameEndTask(w => w.Add(new Smoke(w, pos, "smokey"))); } - ticks = interval; + ticks = info.Interval; } } } diff --git a/OpenRA.Mods.RA/ThrowsParticle.cs b/OpenRA.Mods.RA/ThrowsParticle.cs index 3ce1f252f3..55dca13b3f 100644 --- a/OpenRA.Mods.RA/ThrowsParticle.cs +++ b/OpenRA.Mods.RA/ThrowsParticle.cs @@ -8,19 +8,30 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Mods.RA.Render; using OpenRA.Traits; namespace OpenRA.Mods.RA { - class ThrowsParticleInfo : ITraitInfo, Requires + class ThrowsParticleInfo : ITraitInfo, Requires { public readonly string Anim = null; - public readonly int[] Offset = new[] { 0, 0, 0, 0 }; - public readonly int[] Spread = new[] { 0, 0 }; - public readonly float Speed = 20; - public readonly string AnimKey = null; + + [Desc("Initial position relative to body")] + public readonly WVec Offset = WVec.Zero; + + [Desc("Maximum distance to throw the particle")] + public readonly WRange ThrowRange = new WRange(768); + + [Desc("Maximum height to throw the particle")] + public readonly WRange ThrowHeight = new WRange(256); + + [Desc("Number of ticks to animate")] + public readonly int Length = 15; + + [Desc("Maximum rotation rate")] public readonly float ROT = 15; public object Create(ActorInitializer init) { return new ThrowsParticle(init, this); } @@ -28,51 +39,56 @@ namespace OpenRA.Mods.RA class ThrowsParticle : ITick { - float2 pos; - float alt; + ThrowsParticleInfo info; + WVec pos; + WVec initialPos; + WVec finalPos; + int tick = 0; - float2 v; - float va; float facing; - float dfacing; - - const float gravity = 1.3f; + float rotation; public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info) { + this.info = info; + var self = init.self; - var ifacing = self.Trait(); - var ru = self.Trait(); + var rs = self.Trait(); - alt = 0; - facing = Turreted.GetInitialTurretFacing( init, 0 ); - pos = new Turret(info.Offset).PxPosition(self, ifacing).ToFloat2(); + // TODO: Carry orientation over from the parent instead of just facing + var bodyFacing = init.Contains() ? init.Get() : 0; + facing = Turreted.GetInitialTurretFacing(init, 0); - v = Game.CosmeticRandom.Gauss2D(1) * info.Spread.RelOffset(); - dfacing = Game.CosmeticRandom.Gauss1D(2) * info.ROT; - va = info.Speed; + // Calculate final position + var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); + var throwOffset = new WVec((int)(Game.CosmeticRandom.Gauss1D(1)*info.ThrowRange.Range), 0, 0).Rotate(throwRotation); - var anim = new Animation(ru.GetImage(self), () => (int)facing); + initialPos = pos = info.Offset.Rotate(rs.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); + finalPos = initialPos + throwOffset; + + // Facing rotation + rotation = Game.CosmeticRandom.Gauss1D(2) * info.ROT; + + var anim = new Animation(rs.GetImage(self), () => (int)facing); anim.PlayRepeating(info.Anim); - - ru.anims.Add(info.AnimKey, new AnimationWithOffset( - anim, () => pos - new float2(0, alt), null)); + rs.anims.Add(info.Anim, new AnimationWithOffset(anim, wr => wr.ScreenPxOffset(pos), null)); } public void Tick(Actor self) { - va -= gravity; - alt += va; + if (tick == info.Length) + return; + tick++; - if (alt < 0) alt = 0; - else - { - pos += v; - v = .9f * v; + // Lerp position horizontally and height along a sinusoid using a cubic ease + var t = (tick*tick*tick / (info.Length*info.Length) - 3*tick*tick / info.Length + 3*tick); + var tp = WVec.Lerp(initialPos, finalPos, t, info.Length); + var th = new WAngle(512*(info.Length - t) / info.Length).Sin()*info.ThrowHeight.Range / 1024; + pos = new WVec(tp.X, tp.Y, th); - facing += dfacing; - dfacing *= .9f; - } + // Spin the particle + facing += rotation; + rotation *= .9f; } } } diff --git a/OpenRA.Mods.RA/Turreted.cs b/OpenRA.Mods.RA/Turreted.cs index 37fdfa225d..0040377b81 100755 --- a/OpenRA.Mods.RA/Turreted.cs +++ b/OpenRA.Mods.RA/Turreted.cs @@ -95,31 +95,4 @@ namespace OpenRA.Mods.RA return WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw); } } - - // TODO: Remove this - public class Turret - { - public PVecInt UnitSpacePosition; // where, in the unit's local space. - public PVecInt ScreenSpacePosition; // screen-space hack to make things line up good. - - public Turret(int[] offset) - { - ScreenSpacePosition = (PVecInt) offset.AbsOffset().ToInt2(); - UnitSpacePosition = (PVecInt) offset.RelOffset().ToInt2(); - } - - public PVecFloat PxPosition(Actor self, IFacing facing) - { - // Things that don't have a rotating base don't need the turrets repositioned - if (facing == null) return ScreenSpacePosition; - - var ru = self.TraitOrDefault(); - var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8; - var bodyFacing = facing.Facing; - var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs); - - return (PVecFloat)Util.RotateVectorByFacing(UnitSpacePosition.ToFloat2(), quantizedFacing, .7f) - + (PVecFloat)ScreenSpacePosition.ToFloat2(); - } - } } diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 636567268a..214fd63310 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -28,10 +28,10 @@ TRAN: Range: 8 RenderUnit: WithRotor@PRIMARY: - Offset: 0,14,0,-4 + Offset: -597,0,171 WithRotor@SECONDARY: Id: rotor_2 - Offset: 0,-14,0,-2 + Offset: 597,0,85 WithShadow: Cargo: Types: Infantry @@ -84,7 +84,7 @@ HELI: Period: 200 RenderUnit: WithRotor: - Offset: 0,0,0,-2 + Offset: 0,0,85 WithMuzzleFlash: WithShadow: FallsToEarth: diff --git a/mods/cnc/rules/husks.yaml b/mods/cnc/rules/husks.yaml index 96bb6deb75..735d2a3f57 100644 --- a/mods/cnc/rules/husks.yaml +++ b/mods/cnc/rules/husks.yaml @@ -73,9 +73,6 @@ LTNK.Husk: Image: ltnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret MTNK.Husk: Inherits: ^Husk @@ -86,9 +83,6 @@ MTNK.Husk: Image: mtnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret HTNK.Husk: Inherits: ^Husk @@ -99,9 +93,6 @@ HTNK.Husk: Image: htnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret MSAM.Husk: Inherits: ^Husk @@ -112,9 +103,6 @@ MSAM.Husk: Image: msam ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret MLRS.Husk: Inherits: ^Husk @@ -125,9 +113,6 @@ MLRS.Husk: Image: mlrs ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret STNK.Husk: Inherits: ^Husk diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index 8bca62df6b..faa5695aa7 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -564,8 +564,9 @@ MHQ: Speed: 6 RevealsShroud: Range: 6 - RenderUnitSpinner: - Offset: 0,6 + RenderUnit: + WithSpinner: + Offset: -256,0,256 AttackMove: JustMove: yes Explodes: diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index f18270eaa9..2fc86dc6a6 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -21,10 +21,10 @@ RearmBuildings: starporta,starporto,starporth MinimalLandAltitude: 25 SmokeTrailWhenDamaged@0: - Offset: 15, -12 + Offset: -512,640,0 Interval: 3 SmokeTrailWhenDamaged@1: - Offset: -15, -12 + Offset: -512,-640,0 Interval: 3 RenderUnit: RenderCargo: @@ -103,7 +103,7 @@ ORNI: Moves: yes Explosion: UnitExplodeScale SmokeTrailWhenDamaged: - Offset: 0,-10 + Offset: -427,0,0 ORNI.bomber: CarpetBomb: @@ -133,7 +133,7 @@ ORNI.bomber: Moves: yes Explosion: UnitExplodeScale SmokeTrailWhenDamaged: - Offset: 0,-10 + Offset: -427,0,0 CARRYALL.infantry: ParaDrop: @@ -149,10 +149,10 @@ CARRYALL.infantry: RepairBuildings: repair RearmBuildings: starporta,starporto,starporth SmokeTrailWhenDamaged@0: - Offset: 15, -12 + Offset: -512,540,0 Interval: 3 SmokeTrailWhenDamaged@1: - Offset: -15, -12 + Offset: -512,-640,0 Interval: 3 RenderUnit: Image: carryall diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index b74d92d3d6..124edae33b 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -498,9 +498,6 @@ GUNTOWER.Husk: Image: GUNTOWER ThrowsParticle@turret: Anim: turret - Spread: 4,4 - Speed: 6 - AnimKey: turret ROCKETTOWER: Inherits: ^Building @@ -559,9 +556,6 @@ ROCKETTOWER.Husk: Image: ROCKETTOWER ThrowsParticle@turret: Anim: turret - Spread: 4,4 - Speed: 6 - AnimKey: turret REPAIR: Inherits: ^Building diff --git a/mods/d2k/rules/vehicles.yaml b/mods/d2k/rules/vehicles.yaml index 16b3f88db0..9a63161572 100644 --- a/mods/d2k/rules/vehicles.yaml +++ b/mods/d2k/rules/vehicles.yaml @@ -242,9 +242,6 @@ QUAD.starport: HP: 100 ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret SIEGETANK: Inherits: ^Tank @@ -299,9 +296,6 @@ SIEGETANK.Husk: Icon: siegetankicon ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret RenderUnit: Image: SIEGETANK diff --git a/mods/ra-classic/rules/aircraft.yaml b/mods/ra-classic/rules/aircraft.yaml index 8c96099d29..ad2745911e 100644 --- a/mods/ra-classic/rules/aircraft.yaml +++ b/mods/ra-classic/rules/aircraft.yaml @@ -187,10 +187,10 @@ TRAN: LandableTerrainTypes: Clear,Rough,Road,Ore,Beach RenderUnit: WithRotor@PRIMARY: - Offset: 0,14,0,-8 + Offset: -597,0,341 WithRotor@SECONDARY: Id: rotor_2 - Offset: 0,-14,0,-5 + Offset: 597,0,213 WithShadow: Cargo: Types: Infantry @@ -232,7 +232,7 @@ HELI: Speed: 16 RenderUnit: WithRotor: - Offset: 0,0,0,-2 + Offset: 0,0,85 WithShadow: LimitedAmmo: Ammo: 6 diff --git a/mods/ra/maps/monster-tank-madness/map.yaml b/mods/ra/maps/monster-tank-madness/map.yaml index d63881610b..c9892bffa0 100644 --- a/mods/ra/maps/monster-tank-madness/map.yaml +++ b/mods/ra/maps/monster-tank-madness/map.yaml @@ -2602,9 +2602,6 @@ Rules: Image: 4TNK ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret Health: HP: 2000 SILO: diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index 9c43313241..d810f29d74 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -20,18 +20,18 @@ BADR: Tooltip: Name: Badger Contrail@1: - ContrailOffset: 11, -11 + Offset: -469,469,0 Contrail@2: - ContrailOffset: -11, -11 + Offset: -469,-469,0 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode SmokeTrailWhenDamaged@0: - Offset: 11, -11 + Offset: -469,469,0 Interval: 2 SmokeTrailWhenDamaged@1: - Offset: -11, -11 + Offset: -469,-469,0 Interval: 2 -EjectOnDeath: -GpsDot: @@ -59,18 +59,18 @@ BADR.bomber: Tooltip: Name: Badger Contrail@1: - ContrailOffset: 11, -11 + Offset: 469,469,0 Contrail@2: - ContrailOffset: -11, -11 + Offset: 469,-469,0 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode SmokeTrailWhenDamaged@0: - Offset: 11, -11 + Offset: -469,469,0 Interval: 2 SmokeTrailWhenDamaged@1: - Offset: -11, -11 + Offset: -469,-469,0 Interval: 2 -EjectOnDeath: -GpsDot: @@ -107,6 +107,7 @@ MIG: Speed: 20 RearmBuildings: afld RenderUnit: + CameraPitch: 99 WithShadow: LimitedAmmo: Ammo: 8 @@ -115,15 +116,15 @@ MIG: Selectable: Bounds: 44,40,0,0 Contrail@1: - ContrailOffset: 16,-14 + Offset: -598,-683,0 Contrail@2: - ContrailOffset: -16,-14 + Offset: -598,683,0 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode SmokeTrailWhenDamaged: - Offset: 0,-20,0,-4 + Offset: -853,0,171 Interval: 2 YAK: @@ -160,6 +161,7 @@ YAK: ROT: 5 Speed: 16 RenderUnit: + CameraPitch: 99 WithShadow: LimitedAmmo: Ammo: 18 @@ -169,13 +171,13 @@ YAK: ReturnOnIdle: WithMuzzleFlash: Contrail: - ContrailOffset: 0, -20 + Offset: -853,0,0 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode SmokeTrailWhenDamaged: - Offset: 0, -20 + Offset: -853,0,0 Interval: 2 @@ -207,10 +209,10 @@ TRAN: LandableTerrainTypes: Clear,Rough,Road,Ore,Beach RenderUnit: WithRotor@PRIMARY: - Offset: 0,14,0,-8 + Offset: -597,0,341 WithRotor@SECONDARY: Id: rotor_2 - Offset: 0,-14,0,-5 + Offset: 597,0,213 WithShadow: Cargo: Types: Infantry @@ -270,7 +272,7 @@ HELI: Speed: 16 RenderUnit: WithRotor: - Offset: 0,0,0,-2 + Offset: 0,0,85 WithShadow: LimitedAmmo: Ammo: 8 @@ -278,7 +280,7 @@ HELI: FallsToEarth: Explosion: UnitExplode SmokeTrailWhenDamaged: - Offset: 0,-10 + Offset: -427,0,0 HIND: Inherits: ^Helicopter @@ -328,7 +330,7 @@ HIND: FallsToEarth: Explosion: UnitExplode SmokeTrailWhenDamaged: - Offset: 0,-10 + Offset: -427,0,0 U2: Inherits: ^Plane @@ -345,13 +347,13 @@ U2: -Selectable: -GainsExperience: Contrail@1: - ContrailOffset: 16, -17 + Offset: -725,683,0 Contrail@2: - ContrailOffset: -16, -17 + Offset: -725,-683,0 FallsToEarth: Spins: no Moves: yes Explosion: UnitExplode SmokeTrailWhenDamaged: - Offset: 0,-25 + Offset: -1c43,0,0 Interval: 2 \ No newline at end of file diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index 266fe43b34..40ec8702e7 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -501,8 +501,9 @@ MGG: Speed: 6 RevealsShroud: Range: 6 - RenderUnitSpinner: - Offset: 0,6 + RenderUnit: + WithSpinner: + Offset: -299,0,171 AttackMove: JustMove: yes CreatesShroud: @@ -522,10 +523,7 @@ MGG.Husk: Image: mgg ThrowsParticle@spinner: Anim: spinner-idle - Spread: 3,3 - Speed: 6 - AnimKey: spinner-idle - Offset: 0,6 + Offset: -299,0,171 MRJ: Inherits: ^Vehicle @@ -546,8 +544,9 @@ MRJ: Speed: 6 RevealsShroud: Range: 6 - RenderUnitSpinner: - Offset: 0,6 + RenderUnit: + WithSpinner: + Offset: -256,0,256 AttackMove: JustMove: yes Explodes: @@ -562,9 +561,6 @@ MRJ: Image: 1tnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret 2TNK.Husk: Inherits: ^Husk @@ -574,9 +570,6 @@ MRJ: Image: 2tnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret 3TNK.Husk: Inherits: ^Husk @@ -586,9 +579,6 @@ MRJ: Image: 3tnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret 4TNK.Husk: Inherits: ^Husk @@ -598,9 +588,6 @@ MRJ: Image: 4tnk ThrowsParticle@turret: Anim: turret - Spread: 3,3 - Speed: 6 - AnimKey: turret HARV.FullHusk: Inherits: ^Husk @@ -649,7 +636,8 @@ TTNK: Weapon: TTankZap LocalOffset: 0,0,213 AttackFrontal: - RenderUnitSpinner: + RenderUnit: + WithSpinner: Selectable: Bounds: 28,28,0,0 AutoTarget: