diff --git a/OpenRA.Mods.Common/Effects/Beacon.cs b/OpenRA.Mods.Common/Effects/Beacon.cs index 76b4e9d11b..9d1bfdbc05 100644 --- a/OpenRA.Mods.Common/Effects/Beacon.cs +++ b/OpenRA.Mods.Common/Effects/Beacon.cs @@ -23,7 +23,8 @@ namespace OpenRA.Mods.Common.Effects readonly Player owner; readonly WPos position; - readonly string palettePrefix; + readonly string beaconPalette; + readonly bool isPlayerPalette; readonly string posterPalette; readonly Animation arrow; readonly Animation circles; @@ -34,37 +35,39 @@ namespace OpenRA.Mods.Common.Effects int arrowSpeed = 50; // Player-placed beacons are removed after a delay - public Beacon(Player owner, WPos position, int duration, string palettePrefix) + public Beacon(Player owner, WPos position, int duration, string beaconPalette, bool isPlayerPalette, string beaconCollection, string arrowSprite, string circleSprite) { this.owner = owner; this.position = position; - this.palettePrefix = palettePrefix; + this.beaconPalette = beaconPalette; + this.isPlayerPalette = isPlayerPalette; - arrow = new Animation(owner.World, "beacon"); - circles = new Animation(owner.World, "beacon"); + arrow = new Animation(owner.World, beaconCollection); + circles = new Animation(owner.World, beaconCollection); - arrow.Play("arrow"); - circles.Play("circles"); + arrow.Play(arrowSprite); + circles.Play(circleSprite); if (duration > 0) owner.World.Add(new DelayedAction(duration, () => owner.World.Remove(this))); } // Support power beacons are expected to clean themselves up - public Beacon(Player owner, WPos position, string palettePrefix, string posterType, string posterPalette, Func clockFraction) - : this(owner, position, -1, palettePrefix) + public Beacon(Player owner, WPos position, bool isPlayerPalette, string palette, string posterCollection, string posterType, string posterPalette, + string arrowSequence, string circleSequence, string clockSequence, Func clockFraction) + : this(owner, position, -1, palette, isPlayerPalette, posterCollection, arrowSequence, circleSequence) { this.posterPalette = posterPalette; if (posterType != null) { - poster = new Animation(owner.World, "beacon"); + poster = new Animation(owner.World, posterCollection); poster.Play(posterType); if (clockFraction != null) { - clock = new Animation(owner.World, "beacon"); - clock.PlayFetchIndex("clock", () => Exts.Clamp((int)(clockFraction() * (clock.CurrentSequence.Length - 1)), 0, clock.CurrentSequence.Length - 1)); + clock = new Animation(owner.World, posterCollection); + clock.PlayFetchIndex(clockSequence, () => Exts.Clamp((int)(clockFraction() * (clock.CurrentSequence.Length - 1)), 0, clock.CurrentSequence.Length - 1)); } } } @@ -91,7 +94,7 @@ namespace OpenRA.Mods.Common.Effects if (!owner.IsAlliedWith(owner.World.RenderPlayer)) yield break; - var palette = r.Palette(palettePrefix + owner.InternalName); + var palette = r.Palette(isPlayerPalette ? beaconPalette + owner.InternalName : beaconPalette); foreach (var a in circles.Render(position, palette)) yield return a; diff --git a/OpenRA.Mods.Common/Scripting/Global/BeaconGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/BeaconGlobal.cs index 14cb7fe87b..95f44a4a1c 100644 --- a/OpenRA.Mods.Common/Scripting/Global/BeaconGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/BeaconGlobal.cs @@ -27,9 +27,10 @@ namespace OpenRA.Mods.Common.Scripting [Desc("Creates a new beacon that stays for the specified time at the specified WPos. " + "Does not remove player set beacons, nor gets removed by placing them.")] - public Beacon New(Player owner, WPos position, int duration = 30 * 25, bool showRadarPings = true, string palettePrefix = "player") + public Beacon New(Player owner, WPos position, int duration = 30 * 25, bool showRadarPings = true) { - var playerBeacon = new Beacon(owner, position, duration, palettePrefix); + var beacon = owner.PlayerActor.Info.TraitInfo(); + var playerBeacon = new Beacon(owner, position, duration, beacon.Palette, beacon.IsPlayerPalette, beacon.BeaconImage, beacon.ArrowSequence, beacon.CircleSequence); owner.PlayerActor.World.AddFrameEndTask(w => w.Add(playerBeacon)); if (showRadarPings && radarPings != null) diff --git a/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs b/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs index cafec3fad9..cba8a9bc95 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlaceBeacon.cs @@ -14,12 +14,19 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { + [Desc("A beacon that is constructed from a circle sprite that is animated once and a moving arrow sprite.")] public class PlaceBeaconInfo : ITraitInfo { public readonly int Duration = 30 * 25; public readonly string NotificationType = "Sounds"; public readonly string Notification = "Beacon"; - public readonly string PalettePrefix = "player"; + + public readonly bool IsPlayerPalette = true; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = "player"; + + public readonly string BeaconImage = "beacon"; + [SequenceReference("BeaconImage")] public readonly string ArrowSequence = "arrow"; + [SequenceReference("BeaconImage")] public readonly string CircleSequence = "circles"; public object Create(ActorInitializer init) { return new PlaceBeacon(init.Self, this); } } @@ -50,7 +57,8 @@ namespace OpenRA.Mods.Common.Traits if (playerBeacon != null) self.World.Remove(playerBeacon); - playerBeacon = new Beacon(self.Owner, pos, info.Duration, info.PalettePrefix); + playerBeacon = new Beacon(self.Owner, pos, info.Duration, info.Palette, info.IsPlayerPalette, info.BeaconImage, info.ArrowSequence, info.CircleSequence); + self.World.Add(playerBeacon); if (self.Owner.IsAlliedWith(self.World.RenderPlayer)) diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs index 117450b12a..318576029b 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/AirstrikePower.cs @@ -169,9 +169,14 @@ namespace OpenRA.Mods.Common.Traits beacon = new Beacon( self.Owner, target - new WVec(0, 0, altitude), - Info.BeaconPalettePrefix, + Info.BeaconPaletteIsPlayerPalette, + Info.BeaconPalette, + Info.BeaconImage, Info.BeaconPoster, Info.BeaconPosterPalette, + Info.ArrowSequence, + Info.CircleSequence, + Info.ClockSequence, () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance); w.Add(beacon); diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs index d39584be2e..b35e775a33 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs @@ -134,9 +134,14 @@ namespace OpenRA.Mods.Common.Traits var beacon = new Beacon( order.Player, targetPosition, - Info.BeaconPalettePrefix, + Info.BeaconPaletteIsPlayerPalette, + Info.BeaconPalette, + Info.BeaconImage, Info.BeaconPoster, Info.BeaconPosterPalette, + Info.ArrowSequence, + Info.CircleSequence, + Info.ClockSequence, () => missile.FractionComplete); Action removeBeacon = () => self.World.AddFrameEndTask(w => diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPower.cs index 9d4a18b15e..b5ccbc16b7 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPower.cs @@ -43,11 +43,19 @@ namespace OpenRA.Mods.Common.Traits [Desc("Palette used for the icon.")] [PaletteReference] public readonly string IconPalette = "chrome"; - [Desc("Beacons are only supported on the Airstrike and Nuke powers")] + [Desc("Beacons are only supported on the Airstrike, Paratroopers, and Nuke powers")] public readonly bool DisplayBeacon = false; - public readonly string BeaconPalettePrefix = "player"; - public readonly string BeaconPoster = null; + + public readonly bool BeaconPaletteIsPlayerPalette = true; + [PaletteReference("BeaconPaletteIsPlayerPalette")] public readonly string BeaconPalette = "player"; + + public readonly string BeaconImage = "beacon"; + [SequenceReference("BeaconImage")] public readonly string BeaconPoster = null; [PaletteReference] public readonly string BeaconPosterPalette = "chrome"; + [SequenceReference("BeaconImage")] public readonly string ClockSequence = "clock"; + + [SequenceReference("BeaconImage")] public readonly string ArrowSequence = "arrow"; + [SequenceReference("BeaconImage")] public readonly string CircleSequence = "circles"; public readonly bool DisplayRadarPing = false; diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs index 5d7de97992..6a1f856e8e 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/ParatroopersPower.cs @@ -204,9 +204,14 @@ namespace OpenRA.Mods.RA.Traits beacon = new Beacon( self.Owner, target - new WVec(0, 0, altitude), - Info.BeaconPalettePrefix, + Info.BeaconPaletteIsPlayerPalette, + Info.BeaconPalette, + Info.BeaconImage, Info.BeaconPoster, Info.BeaconPosterPalette, + Info.ArrowSequence, + Info.CircleSequence, + Info.ClockSequence, () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance); w.Add(beacon);