Add support for TS-style tinted target flashes.

This commit is contained in:
Paul Chote
2021-07-03 23:28:48 +01:00
committed by abcdefg30
parent 9291263609
commit 7a93ff3258
8 changed files with 88 additions and 14 deletions

View File

@@ -76,6 +76,9 @@ namespace OpenRA.Traits
static readonly Rectangle[] NoBounds = new Rectangle[0]; static readonly Rectangle[] NoBounds = new Rectangle[0];
int flashTicks; int flashTicks;
TintModifiers flashModifiers;
float3 flashTint;
float? flashAlpha;
public FrozenActor(Actor actor, ICreatesFrozenActors frozenTrait, PPos[] footprint, Player viewer, bool startsRevealed) public FrozenActor(Actor actor, ICreatesFrozenActors frozenTrait, PPos[] footprint, Player viewer, bool startsRevealed)
{ {
@@ -176,9 +179,20 @@ namespace OpenRA.Traits
Owner = null; Owner = null;
} }
public void Flash() public void Flash(Color color, float alpha)
{ {
flashTicks = 5; flashTicks = 5;
flashModifiers = TintModifiers.ReplaceColor;
flashTint = new float3(color.R, color.G, color.B) / 255f;
flashAlpha = alpha;
}
public void Flash(float3 tint)
{
flashTicks = 5;
flashModifiers = TintModifiers.None;
flashTint = tint;
flashAlpha = null;
} }
public IEnumerable<IRenderable> Render(WorldRenderer wr) public IEnumerable<IRenderable> Render(WorldRenderer wr)
@@ -192,7 +206,11 @@ namespace OpenRA.Traits
.Select(r => .Select(r =>
{ {
var mr = (IModifyableRenderable)r; var mr = (IModifyableRenderable)r;
return mr.WithTint(float3.Ones, mr.TintModifiers | TintModifiers.ReplaceColor).WithAlpha(0.5f); mr = mr.WithTint(flashTint, mr.TintModifiers | flashModifiers);
if (flashAlpha.HasValue)
mr = mr.WithAlpha(flashAlpha.Value);
return mr;
})); }));
} }

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
if (!enterDemolishables.Any(i => i.IsValidTarget(enterActor, self))) if (!enterDemolishables.Any(i => i.IsValidTarget(enterActor, self)))
return; return;
w.Add(new FlashTarget(enterActor, count: flashes, delay: flashesDelay, interval: flashInterval)); w.Add(new FlashTarget(enterActor, Color.White, count: flashes, interval: flashInterval, delay: flashesDelay));
foreach (var ind in notifiers) foreach (var ind in notifiers)
ind.Demolishing(self); ind.Demolishing(self);

View File

@@ -13,21 +13,25 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Effects; using OpenRA.Effects;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.Effects namespace OpenRA.Mods.Common.Effects
{ {
public class FlashTarget : IEffect public class FlashTarget : IEffect
{ {
readonly Actor target; readonly Actor target;
readonly Player player;
readonly int count; readonly int count;
readonly int interval; readonly int interval;
readonly TintModifiers modifiers;
readonly float3 tint;
readonly float? alpha;
int tick; int tick;
public FlashTarget(Actor target, Player asPlayer = null, int count = 2, int interval = 2, int delay = 0) FlashTarget(Actor target, int count, int interval, int delay)
{ {
this.target = target; this.target = target;
player = asPlayer;
this.count = count; this.count = count;
this.interval = interval; this.interval = interval;
tick = -delay; tick = -delay;
@@ -38,6 +42,20 @@ namespace OpenRA.Mods.Common.Effects
}); });
} }
public FlashTarget(Actor target, Color color, float alpha = 0.5f, int count = 2, int interval = 2, int delay = 0)
: this(target, count, interval, delay)
{
modifiers = TintModifiers.ReplaceColor;
tint = new float3(color.R, color.G, color.B) / 255f;
this.alpha = alpha;
}
public FlashTarget(Actor target, float3 tint, int count = 2, int interval = 2, int delay = 0)
: this(target, count, interval, delay)
{
this.tint = tint;
}
public void Tick(World world) public void Tick(World world)
{ {
if (++tick >= count * interval || !target.IsInWorld) if (++tick >= count * interval || !target.IsInWorld)
@@ -48,13 +66,16 @@ namespace OpenRA.Mods.Common.Effects
{ {
if (target.IsInWorld && tick >= 0 && tick % interval == 0) if (target.IsInWorld && tick >= 0 && tick % interval == 0)
{ {
var color = player == null ? float3.Ones : new float3(player.Color.R, player.Color.G, player.Color.B) / 255f;
return target.Render(wr) return target.Render(wr)
.Where(r => !r.IsDecoration && r is IModifyableRenderable) .Where(r => !r.IsDecoration && r is IModifyableRenderable)
.Select(r => .Select(r =>
{ {
var mr = (IModifyableRenderable)r; var mr = (IModifyableRenderable)r;
return mr.WithTint(color, mr.TintModifiers | TintModifiers.ReplaceColor).WithAlpha(0.5f); mr = mr.WithTint(tint, mr.TintModifiers | modifiers);
if (alpha.HasValue)
mr = mr.WithAlpha(alpha.Value);
return mr;
}); });
} }

View File

@@ -14,6 +14,7 @@ using Eluant;
using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Scripting; using OpenRA.Scripting;
using OpenRA.Traits; using OpenRA.Traits;
@@ -76,7 +77,7 @@ namespace OpenRA.Mods.Common.Scripting
"defines which player palette to use. Duration is in ticks.")] "defines which player palette to use. Duration is in ticks.")]
public void Flash(int duration = 4, Player asPlayer = null) public void Flash(int duration = 4, Player asPlayer = null)
{ {
Self.World.Add(new FlashTarget(Self, asPlayer, duration)); Self.World.Add(new FlashTarget(Self, asPlayer?.Color ?? Color.White, duration));
} }
[Desc("The effective owner of the actor.")] [Desc("The effective owner of the actor.")]

View File

@@ -64,10 +64,10 @@ namespace OpenRA.Mods.Common.Traits
if (tick / 4 < captorOwners.Count && tick % 4 == 0) if (tick / 4 < captorOwners.Count && tick % 4 == 0)
{ {
var captorOwner = captorOwners[tick / 4]; var captorOwner = captorOwners[tick / 4];
self.World.Add(new FlashTarget(self, captorOwner)); self.World.Add(new FlashTarget(self, captorOwner.Color));
foreach (var captor in captors) foreach (var captor in captors)
if (captor.Owner == captorOwner) if (captor.Owner == captorOwner)
self.World.Add(new FlashTarget(captor, captorOwner)); self.World.Add(new FlashTarget(captor, captorOwner.Color));
} }
if (++tick >= Info.Interval) if (++tick >= Info.Interval)

View File

@@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits
self.ChangeOwner(captor.Owner); self.ChangeOwner(captor.Owner);
if (self.Owner == self.World.LocalPlayer) if (self.Owner == self.World.LocalPlayer)
w.Add(new FlashTarget(self)); w.Add(new FlashTarget(self, Color.White));
var pc = captor.Info.TraitInfoOrDefault<ProximityCaptorInfo>(); var pc = captor.Info.TraitInfoOrDefault<ProximityCaptorInfo>();
foreach (var t in self.TraitsImplementing<INotifyCapture>()) foreach (var t in self.TraitsImplementing<INotifyCapture>())

View File

@@ -10,10 +10,13 @@
#endregion #endregion
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
public enum ActorFlashType { Overlay, Tint }
[Desc("Renders an effect at the order target locations.")] [Desc("Renders an effect at the order target locations.")]
public class OrderEffectsInfo : TraitInfo public class OrderEffectsInfo : TraitInfo
{ {
@@ -28,6 +31,24 @@ namespace OpenRA.Mods.Common.Traits
[Desc("The palette to use.")] [Desc("The palette to use.")]
public readonly string TerrainFlashPalette; public readonly string TerrainFlashPalette;
[Desc("The type of effect to apply to targeted (frozen) actors. Accepts values Overlay and Tint.")]
public readonly ActorFlashType ActorFlashType = ActorFlashType.Overlay;
[Desc("The overlay color to display when ActorFlashType is Overlay.")]
public readonly Color ActorFlashOverlayColor = Color.White;
[Desc("The overlay transparency to display when ActorFlashType is Overlay.")]
public readonly float ActorFlashOverlayAlpha = 0.5f;
[Desc("The tint to apply when ActorFlashType is Tint.")]
public readonly float3 ActorFlashTint = new float3(1.4f, 1.4f, 1.4f);
[Desc("Number of times to flash (frozen) actors.")]
public readonly int ActorFlashCount = 2;
[Desc("Number of ticks between (frozen) actor flashes.")]
public readonly int ActorFlashInterval = 2;
public override object Create(ActorInitializer init) public override object Create(ActorInitializer init)
{ {
return new OrderEffects(this); return new OrderEffects(this);
@@ -47,13 +68,25 @@ namespace OpenRA.Mods.Common.Traits
{ {
if (target.Type == TargetType.Actor) if (target.Type == TargetType.Actor)
{ {
world.AddFrameEndTask(w => w.Add(new FlashTarget(target.Actor))); if (info.ActorFlashType == ActorFlashType.Overlay)
world.AddFrameEndTask(w => w.Add(new FlashTarget(
target.Actor, info.ActorFlashOverlayColor, info.ActorFlashOverlayAlpha,
info.ActorFlashCount, info.ActorFlashInterval)));
else
world.AddFrameEndTask(w => w.Add(new FlashTarget(
target.Actor, info.ActorFlashTint,
info.ActorFlashCount, info.ActorFlashInterval)));
return true; return true;
} }
if (target.Type == TargetType.FrozenActor) if (target.Type == TargetType.FrozenActor)
{ {
target.FrozenActor.Flash(); if (info.ActorFlashType == ActorFlashType.Overlay)
target.FrozenActor.Flash(info.ActorFlashOverlayColor, info.ActorFlashOverlayAlpha);
else
target.FrozenActor.Flash(info.ActorFlashTint);
return true; return true;
} }

View File

@@ -388,6 +388,7 @@ World:
TerrainFlashImage: moveflsh TerrainFlashImage: moveflsh
TerrainFlashSequence: idle TerrainFlashSequence: idle
TerrainFlashPalette: moveflash TerrainFlashPalette: moveflash
ActorFlashType: Tint
EditorWorld: EditorWorld:
Inherits: ^BaseWorld Inherits: ^BaseWorld