Add clock overlay to support power beacons.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Effects;
|
using OpenRA.Effects;
|
||||||
@@ -24,16 +25,18 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
readonly Animation arrow;
|
readonly Animation arrow;
|
||||||
readonly Animation circles;
|
readonly Animation circles;
|
||||||
readonly Animation poster;
|
readonly Animation poster;
|
||||||
|
readonly Animation clock;
|
||||||
|
|
||||||
static readonly int maxArrowHeight = 512;
|
static readonly int maxArrowHeight = 512;
|
||||||
int arrowHeight = maxArrowHeight;
|
int arrowHeight = maxArrowHeight;
|
||||||
int arrowSpeed = 50;
|
int arrowSpeed = 50;
|
||||||
|
|
||||||
public Beacon(Player owner, WPos position, int duration, string palettePrefix, string posterType, string posterPalette)
|
// Player-placed beacons are removed after a delay
|
||||||
|
public Beacon(Player owner, WPos position, int duration, string palettePrefix)
|
||||||
{
|
{
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.palettePrefix = palettePrefix;
|
this.palettePrefix = palettePrefix;
|
||||||
this.posterPalette = posterPalette;
|
|
||||||
|
|
||||||
arrow = new Animation(owner.World, "beacon");
|
arrow = new Animation(owner.World, "beacon");
|
||||||
circles = new Animation(owner.World, "beacon");
|
circles = new Animation(owner.World, "beacon");
|
||||||
@@ -41,14 +44,27 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
arrow.Play("arrow");
|
arrow.Play("arrow");
|
||||||
circles.Play("circles");
|
circles.Play("circles");
|
||||||
|
|
||||||
|
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<float> clockFraction)
|
||||||
|
: this(owner, position, -1, palettePrefix)
|
||||||
|
{
|
||||||
|
this.posterPalette = posterPalette;
|
||||||
|
|
||||||
if (posterType != null)
|
if (posterType != null)
|
||||||
{
|
{
|
||||||
poster = new Animation(owner.World, "beacon");
|
poster = new Animation(owner.World, "beacon");
|
||||||
poster.Play(posterType);
|
poster.Play(posterType);
|
||||||
}
|
|
||||||
|
|
||||||
if (duration > 0)
|
if (clockFraction != null)
|
||||||
owner.World.Add(new DelayedAction(duration, () => owner.World.Remove(this)));
|
{
|
||||||
|
clock = new Animation(owner.World, "beacon");
|
||||||
|
clock.PlayFetchIndex("clock", () => Exts.Clamp((int)(clockFraction() * (clock.CurrentSequence.Length - 1)), 0, clock.CurrentSequence.Length - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
@@ -63,6 +79,9 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
|
|
||||||
arrow.Tick();
|
arrow.Tick();
|
||||||
circles.Tick();
|
circles.Tick();
|
||||||
|
|
||||||
|
if (clock != null)
|
||||||
|
clock.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IRenderable> Render(WorldRenderer r)
|
public IEnumerable<IRenderable> Render(WorldRenderer r)
|
||||||
@@ -78,8 +97,14 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
yield return a;
|
yield return a;
|
||||||
|
|
||||||
if (poster != null)
|
if (poster != null)
|
||||||
|
{
|
||||||
foreach (var a in poster.Render(position, r.Palette(posterPalette)))
|
foreach (var a in poster.Render(position, r.Palette(posterPalette)))
|
||||||
yield return a;
|
yield return a;
|
||||||
|
|
||||||
|
if (clock != null)
|
||||||
|
foreach (var a in clock.Render(position, r.Palette(posterPalette)))
|
||||||
|
yield return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,5 +90,7 @@ namespace OpenRA.Mods.RA.Effects
|
|||||||
{
|
{
|
||||||
return anim.Render(pos, wr.Palette("effect"));
|
return anim.Render(pos, wr.Palette("effect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float FractionComplete { get { return ticks * 1f / delay; } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (playerBeacon != null)
|
if (playerBeacon != null)
|
||||||
self.World.Remove(playerBeacon);
|
self.World.Remove(playerBeacon);
|
||||||
|
|
||||||
playerBeacon = new Beacon(self.Owner, pos, info.Duration, info.PalettePrefix, null, null);
|
playerBeacon = new Beacon(self.Owner, pos, info.Duration, info.PalettePrefix);
|
||||||
self.World.Add(playerBeacon);
|
self.World.Add(playerBeacon);
|
||||||
|
|
||||||
if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ namespace OpenRA.Mods.RA
|
|||||||
[Desc("Amount of time to keep the camera alive after the aircraft have finished attacking")]
|
[Desc("Amount of time to keep the camera alive after the aircraft have finished attacking")]
|
||||||
public readonly int CameraRemoveDelay = 25;
|
public readonly int CameraRemoveDelay = 25;
|
||||||
|
|
||||||
|
[Desc("Weapon range offset to apply during the beacon clock calculation")]
|
||||||
|
public readonly WRange BeaconDistanceOffset = WRange.FromCells(6);
|
||||||
|
|
||||||
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,20 +58,6 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
base.Activate(self, order, manager);
|
base.Activate(self, order, manager);
|
||||||
|
|
||||||
Beacon beacon = null;
|
|
||||||
if (Info.DisplayBeacon)
|
|
||||||
{
|
|
||||||
beacon = new Beacon(
|
|
||||||
order.Player,
|
|
||||||
order.TargetLocation.CenterPosition,
|
|
||||||
-1,
|
|
||||||
Info.BeaconPalettePrefix,
|
|
||||||
Info.BeaconPoster,
|
|
||||||
Info.BeaconPosterPalette);
|
|
||||||
|
|
||||||
self.World.Add(beacon);
|
|
||||||
}
|
|
||||||
|
|
||||||
var info = Info as AirstrikePowerInfo;
|
var info = Info as AirstrikePowerInfo;
|
||||||
var attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
var attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
|
||||||
var attackRotation = WRot.FromFacing(attackFacing);
|
var attackRotation = WRot.FromFacing(attackFacing);
|
||||||
@@ -81,6 +70,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
Actor flare = null;
|
Actor flare = null;
|
||||||
Actor camera = null;
|
Actor camera = null;
|
||||||
|
Beacon beacon = null;
|
||||||
Dictionary<Actor, bool> aircraftInRange = new Dictionary<Actor, bool>();
|
Dictionary<Actor, bool> aircraftInRange = new Dictionary<Actor, bool>();
|
||||||
|
|
||||||
Action<Actor> onEnterRange = a =>
|
Action<Actor> onEnterRange = a =>
|
||||||
@@ -147,6 +137,7 @@ namespace OpenRA.Mods.RA
|
|||||||
var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound;
|
var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound;
|
||||||
Sound.Play(notification);
|
Sound.Play(notification);
|
||||||
|
|
||||||
|
Actor distanceTestActor = null;
|
||||||
for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
|
for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
|
||||||
{
|
{
|
||||||
// Even-sized squads skip the lead plane
|
// Even-sized squads skip the lead plane
|
||||||
@@ -174,6 +165,23 @@ namespace OpenRA.Mods.RA
|
|||||||
a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
|
a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
|
||||||
a.QueueActivity(new RemoveSelf());
|
a.QueueActivity(new RemoveSelf());
|
||||||
aircraftInRange.Add(a, false);
|
aircraftInRange.Add(a, false);
|
||||||
|
distanceTestActor = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Info.DisplayBeacon)
|
||||||
|
{
|
||||||
|
var distance = (target - startEdge).HorizontalLength;
|
||||||
|
|
||||||
|
beacon = new Beacon(
|
||||||
|
order.Player,
|
||||||
|
order.TargetLocation.CenterPosition,
|
||||||
|
Info.BeaconPalettePrefix,
|
||||||
|
Info.BeaconPoster,
|
||||||
|
Info.BeaconPosterPalette,
|
||||||
|
() => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Range) * 1f / distance
|
||||||
|
);
|
||||||
|
|
||||||
|
w.Add(beacon);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,20 +68,6 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
base.Activate(self, order, manager);
|
base.Activate(self, order, manager);
|
||||||
|
|
||||||
Beacon beacon = null;
|
|
||||||
if (Info.DisplayBeacon)
|
|
||||||
{
|
|
||||||
beacon = new Beacon(
|
|
||||||
order.Player,
|
|
||||||
order.TargetLocation.CenterPosition,
|
|
||||||
-1,
|
|
||||||
Info.BeaconPalettePrefix,
|
|
||||||
Info.BeaconPoster,
|
|
||||||
Info.BeaconPosterPalette);
|
|
||||||
|
|
||||||
self.World.Add(beacon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||||
Sound.Play(Info.LaunchSound);
|
Sound.Play(Info.LaunchSound);
|
||||||
else
|
else
|
||||||
@@ -91,10 +77,12 @@ namespace OpenRA.Mods.RA
|
|||||||
var rb = self.Trait<RenderSimple>();
|
var rb = self.Trait<RenderSimple>();
|
||||||
rb.PlayCustomAnim(self, "active");
|
rb.PlayCustomAnim(self, "active");
|
||||||
|
|
||||||
self.World.AddFrameEndTask(w => w.Add(new NukeLaunch(self.Owner, npi.MissileWeapon,
|
var missile = new NukeLaunch(self.Owner, npi.MissileWeapon,
|
||||||
self.CenterPosition + body.LocalToWorld(npi.SpawnOffset),
|
self.CenterPosition + body.LocalToWorld(npi.SpawnOffset),
|
||||||
order.TargetLocation.CenterPosition,
|
order.TargetLocation.CenterPosition,
|
||||||
npi.FlightVelocity, npi.FlightDelay, npi.SkipAscent)));
|
npi.FlightVelocity, npi.FlightDelay, npi.SkipAscent);
|
||||||
|
|
||||||
|
self.World.AddFrameEndTask(w => w.Add(missile));
|
||||||
|
|
||||||
if (npi.CameraActor != null)
|
if (npi.CameraActor != null)
|
||||||
{
|
{
|
||||||
@@ -111,15 +99,29 @@ namespace OpenRA.Mods.RA
|
|||||||
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(npi.FlightDelay - npi.CameraSpawnAdvance, addCamera)));
|
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(npi.FlightDelay - npi.CameraSpawnAdvance, addCamera)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beacon != null)
|
if (Info.DisplayBeacon)
|
||||||
{
|
{
|
||||||
|
var beacon = new Beacon(
|
||||||
|
order.Player,
|
||||||
|
order.TargetLocation.CenterPosition,
|
||||||
|
Info.BeaconPalettePrefix,
|
||||||
|
Info.BeaconPoster,
|
||||||
|
Info.BeaconPosterPalette,
|
||||||
|
() => missile.FractionComplete
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
Action removeBeacon = () => self.World.AddFrameEndTask(w =>
|
Action removeBeacon = () => self.World.AddFrameEndTask(w =>
|
||||||
{
|
{
|
||||||
w.Remove(beacon);
|
w.Remove(beacon);
|
||||||
beacon = null;
|
beacon = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(npi.FlightDelay - npi.BeaconRemoveAdvance, removeBeacon)));
|
self.World.AddFrameEndTask(w =>
|
||||||
|
{
|
||||||
|
w.Add(beacon);
|
||||||
|
w.Add(new DelayedAction(npi.FlightDelay - npi.BeaconRemoveAdvance, removeBeacon));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
mods/cnc/bits/beaconclock.shp
Normal file
BIN
mods/cnc/bits/beaconclock.shp
Normal file
Binary file not shown.
@@ -169,6 +169,10 @@ beacon:
|
|||||||
Start: 0
|
Start: 0
|
||||||
Length: 1
|
Length: 1
|
||||||
Offset: 0,-42
|
Offset: 0,-42
|
||||||
|
clock: beaconclock
|
||||||
|
Start: 0
|
||||||
|
Length: *
|
||||||
|
Offset: 0,-42
|
||||||
|
|
||||||
select:
|
select:
|
||||||
repair:
|
repair:
|
||||||
|
|||||||
BIN
mods/ra/bits/beaconclock.shp
Normal file
BIN
mods/ra/bits/beaconclock.shp
Normal file
Binary file not shown.
@@ -125,6 +125,10 @@ beacon:
|
|||||||
Start: 0
|
Start: 0
|
||||||
Length: *
|
Length: *
|
||||||
Offset: 0,-42
|
Offset: 0,-42
|
||||||
|
clock: beaconclock
|
||||||
|
Start: 0
|
||||||
|
Length: *
|
||||||
|
Offset: 0,-42
|
||||||
|
|
||||||
smoke_m:
|
smoke_m:
|
||||||
idle:
|
idle:
|
||||||
|
|||||||
Reference in New Issue
Block a user