diff --git a/CHANGELOG b/CHANGELOG index 0036268815..6fd3188230 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ NEW: Fixed base attack notification playing when allied engineers repaired your buildings. Improved the ingame chat interface and input, with it defaulting to Team Chat. Redesigned the settings panel. + Re-added move flashes. Red Alert: Added MAD Tank. Fixed a crash in Monster Tank Madness. diff --git a/OpenRA.Game/Effects/MoveFlash.cs b/OpenRA.Game/Effects/MoveFlash.cs new file mode 100644 index 0000000000..762ce5106c --- /dev/null +++ b/OpenRA.Game/Effects/MoveFlash.cs @@ -0,0 +1,41 @@ +#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 + * 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.Collections.Generic; +using OpenRA.Effects; +using OpenRA.FileFormats; +using OpenRA.Graphics; +using OpenRA.Traits; + +namespace OpenRA.Effects +{ + public class MoveFlash : IEffect + { + Animation anim; + WPos pos; + + public MoveFlash(WPos pos, World world) + { + this.pos = pos; + anim = new Animation("moveflsh"); + anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this))); + } + + public void Tick(World world) + { + anim.Tick(); + } + + public IEnumerable Render(WorldRenderer wr) + { + return anim.Render(pos, WVec.Zero, 0, wr.Palette("moveflash"), 1f / wr.Viewport.Zoom); + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index e679a99d7b..d2625dfbd6 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -94,11 +94,6 @@ namespace OpenRA.Graphics Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1; } - public CPos ViewToWorld(int2 view) - { - return worldRenderer.Position(ViewToWorldPx(view)).ToCPos(); - } - public int2 ViewToWorldPx(int2 view) { return (1f / Zoom * view.ToFloat2()).ToInt2() + TopLeft; } public int2 WorldToViewPx(int2 world) { return (Zoom * (world - TopLeft).ToFloat2()).ToInt2(); } diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 108f137b14..4830545e52 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -236,6 +236,7 @@ + diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index 4613ee6dff..da741d7a87 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -41,16 +41,15 @@ namespace OpenRA.Orders .Where(o => o != null) .ToArray(); - var actorsInvolved = orders.Select(o => o.self).Distinct(); + var actorsInvolved = orders.Select(o => o.Actor).Distinct(); if (actorsInvolved.Any()) yield return new Order("CreateGroup", actorsInvolved.First().Owner.PlayerActor, false) { TargetString = actorsInvolved.Select(a => a.ActorID).JoinWith(",") }; - foreach (var o in orders) - yield return CheckSameOrder(o.iot, o.trait.IssueOrder(o.self, o.iot, o.target, mi.Modifiers.HasModifier(Modifiers.Shift))); + yield return CheckSameOrder(o.Order, o.Trait.IssueOrder(o.Actor, o.Order, o.Target, mi.Modifiers.HasModifier(Modifiers.Shift))); } public void Tick(World world) { } @@ -89,7 +88,7 @@ namespace OpenRA.Orders .Where(o => o != null) .ToArray(); - var cursorName = orders.Select(o => o.cursor).FirstOrDefault(); + var cursorName = orders.Select(o => o.Cursor).FirstOrDefault(); return cursorName ?? (useSelect ? "select" : "default"); } @@ -103,9 +102,9 @@ namespace OpenRA.Orders if (mi.Button == Game.mouseButtonPreference.Action) { - foreach( var o in self.TraitsImplementing() + foreach (var o in self.TraitsImplementing() .SelectMany(trait => trait.Orders - .Select(x => new { Trait = trait, Order = x } )) + .Select(x => new { Trait = trait, Order = x })) .OrderByDescending(x => x.Order.OrderPriority)) { var actorsAt = self.World.ActorMap.GetUnitsAt(target.CenterPosition.ToCPos()).ToList(); @@ -138,19 +137,19 @@ namespace OpenRA.Orders class UnitOrderResult { - public readonly Actor self; - public readonly IOrderTargeter iot; - public readonly IIssueOrder trait; - public readonly string cursor; - public readonly Target target; + public readonly Actor Actor; + public readonly IOrderTargeter Order; + public readonly IIssueOrder Trait; + public readonly string Cursor; + public readonly Target Target; - public UnitOrderResult(Actor self, IOrderTargeter iot, IIssueOrder trait, string cursor, Target target) + public UnitOrderResult(Actor actor, IOrderTargeter order, IIssueOrder trait, string cursor, Target target) { - this.self = self; - this.iot = iot; - this.trait = trait; - this.cursor = cursor; - this.target = target; + this.Actor = actor; + this.Order = order; + this.Trait = trait; + this.Cursor = cursor; + this.Target = target; } } } diff --git a/OpenRA.Game/Traits/DrawLineToTarget.cs b/OpenRA.Game/Traits/DrawLineToTarget.cs index 2fa04f64f1..da846940dc 100644 --- a/OpenRA.Game/Traits/DrawLineToTarget.cs +++ b/OpenRA.Game/Traits/DrawLineToTarget.cs @@ -97,9 +97,6 @@ namespace OpenRA.Traits if (self.Destroyed) return; - if (target.Type == TargetType.Actor && display) - w.Add(new FlashTarget(target.Actor)); - var line = self.TraitOrDefault(); if (line != null) line.SetTarget(self, target, color, display); diff --git a/OpenRA.Game/Widgets/ViewportControllerWidget.cs b/OpenRA.Game/Widgets/ViewportControllerWidget.cs index b5ad7128ed..65d4fafaf1 100644 --- a/OpenRA.Game/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Game/Widgets/ViewportControllerWidget.cs @@ -95,7 +95,7 @@ namespace OpenRA.Widgets public void UpdateMouseover() { TooltipType = WorldTooltipType.None; - var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); + var cell = worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); if (!world.Map.IsInMap(cell)) return; diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index 27fb1e0b60..b68ea43e1b 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using OpenRA.Effects; using OpenRA.FileFormats; using OpenRA.Graphics; using OpenRA.Orders; @@ -21,14 +22,16 @@ namespace OpenRA.Widgets { public class WorldInteractionControllerWidget : Widget { - protected readonly World world; + static readonly Actor[] NoActors = { }; + + protected readonly World World; readonly WorldRenderer worldRenderer; int2 dragStart, dragEnd; [ObjectCreator.UseCtor] public WorldInteractionControllerWidget(World world, WorldRenderer worldRenderer) { - this.world = world; + this.World = world; this.worldRenderer = worldRenderer; } @@ -37,14 +40,14 @@ namespace OpenRA.Widgets var selbox = SelectionBox; if (selbox == null) { - foreach (var u in SelectActorsInBox(world, dragStart, dragStart, _ => true)) + foreach (var u in SelectActorsInBox(World, dragStart, dragStart, _ => true)) worldRenderer.DrawRollover(u); return; } Game.Renderer.WorldLineRenderer.DrawRect(selbox.Value.First.ToFloat2(), selbox.Value.Second.ToFloat2(), Color.White); - foreach (var u in SelectActorsInBox(world, selbox.Value.First, selbox.Value.Second, _ => true)) + foreach (var u in SelectActorsInBox(World, selbox.Value.First, selbox.Value.Second, _ => true)) worldRenderer.DrawRollover(u); } @@ -52,76 +55,75 @@ namespace OpenRA.Widgets { var xy = worldRenderer.Viewport.ViewToWorldPx(mi.Location); - var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; + var useClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; - var HasBox = (SelectionBox != null) ? true : false; - var MultiClick = (mi.MultiTapCount >= 2) ? true : false; + var hasBox = (SelectionBox != null) ? true : false; + var multiClick = (mi.MultiTapCount >= 2) ? true : false; if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeMouseFocus(mi)) return false; - + dragStart = dragEnd = xy; - //place buildings - if (!UseClassicMouseStyle || (UseClassicMouseStyle && !world.Selection.Actors.Any()) ) - ApplyOrders(world, xy, mi); + // place buildings + if (!useClassicMouseStyle || (useClassicMouseStyle && !World.Selection.Actors.Any())) + ApplyOrders(World, xy, mi); } - + if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move) dragEnd = xy; if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { - if (UseClassicMouseStyle && HasMouseFocus) + if (useClassicMouseStyle && HasMouseFocus) { - //order units around - if (!HasBox && world.Selection.Actors.Any() && !MultiClick) + // order units around + if (!hasBox && World.Selection.Actors.Any() && !multiClick) { - ApplyOrders(world, xy, mi); + ApplyOrders(World, xy, mi); YieldMouseFocus(mi); return true; } } - if (world.OrderGenerator is UnitOrderGenerator) + if (World.OrderGenerator is UnitOrderGenerator) { - if (MultiClick) + if (multiClick) { - var unit = world.ScreenMap.ActorsAt(xy).FirstOrDefault(); - var newSelection2 = SelectActorsInBox(world, worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.BottomRight, + var unit = World.ScreenMap.ActorsAt(xy).FirstOrDefault(); + var newSelection2 = SelectActorsInBox(World, worldRenderer.Viewport.TopLeft, worldRenderer.Viewport.BottomRight, a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); - - world.Selection.Combine(world, newSelection2, true, false); + + World.Selection.Combine(World, newSelection2, true, false); } else { - var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); - world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); + var newSelection = SelectActorsInBox(World, dragStart, xy, _ => true); + World.Selection.Combine(World, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); } } - + dragStart = dragEnd = xy; YieldMouseFocus(mi); } - + if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) dragStart = dragEnd = xy; - + if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) { - if (UseClassicMouseStyle) - world.Selection.Clear(); + if (useClassicMouseStyle) + World.Selection.Clear(); - if (!HasBox) // don't issue orders while selecting - ApplyOrders(world, xy, mi); + if (!hasBox) // don't issue orders while selecting + ApplyOrders(World, xy, mi); } - + return true; } - public Pair? SelectionBox { get @@ -137,14 +139,33 @@ namespace OpenRA.Widgets var pos = worldRenderer.Position(xy); var orders = world.OrderGenerator.Order(world, pos.ToCPos(), mi).ToArray(); - orders.Do(o => world.IssueOrder(o)); world.PlayVoiceForOrders(orders); + + var flashed = false; + foreach (var o in orders) + { + if (!flashed) + { + if (o.TargetActor != null) + { + world.AddFrameEndTask(w => w.Add(new FlashTarget(o.TargetActor))); + flashed = true; + } + else if (o.Subject != world.LocalPlayer.PlayerActor && o.TargetLocation != CPos.Zero) // TODO: this filters building placement, but also suppport powers :( + { + world.AddFrameEndTask(w => w.Add(new MoveFlash(worldRenderer.Position(worldRenderer.Viewport.ViewToWorldPx(mi.Location)), world))); + flashed = true; + } + } + + world.IssueOrder(o); + } } public override string GetCursor(int2 screenPos) { - return Sync.CheckSyncUnchanged(world, () => + return Sync.CheckSyncUnchanged(World, () => { // Always show an arrow while selecting if (SelectionBox != null) @@ -161,7 +182,7 @@ namespace OpenRA.Widgets Modifiers = Game.GetModifierKeys() }; - return world.OrderGenerator.GetCursor(world, cell, mi); + return World.OrderGenerator.GetCursor(World, cell, mi); }); } @@ -172,18 +193,16 @@ namespace OpenRA.Widgets if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9) { var group = (int)e.Key - (int)Keycode.NUMBER_0; - world.Selection.DoControlGroup(world, worldRenderer, group, e.Modifiers, e.MultiTapCount); + World.Selection.DoControlGroup(World, worldRenderer, group, e.Modifiers, e.MultiTapCount); return true; } - - // Disable pausing for spectators - else if (Hotkey.FromKeyInput(e) == Game.Settings.Keys.PauseKey && world.LocalPlayer != null) - world.SetPauseState(!world.Paused); + else if (Hotkey.FromKeyInput(e) == Game.Settings.Keys.PauseKey && World.LocalPlayer != null) // Disable pausing for spectators + World.SetPauseState(!World.Paused); } + return false; } - static readonly Actor[] NoActors = {}; IEnumerable SelectActorsInBox(World world, int2 a, int2 b, Func cond) { return world.ScreenMap.ActorsInBox(a, b) diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 01e27d1649..f0d05088ac 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -81,7 +81,7 @@ namespace OpenRA public readonly ActorMap ActorMap; public readonly ScreenMap ScreenMap; - public void IssueOrder( Order o ) { orderManager.IssueOrder( o ); } /* avoid exposing the OM to mod code */ + public void IssueOrder(Order o) { orderManager.IssueOrder(o); } /* avoid exposing the OM to mod code */ IOrderGenerator orderGenerator_; public IOrderGenerator OrderGenerator diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index fb315d6267..23adda90f2 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -259,7 +259,9 @@ namespace OpenRA.Mods.RA.Move { if (order is MoveOrderTargeter) { - if (Info.OnRails) return null; + if (Info.OnRails) + return null; + return new Order("Move", self, queued) { TargetLocation = target.CenterPosition.ToCPos() }; } return null; diff --git a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs old mode 100755 new mode 100644 index d3d32b61c5..3c5d95ddb1 --- a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs @@ -71,7 +71,7 @@ namespace OpenRA.Mods.RA.Orders public IEnumerable Render(WorldRenderer wr, World world) { yield break; } public void RenderAfterWorld(WorldRenderer wr, World world) { - var position = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var position = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var topLeft = position - FootprintUtils.AdjustForBuildingSize(BuildingInfo); var actorInfo = Rules.Info[Building]; diff --git a/OpenRA.Mods.RA/Player/PlaceBuilding.cs b/OpenRA.Mods.RA/Player/PlaceBuilding.cs index acc8bf2019..88c5b9ce6a 100755 --- a/OpenRA.Mods.RA/Player/PlaceBuilding.cs +++ b/OpenRA.Mods.RA/Player/PlaceBuilding.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA // Find the queue with the target actor var queue = w.ActorsWithTrait() .Where(p => p.Actor.Owner == self.Owner && - p.Trait.CurrentItem() != null && + p.Trait.CurrentItem() != null && p.Trait.CurrentItem().Item == order.TargetString && p.Trait.CurrentItem().RemainingTime == 0) .Select(p => p.Trait) diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs old mode 100755 new mode 100644 index b01e915fcd..9b3811c586 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -138,7 +138,7 @@ namespace OpenRA.Mods.RA public void RenderAfterWorld(WorldRenderer wr, World world) { - var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var targetUnits = power.UnitsInRange(xy); foreach (var unit in targetUnits) if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility()) @@ -147,7 +147,7 @@ namespace OpenRA.Mods.RA public IEnumerable Render(WorldRenderer wr, World world) { - var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var tiles = world.FindTilesInCircle(xy, range); var pal = wr.Palette("terrain"); foreach (var t in tiles) @@ -226,7 +226,7 @@ namespace OpenRA.Mods.RA public IEnumerable Render(WorldRenderer wr, World world) { - var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var pal = wr.Palette("terrain"); // Source tiles diff --git a/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs b/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs old mode 100755 new mode 100644 index abfaeafc06..a483fe30c9 --- a/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/IronCurtainPower.cs @@ -90,14 +90,14 @@ namespace OpenRA.Mods.RA public void RenderAfterWorld(WorldRenderer wr, World world) { - var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); foreach (var unit in power.UnitsInRange(xy)) wr.DrawSelectionBox(unit, Color.Red); } public IEnumerable Render(WorldRenderer wr, World world) { - var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); + var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var pal = wr.Palette("terrain"); foreach (var t in world.FindTilesInCircle(xy, range)) yield return new SpriteRenderable(tile, t.CenterPosition, WVec.Zero, -511, pal, 1f, true); diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 32013bfabb..fafbc8dba8 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -257,6 +257,12 @@ World: G: 255 B: 255 A: 128 + PaletteFromRGBA@moveflash: + Name: moveflash + R: 255 + G: 255 + B: 255 + A: 64 PaletteFromRGBA@disabled: Name: disabled R: 0 diff --git a/mods/cnc/sequences/misc.yaml b/mods/cnc/sequences/misc.yaml index 7328ce4543..d6a88dc522 100644 --- a/mods/cnc/sequences/misc.yaml +++ b/mods/cnc/sequences/misc.yaml @@ -304,4 +304,10 @@ icon: ioncannon: ionicnh Start: 0 abomb: atomicnh - Start: 0 \ No newline at end of file + Start: 0 + +moveflsh: + idle: + Start: 0 + Length: * + Tick: 80 \ No newline at end of file diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 0e0e9a991d..2426db13f3 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -411,12 +411,11 @@ World: G: 255 B: 255 A: 128 - PaletteFromRGBA@invuln: - Name: invuln - R: 128 - G: 0 - B: 0 - A: 128 + PaletteFromR8@moveflash: + Name: moveflash + Filename: DATA.R8 + Offset: 2572352 + A: 64 PaletteFromRGBA@disabled: Name: disabled R: 0 diff --git a/mods/d2k/sequences/misc.yaml b/mods/d2k/sequences/misc.yaml index 8391921077..50e14f4796 100644 --- a/mods/d2k/sequences/misc.yaml +++ b/mods/d2k/sequences/misc.yaml @@ -297,4 +297,11 @@ spicebloom: idle: DATA.R8 Start: 109 ZOffset: -511 - Offset: -16,-16 \ No newline at end of file + Offset: -16,-16 + +moveflsh: + idle: DATA.R8 + Start: 3621 + Length: 5 + Tick: 80 + BlendMode: Subtractive \ No newline at end of file diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 286ea3d788..93a45a4dc0 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -587,6 +587,12 @@ World: G: 255 B: 255 A: 128 + PaletteFromRGBA@moveflash: + Name: moveflash + R: 255 + G: 255 + B: 255 + A: 64 PaletteFromRGBA@invuln: Name: invuln R: 128 diff --git a/mods/ra/sequences/misc.yaml b/mods/ra/sequences/misc.yaml index f1f5b2fd95..045c9ab0c5 100644 --- a/mods/ra/sequences/misc.yaml +++ b/mods/ra/sequences/misc.yaml @@ -162,6 +162,7 @@ moveflsh: idle: Start: 0 Length: * + Tick: 80 select: repair: diff --git a/mods/ts/rules/system.yaml b/mods/ts/rules/system.yaml index 0625b3ce46..4974e9196a 100644 --- a/mods/ts/rules/system.yaml +++ b/mods/ts/rules/system.yaml @@ -85,12 +85,12 @@ World: G: 255 B: 255 A: 128 - PaletteFromRGBA@invuln: - Name: invuln - R: 128 - G: 0 - B: 0 - A: 128 + PaletteFromRGBA@moveflash: + Name: moveflash + R: 255 + G: 255 + B: 255 + A: 64 PaletteFromRGBA@disabled: Name: disabled R: 0 diff --git a/mods/ts/sequences/misc.yaml b/mods/ts/sequences/misc.yaml index 6e3ad05f23..434d185da1 100644 --- a/mods/ts/sequences/misc.yaml +++ b/mods/ts/sequences/misc.yaml @@ -242,4 +242,10 @@ crystal4: torpedo: idle: Start: 0 - Length: * \ No newline at end of file + Length: * + +moveflsh: + idle: + Start: 0 + Length: * + Tick: 80 \ No newline at end of file