diff --git a/OpenRA.Game/Graphics/Animation.cs b/OpenRA.Game/Graphics/Animation.cs index 620e557888..dd2354ceb9 100644 --- a/OpenRA.Game/Graphics/Animation.cs +++ b/OpenRA.Game/Graphics/Animation.cs @@ -38,20 +38,20 @@ namespace OpenRA.Graphics int CurrentFrame { get { return backwards ? CurrentSequence.Start + CurrentSequence.Length - frame - 1 : frame; } } public Sprite Image { get { return CurrentSequence.GetSprite(CurrentFrame, facingFunc()); } } - public IEnumerable Render(WPos pos, int zOffset, PaletteReference palette, float scale) + public IEnumerable Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale) { if (CurrentSequence.ShadowStart >= 0) { var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc()); - yield return new SpriteRenderable(shadow, pos, CurrentSequence.ShadowZOffset + zOffset, palette, scale); + yield return new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale); } - yield return new SpriteRenderable(Image, pos, CurrentSequence.ZOffset + zOffset, palette, scale); + yield return new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale); } public IEnumerable Render(WPos pos, PaletteReference palette) { - return Render(pos, 0, palette, 1f); + return Render(pos, WVec.Zero, 0, palette, 1f); } public void Play(string sequenceName) diff --git a/OpenRA.Game/Graphics/AnimationWithOffset.cs b/OpenRA.Game/Graphics/AnimationWithOffset.cs index cc9ce31334..38ee527a4a 100644 --- a/OpenRA.Game/Graphics/AnimationWithOffset.cs +++ b/OpenRA.Game/Graphics/AnimationWithOffset.cs @@ -37,12 +37,11 @@ namespace OpenRA.Graphics public IEnumerable Render(Actor self, WorldRenderer wr, PaletteReference pal, float scale) { - var p = self.CenterPosition; - if (OffsetFunc != null) - p += OffsetFunc(); + var center = self.CenterPosition; + var offset = OffsetFunc != null ? OffsetFunc() : WVec.Zero; - var z = (ZOffset != null) ? ZOffset(p) : 0; - return Animation.Render(p, z, pal, scale); + var z = (ZOffset != null) ? ZOffset(center + offset) : 0; + return Animation.Render(center, offset, z, pal, scale); } public static implicit operator AnimationWithOffset(Animation a) diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index 923385a473..13e48737e2 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -52,42 +52,52 @@ namespace OpenRA.Graphics readonly Sprite sprite; readonly WPos pos; + readonly WVec offset; readonly int zOffset; readonly PaletteReference palette; readonly float scale; - public SpriteRenderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale) + public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale) { this.sprite = sprite; this.pos = pos; + this.offset = offset; this.zOffset = zOffset; this.palette = palette; this.scale = scale; } + public SpriteRenderable(Sprite sprite, WPos pos, int zOffset, PaletteReference palette, float scale) + : this(sprite, pos, WVec.Zero, zOffset, palette, scale) { } + // Provided for legacy support only - Don't use for new things! public SpriteRenderable(Sprite sprite, float2 pos, PaletteReference palette, int z) : this(sprite, new PPos((int)pos.X, (int)pos.Y).ToWPos(0), z, palette, 1f) { } - public WPos Pos { get { return pos; } } + public WPos Pos { get { return pos + offset; } } public float Scale { get { return scale; } } public PaletteReference Palette { get { return palette; } } public int ZOffset { get { return zOffset; } } - public IRenderable WithScale(float newScale) { return new SpriteRenderable(sprite, pos, zOffset, palette, newScale); } - public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, zOffset, newPalette, scale); } - public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, newOffset, palette, scale); } - public IRenderable WithPos(WPos pos) { return new SpriteRenderable(sprite, pos, zOffset, palette, scale); } + public IRenderable WithScale(float newScale) { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, newScale); } + public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale); } + public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale); } + public IRenderable WithPos(WPos pos) { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale); } + + float2 ScreenPosition(WorldRenderer wr) + { + return wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f*scale*sprite.size).ToInt2(); + } public void BeforeRender(WorldRenderer wr) {} public void Render(WorldRenderer wr) { - sprite.DrawAt(wr.ScreenPxPosition(pos) - (0.5f*scale*sprite.size).ToInt2(), palette, scale); + sprite.DrawAt(ScreenPosition(wr), palette, scale); } public void RenderDebugGeometry(WorldRenderer wr) { - var offset = wr.ScreenPxPosition(pos) - 0.5f*scale*sprite.size + sprite.offset; + var offset = ScreenPosition(wr) + sprite.offset; Game.Renderer.WorldLineRenderer.DrawRect(offset, offset + sprite.size, Color.Red); } } diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index d01d7e963c..dff248e944 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -245,6 +245,13 @@ namespace OpenRA.Graphics return new float[] {c*vec.X, c*vec.Y, c*vec.Z, 1}; } + public int2 ScreenPxOffset(WVec vec) + { + // Round to nearest pixel + var px = ScreenVector(vec); + return new int2((int)Math.Round(px[0]), (int)Math.Round(px[1] - px[2])); + } + public float ScreenZPosition(WPos pos, int zOffset) { return (pos.Y + pos.Z + zOffset)*Game.CellSize/1024f; } } } diff --git a/OpenRA.Mods.RA/Effects/Parachute.cs b/OpenRA.Mods.RA/Effects/Parachute.cs index 8ebbf056e1..e705d939e5 100644 --- a/OpenRA.Mods.RA/Effects/Parachute.cs +++ b/OpenRA.Mods.RA/Effects/Parachute.cs @@ -76,7 +76,7 @@ namespace OpenRA.Mods.RA.Effects yield return c.WithPos(pos); } - foreach (var r in paraAnim.Render(pos + parachuteOffset, 1, rc.First().Palette, 1f)) + foreach (var r in paraAnim.Render(pos, parachuteOffset, 1, rc.First().Palette, 1f)) yield return r; } }