diff --git a/OpenRA.Game/Effects/SpriteEffect.cs b/OpenRA.Game/Effects/SpriteEffect.cs index 838f470c4c..c415dfab19 100644 --- a/OpenRA.Game/Effects/SpriteEffect.cs +++ b/OpenRA.Game/Effects/SpriteEffect.cs @@ -18,11 +18,13 @@ namespace OpenRA.Effects readonly string palette; readonly Animation anim; readonly WPos pos; + readonly bool scaleSizeWithZoom; - public SpriteEffect(WPos pos, World world, string image, string palette) + public SpriteEffect(WPos pos, World world, string image, string palette, bool scaleSizeWithZoom = false) { this.pos = pos; this.palette = palette; + this.scaleSizeWithZoom = scaleSizeWithZoom; anim = new Animation(world, image); anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this))); } @@ -34,7 +36,8 @@ namespace OpenRA.Effects public IEnumerable Render(WorldRenderer wr) { - return anim.Render(pos, WVec.Zero, 0, wr.Palette(palette), 1f / wr.Viewport.Zoom); + var zoom = scaleSizeWithZoom ? 1f / wr.Viewport.Zoom : 1f; + return anim.Render(pos, WVec.Zero, 0, wr.Palette(palette), zoom); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index b2bfeb835f..232b4cdbe4 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -214,7 +214,7 @@ namespace OpenRA.Widgets else if (o.TargetLocation != CPos.Zero) { var pos = world.Map.CenterOfCell(cell); - world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, world, "moveflsh", "moveflash"))); + world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, world, "moveflsh", "moveflash", true))); flashed = true; } } diff --git a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs index cb5f87a67d..6ca9e85c01 100644 --- a/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs +++ b/OpenRA.Mods.Common/Traits/Render/LeavesTrails.cs @@ -15,6 +15,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { + public enum TrailType { Cell, CenterPosition } + [Desc("Renders a sprite effect when leaving a cell.")] public class LeavesTrailsInfo : ITraitInfo { @@ -24,6 +26,22 @@ namespace OpenRA.Mods.Common.Traits [Desc("Only do so when the terrain types match with the previous cell.")] public readonly HashSet TerrainTypes = new HashSet(); + [Desc("Accepts values: Cell to draw the trail sprite in the center of the current cell,", + "CenterPosition to draw the trail sprite at the current position.")] + public readonly TrailType Type = TrailType.Cell; + + [Desc("Display a trail while stationary.")] + public readonly bool TrailWhileStationary = false; + + [Desc("Delay between trail updates when stationary.")] + public readonly int StationaryInterval = 0; + + [Desc("Display a trail while moving.")] + public readonly bool TrailWhileMoving = true; + + [Desc("Delay between trail updates when moving.")] + public readonly int MovingInterval = 0; + public object Create(ActorInitializer init) { return new LeavesTrails(this, init.Self); } } @@ -36,18 +54,30 @@ namespace OpenRA.Mods.Common.Traits this.info = info; } - CPos cachedLocation; + WPos cachedPosition; + int ticks; public void Tick(Actor self) { - if (cachedLocation != self.Location) + var isMoving = self.CenterPosition != cachedPosition; + if ((isMoving && !info.TrailWhileMoving) || (!isMoving && !info.TrailWhileStationary)) + return; + + var interval = isMoving ? info.MovingInterval : + info.StationaryInterval; + if (++ticks >= interval) { - var type = self.World.Map.GetTerrainInfo(cachedLocation).Type; - var pos = self.World.Map.CenterOfCell(cachedLocation); + var cachedCell = self.World.Map.CellContaining(cachedPosition); + var type = self.World.Map.GetTerrainInfo(cachedCell).Type; + + var pos = info.Type == TrailType.CenterPosition ? cachedPosition : + self.World.Map.CenterOfCell(cachedCell); + if (info.TerrainTypes.Contains(type) && !string.IsNullOrEmpty(info.Image)) self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, self.World, info.Image, info.Palette))); - cachedLocation = self.Location; + cachedPosition = self.CenterPosition; + ticks = 0; } } } diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index cc4f286fe3..3906299bad 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -34,6 +34,8 @@ APC: Image: wake Palette: effect TerrainTypes: Water + StationaryInterval: 18 + MovingInterval: 6 HVR: Inherits: ^VoxelVehicle @@ -79,6 +81,9 @@ HVR: Image: wake Palette: effect TerrainTypes: Water + TrailWhileStationary: True + StationaryInterval: 18 + MovingInterval: 6 SMECH: Inherits: ^Tank diff --git a/mods/ts/sequences/misc.yaml b/mods/ts/sequences/misc.yaml index be61b599be..8879f3befc 100644 --- a/mods/ts/sequences/misc.yaml +++ b/mods/ts/sequences/misc.yaml @@ -266,7 +266,7 @@ wake: idle: wake2 Length: * Tick: 180 - ZOffset: 2047 + ZOffset: -512 resources: Defaults: