Replace projectile, WithShadow, WithParachute shadows with tint effects.

This commit is contained in:
Paul Chote
2021-02-12 23:20:28 +00:00
committed by reaperrr
parent 1c1af89bb9
commit 554486fb0b
7 changed files with 126 additions and 24 deletions

View File

@@ -50,9 +50,8 @@ namespace OpenRA.Mods.Common.Projectiles
[Desc("Does this projectile have a shadow?")] [Desc("Does this projectile have a shadow?")]
public readonly bool Shadow = false; public readonly bool Shadow = false;
[PaletteReference] [Desc("Color to draw shadow if Shadow is true.")]
[Desc("Palette to use for this projectile's shadow if Shadow is true.")] public readonly Color ShadowColor = Color.FromArgb(140, 0, 0, 0);
public readonly string ShadowPalette = "shadow";
[Desc("Trail animation.")] [Desc("Trail animation.")]
public readonly string TrailImage = null; public readonly string TrailImage = null;
@@ -122,6 +121,9 @@ namespace OpenRA.Mods.Common.Projectiles
readonly WDist speed; readonly WDist speed;
readonly string trailPalette; readonly string trailPalette;
readonly float3 shadowColor;
readonly float shadowAlpha;
ContrailRenderable contrail; ContrailRenderable contrail;
[Sync] [Sync]
@@ -181,6 +183,9 @@ namespace OpenRA.Mods.Common.Projectiles
smokeTicks = info.TrailDelay; smokeTicks = info.TrailDelay;
remainingBounces = info.BounceCount; remainingBounces = info.BounceCount;
shadowColor = new float3(info.ShadowColor.R, info.ShadowColor.G, info.ShadowColor.B) / 255f;
shadowAlpha = info.ShadowColor.A;
} }
WAngle GetEffectiveFacing() WAngle GetEffectiveFacing()
@@ -286,8 +291,10 @@ namespace OpenRA.Mods.Common.Projectiles
{ {
var dat = world.Map.DistanceAboveTerrain(pos); var dat = world.Map.DistanceAboveTerrain(pos);
var shadowPos = pos - new WVec(0, 0, dat.Length); var shadowPos = pos - new WVec(0, 0, dat.Length);
foreach (var r in anim.Render(shadowPos, wr.Palette(info.ShadowPalette))) foreach (var r in anim.Render(shadowPos, wr.Palette(info.Palette)))
yield return r; yield return ((IModifyableRenderable)r)
.WithTint(shadowColor, ((IModifyableRenderable)r).TintModifiers | TintModifiers.ReplaceColor)
.WithAlpha(shadowAlpha);
} }
var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : "")); var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : ""));

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Projectiles namespace OpenRA.Mods.Common.Projectiles
@@ -35,10 +36,11 @@ namespace OpenRA.Mods.Common.Projectiles
[Desc("Palette is a player palette BaseName")] [Desc("Palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false; public readonly bool IsPlayerPalette = false;
[Desc("Does this projectile have a shadow?")]
public readonly bool Shadow = false; public readonly bool Shadow = false;
[PaletteReference] [Desc("Color to draw shadow if Shadow is true.")]
public readonly string ShadowPalette = "shadow"; public readonly Color ShadowColor = Color.FromArgb(140, 0, 0, 0);
[Desc("Projectile movement vector per tick (forward, right, up), use negative values for opposite directions.")] [Desc("Projectile movement vector per tick (forward, right, up), use negative values for opposite directions.")]
public readonly WVec Velocity = WVec.Zero; public readonly WVec Velocity = WVec.Zero;
@@ -55,6 +57,10 @@ namespace OpenRA.Mods.Common.Projectiles
readonly Animation anim; readonly Animation anim;
readonly ProjectileArgs args; readonly ProjectileArgs args;
readonly WVec acceleration; readonly WVec acceleration;
readonly float3 shadowColor;
readonly float shadowAlpha;
WVec velocity; WVec velocity;
[Sync] [Sync]
@@ -78,6 +84,9 @@ namespace OpenRA.Mods.Common.Projectiles
else else
anim.PlayRepeating(info.Sequences.Random(args.SourceActor.World.SharedRandom)); anim.PlayRepeating(info.Sequences.Random(args.SourceActor.World.SharedRandom));
} }
shadowColor = new float3(info.ShadowColor.R, info.ShadowColor.G, info.ShadowColor.B) / 255f;
shadowAlpha = info.ShadowColor.A;
} }
public void Tick(World world) public void Tick(World world)
@@ -115,8 +124,10 @@ namespace OpenRA.Mods.Common.Projectiles
{ {
var dat = world.Map.DistanceAboveTerrain(pos); var dat = world.Map.DistanceAboveTerrain(pos);
var shadowPos = pos - new WVec(0, 0, dat.Length); var shadowPos = pos - new WVec(0, 0, dat.Length);
foreach (var r in anim.Render(shadowPos, wr.Palette(info.ShadowPalette))) foreach (var r in anim.Render(shadowPos, wr.Palette(info.Palette)))
yield return r; yield return ((IModifyableRenderable)r)
.WithTint(shadowColor, ((IModifyableRenderable)r).TintModifiers | TintModifiers.ReplaceColor)
.WithAlpha(shadowAlpha);
} }
var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : "")); var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : ""));

View File

@@ -37,9 +37,12 @@ namespace OpenRA.Mods.Common.Projectiles
[Desc("Palette is a player palette BaseName")] [Desc("Palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false; public readonly bool IsPlayerPalette = false;
[Desc("Should the projectile's shadow be rendered?")] [Desc("Does this projectile have a shadow?")]
public readonly bool Shadow = false; public readonly bool Shadow = false;
[Desc("Color to draw shadow if Shadow is true.")]
public readonly Color ShadowColor = Color.FromArgb(140, 0, 0, 0);
[Desc("Minimum vertical launch angle (pitch).")] [Desc("Minimum vertical launch angle (pitch).")]
public readonly WAngle MinimumLaunchAngle = new WAngle(-64); public readonly WAngle MinimumLaunchAngle = new WAngle(-64);
@@ -180,6 +183,9 @@ namespace OpenRA.Mods.Common.Projectiles
readonly WAngle minLaunchAngle; readonly WAngle minLaunchAngle;
readonly WAngle maxLaunchAngle; readonly WAngle maxLaunchAngle;
readonly float3 shadowColor;
readonly float shadowAlpha;
int ticks; int ticks;
int ticksToNextSmoke; int ticksToNextSmoke;
@@ -264,6 +270,9 @@ namespace OpenRA.Mods.Common.Projectiles
trailPalette = info.TrailPalette; trailPalette = info.TrailPalette;
if (info.TrailUsePlayerPalette) if (info.TrailUsePlayerPalette)
trailPalette += args.SourceActor.Owner.InternalName; trailPalette += args.SourceActor.Owner.InternalName;
shadowColor = new float3(info.ShadowColor.R, info.ShadowColor.G, info.ShadowColor.B) / 255f;
shadowAlpha = info.ShadowColor.A;
} }
static int LoopRadius(int speed, int rot) static int LoopRadius(int speed, int rot)
@@ -916,8 +925,10 @@ namespace OpenRA.Mods.Common.Projectiles
{ {
var dat = world.Map.DistanceAboveTerrain(pos); var dat = world.Map.DistanceAboveTerrain(pos);
var shadowPos = pos - new WVec(0, 0, dat.Length); var shadowPos = pos - new WVec(0, 0, dat.Length);
foreach (var r in anim.Render(shadowPos, wr.Palette("shadow"))) foreach (var r in anim.Render(shadowPos, wr.Palette(info.Palette)))
yield return r; yield return ((IModifyableRenderable)r)
.WithTint(shadowColor, ((IModifyableRenderable)r).TintModifiers | TintModifiers.ReplaceColor)
.WithAlpha(shadowAlpha);
} }
var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : "")); var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : ""));

View File

@@ -53,9 +53,8 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Paradropped unit's shadow sequence.")] [Desc("Paradropped unit's shadow sequence.")]
public readonly string ShadowSequence = null; public readonly string ShadowSequence = null;
[PaletteReference(false)] [Desc("Color to render the paradropped unit's shadow.")]
[Desc("Palette used to render the paradropped unit's shadow.")] public readonly Color ShadowColor = Color.FromArgb(140, 0, 0, 0);
public readonly string ShadowPalette = "shadow";
[Desc("Shadow position relative to the paradropped unit's intended landing position.")] [Desc("Shadow position relative to the paradropped unit's intended landing position.")]
public readonly WVec ShadowOffset = new WVec(0, 128, 0); public readonly WVec ShadowOffset = new WVec(0, 128, 0);
@@ -108,6 +107,8 @@ namespace OpenRA.Mods.Common.Traits.Render
readonly Animation shadow; readonly Animation shadow;
readonly AnimationWithOffset anim; readonly AnimationWithOffset anim;
readonly WithParachuteInfo info; readonly WithParachuteInfo info;
readonly float3 shadowColor;
readonly float shadowAlpha;
bool renderProlonged = false; bool renderProlonged = false;
@@ -135,6 +136,9 @@ namespace OpenRA.Mods.Common.Traits.Render
var rs = self.Trait<RenderSprites>(); var rs = self.Trait<RenderSprites>();
rs.Add(anim, info.Palette, info.IsPlayerPalette); rs.Add(anim, info.Palette, info.IsPlayerPalette);
shadowColor = new float3(info.ShadowColor.R, info.ShadowColor.G, info.ShadowColor.B) / 255f;
shadowAlpha = info.ShadowColor.A / 255f;
} }
protected override void TraitEnabled(Actor self) protected override void TraitEnabled(Actor self)
@@ -175,9 +179,9 @@ namespace OpenRA.Mods.Common.Traits.Render
var dat = self.World.Map.DistanceAboveTerrain(self.CenterPosition); var dat = self.World.Map.DistanceAboveTerrain(self.CenterPosition);
var pos = self.CenterPosition - new WVec(0, 0, dat.Length); var pos = self.CenterPosition - new WVec(0, 0, dat.Length);
var palette = wr.Palette(info.ShadowPalette); var palette = wr.Palette(info.Palette);
var tintModifiers = shadow.CurrentSequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None; var tintModifiers = shadow.CurrentSequence.IgnoreWorldTint ? TintModifiers.ReplaceColor | TintModifiers.IgnoreWorldTint : TintModifiers.ReplaceColor;
return new IRenderable[] { new SpriteRenderable(shadow.Image, pos, info.ShadowOffset, info.ShadowZOffset, palette, shadow.CurrentSequence.Scale, true, tintModifiers) }; return new IRenderable[] { new SpriteRenderable(shadow.Image, pos, info.ShadowOffset, info.ShadowZOffset, palette, 1, shadowAlpha, shadowColor, tintModifiers, true) };
} }
IEnumerable<Rectangle> IRender.ScreenBounds(Actor self, WorldRenderer wr) IEnumerable<Rectangle> IRender.ScreenBounds(Actor self, WorldRenderer wr)

View File

@@ -20,8 +20,8 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Clones the actor sprite with another palette below it.")] [Desc("Clones the actor sprite with another palette below it.")]
public class WithShadowInfo : ConditionalTraitInfo public class WithShadowInfo : ConditionalTraitInfo
{ {
[PaletteReference] [Desc("Color to draw shadow.")]
public readonly string Palette = "shadow"; public readonly Color ShadowColor = Color.FromArgb(140, 0, 0, 0);
[Desc("Shadow position offset relative to actor position (ground level).")] [Desc("Shadow position offset relative to actor position (ground level).")]
public readonly WVec Offset = WVec.Zero; public readonly WVec Offset = WVec.Zero;
@@ -35,11 +35,15 @@ namespace OpenRA.Mods.Common.Traits.Render
public class WithShadow : ConditionalTrait<WithShadowInfo>, IRenderModifier public class WithShadow : ConditionalTrait<WithShadowInfo>, IRenderModifier
{ {
readonly WithShadowInfo info; readonly WithShadowInfo info;
readonly float3 shadowColor;
readonly float shadowAlpha;
public WithShadow(WithShadowInfo info) public WithShadow(WithShadowInfo info)
: base(info) : base(info)
{ {
this.info = info; this.info = info;
shadowColor = new float3(info.ShadowColor.R, info.ShadowColor.G, info.ShadowColor.B) / 255f;
shadowAlpha = info.ShadowColor.A / 255f;
} }
IEnumerable<IRenderable> IRenderModifier.ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r) IEnumerable<IRenderable> IRenderModifier.ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
@@ -47,12 +51,12 @@ namespace OpenRA.Mods.Common.Traits.Render
if (IsTraitDisabled) if (IsTraitDisabled)
return r; return r;
// Contrails shouldn't cast shadows
var height = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length; var height = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length;
var shadowSprites = r.Where(s => !s.IsDecoration && s is IPalettedRenderable) var shadowSprites = r.Where(s => !s.IsDecoration && s is IModifyableRenderable)
.Select(a => ((IPalettedRenderable)a).WithPalette(wr.Palette(info.Palette)) .Select(ma => ((IModifyableRenderable)ma).WithTint(shadowColor, ((IModifyableRenderable)ma).TintModifiers | TintModifiers.ReplaceColor)
.WithAlpha(shadowAlpha)
.OffsetBy(info.Offset - new WVec(0, 0, height)) .OffsetBy(info.Offset - new WVec(0, 0, height))
.WithZOffset(a.ZOffset + (height + info.ZOffset)) .WithZOffset(ma.ZOffset + (height + info.ZOffset))
.AsDecoration()); .AsDecoration());
return shadowSprites.Concat(r); return shadowSprites.Concat(r);

View File

@@ -0,0 +1,64 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 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, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class ReplaceShadowPalette : UpdateRule
{
public override string Name { get { return "Removed ShadowPalette from WithShadow and projectiles."; } }
public override string Description
{
get
{
return "The ShadowPalette field has been replaced by ShadowColor on projectiles.\n" +
"The Palette field on WithShadow and ShadowPalette on WithParachute have similarly been replaced with ShadowColor.";
}
}
readonly List<string> locations = new List<string>();
public override IEnumerable<string> AfterUpdate(ModData modData)
{
if (locations.Any())
yield return "The shadow palette overrides have been removed from the following locations:\n" +
UpdateUtils.FormatMessageList(locations) + "\n\n" +
"You may wish to inspect and change these.";
locations.Clear();
}
public override IEnumerable<string> UpdateWeaponNode(ModData modData, MiniYamlNode weaponNode)
{
foreach (var projectileNode in weaponNode.ChildrenMatching("Projectile"))
if (projectileNode.RemoveNodes("ShadowPalette") > 0)
locations.Add("{0}: {1} ({2})".F(weaponNode.Key, weaponNode.Key, weaponNode.Location.Filename));
yield break;
}
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var node in actorNode.ChildrenMatching("WithShadow"))
if (node.RemoveNodes("Palette") > 0)
locations.Add("{0}: {1} ({2})".F(actorNode.Key, node.Key, actorNode.Location.Filename));
foreach (var node in actorNode.ChildrenMatching("WithParachute"))
if (node.RemoveNodes("ShadowPalette") > 0)
locations.Add("{0}: {1} ({2})".F(actorNode.Key, node.Key, actorNode.Location.Filename));
yield break;
}
}
}

View File

@@ -89,6 +89,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new ReplaceWithColoredOverlayPalette(), new ReplaceWithColoredOverlayPalette(),
new RemoveRenderSpritesScale(), new RemoveRenderSpritesScale(),
new RemovePlaceBuildingPalette(), new RemovePlaceBuildingPalette(),
new ReplaceShadowPalette(),
}) })
}; };