From 1809817b3f93c45fdb9181ad201b12a393e4a0d2 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+PunkPun@users.noreply.github.com> Date: Wed, 24 Aug 2022 16:25:07 +0300 Subject: [PATCH] Add ContrailEndColor and Contrail transparency control --- .../Graphics/ContrailRenderable.cs | 28 ++++------- OpenRA.Mods.Common/Projectiles/Bullet.cs | 25 ++++++++-- OpenRA.Mods.Common/Projectiles/Missile.cs | 22 ++++++-- OpenRA.Mods.Common/Traits/Render/Contrail.cs | 36 +++++++++---- .../20210321/RenameContrailProperties.cs | 50 +++++++++++++++++++ OpenRA.Mods.Common/UpdateRules/UpdatePath.cs | 1 + mods/cnc/rules/aircraft.yaml | 6 +++ mods/cnc/rules/campaign-palettes.yaml | 8 +-- mods/ra/rules/aircraft.yaml | 7 +++ 9 files changed, 143 insertions(+), 40 deletions(-) create mode 100644 OpenRA.Mods.Common/UpdateRules/Rules/20210321/RenameContrailProperties.cs diff --git a/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs b/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs index 4ebc0b17a8..9856f1d7cc 100644 --- a/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/ContrailRenderable.cs @@ -22,7 +22,8 @@ namespace OpenRA.Mods.Common.Graphics public int Length => trail.Length; readonly World world; - readonly Color color; + readonly Color startcolor; + readonly Color endcolor; readonly int zOffset; // Store trail positions in a circular buffer @@ -32,10 +33,10 @@ namespace OpenRA.Mods.Common.Graphics int length; readonly int skip; - public ContrailRenderable(World world, Color color, WDist width, int length, int skip, int zOffset) - : this(world, new WPos[length], width, 0, 0, skip, color, zOffset) { } + public ContrailRenderable(World world, Color startcolor, Color endcolor, WDist width, int length, int skip, int zOffset) + : this(world, new WPos[length], width, 0, 0, skip, startcolor, endcolor, zOffset) { } - ContrailRenderable(World world, WPos[] trail, WDist width, int next, int length, int skip, Color color, int zOffset) + ContrailRenderable(World world, WPos[] trail, WDist width, int next, int length, int skip, Color startcolor, Color endcolor, int zOffset) { this.world = world; this.trail = trail; @@ -43,7 +44,8 @@ namespace OpenRA.Mods.Common.Graphics this.next = next; this.length = length; this.skip = skip; - this.color = color; + this.startcolor = startcolor; + this.endcolor = endcolor; this.zOffset = zOffset; } @@ -51,13 +53,12 @@ namespace OpenRA.Mods.Common.Graphics public int ZOffset => zOffset; public bool IsDecoration => true; - public IRenderable WithZOffset(int newOffset) { return new ContrailRenderable(world, (WPos[])trail.Clone(), width, next, length, skip, color, newOffset); } - + public IRenderable WithZOffset(int newOffset) { return new ContrailRenderable(world, (WPos[])trail.Clone(), width, next, length, skip, startcolor, endcolor, newOffset); } public IRenderable OffsetBy(in WVec vec) { // Lambdas can't use 'in' variables, so capture a copy for later var offset = vec; - return new ContrailRenderable(world, trail.Select(pos => pos + offset).ToArray(), width, next, length, skip, color, zOffset); + return new ContrailRenderable(world, trail.Select(pos => pos + offset).ToArray(), width, next, length, skip, startcolor, endcolor, zOffset); } public IRenderable AsDecoration() { return this; } @@ -76,13 +77,12 @@ namespace OpenRA.Mods.Common.Graphics // Start of the first line segment is the tail of the list - don't smooth it. var curPos = trail[Index(next - skip - 1)]; - var curColor = color; + var curColor = startcolor; for (var i = 1; i < renderLength; i++) { var j = next - skip - 1 - i; - var alpha = ((renderLength - i) * color.A + renderLength - 1) / renderLength; - var nextColor = Color.FromArgb(alpha, color); + var nextColor = Exts.ColorLerp(i * 1f / (renderLength - 1), startcolor, endcolor); var nextX = 0L; var nextY = 0L; @@ -124,11 +124,5 @@ namespace OpenRA.Mods.Common.Graphics if (length < trail.Length) length++; } - - public static Color ChooseColor(Actor self) - { - var ownerColor = Color.FromArgb(255, self.Owner.Color); - return Exts.ColorLerp(0.5f, ownerColor, Color.White); - } } } diff --git a/OpenRA.Mods.Common/Projectiles/Bullet.cs b/OpenRA.Mods.Common/Projectiles/Bullet.cs index 8b1b3e7689..f6279a844a 100644 --- a/OpenRA.Mods.Common/Projectiles/Bullet.cs +++ b/OpenRA.Mods.Common/Projectiles/Bullet.cs @@ -103,8 +103,6 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("When set, display a line behind the actor. Length is measured in ticks after appearing.")] public readonly int ContrailLength = 0; - public readonly Color ContrailColor = Color.White; - public readonly bool ContrailUsePlayerColor = false; [Desc("Time (in ticks) after which the line should appear. Controls the distance to the actor.")] public readonly int ContrailDelay = 1; @@ -115,6 +113,24 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Thickness of the emitted line.")] public readonly WDist ContrailWidth = new WDist(64); + [Desc("RGB color at the contrail start.")] + public readonly Color ContrailStartColor = Color.White; + + [Desc("Use player remap color instead of a custom color at the contrail the start.")] + public readonly bool ContrailStartColorUsePlayerColor = false; + + [Desc("The alpha value [from 0 to 255] of color at the contrail the start.")] + public readonly int ContrailStartColorAlpha = 255; + + [Desc("RGB color at the contrail end. Set to start color if undefined")] + public readonly Color? ContrailEndColor; + + [Desc("Use player remap color instead of a custom color at the contrail end.")] + public readonly bool ContrailEndColorUsePlayerColor = false; + + [Desc("The alpha value [from 0 to 255] of color at the contrail end.")] + public readonly int ContrailEndColorAlpha = 0; + public IProjectile Create(ProjectileArgs args) { return new Bullet(this, args); } } @@ -180,8 +196,9 @@ namespace OpenRA.Mods.Common.Projectiles if (info.ContrailLength > 0) { - var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; - contrail = new ContrailRenderable(world, color, info.ContrailWidth, info.ContrailLength, info.ContrailDelay, info.ContrailZOffset); + var startcolor = info.ContrailStartColorUsePlayerColor ? Color.FromArgb(info.ContrailStartColorAlpha, args.SourceActor.Owner.Color) : Color.FromArgb(info.ContrailStartColorAlpha, info.ContrailStartColor); + var endcolor = info.ContrailEndColorUsePlayerColor ? Color.FromArgb(info.ContrailEndColorAlpha, args.SourceActor.Owner.Color) : Color.FromArgb(info.ContrailEndColorAlpha, info.ContrailEndColor ?? info.ContrailStartColor); + contrail = new ContrailRenderable(world, startcolor, endcolor, info.ContrailWidth, info.ContrailLength, info.ContrailDelay, info.ContrailZOffset); } trailPalette = info.TrailPalette; diff --git a/OpenRA.Mods.Common/Projectiles/Missile.cs b/OpenRA.Mods.Common/Projectiles/Missile.cs index 4472744138..82ccb74d66 100644 --- a/OpenRA.Mods.Common/Projectiles/Missile.cs +++ b/OpenRA.Mods.Common/Projectiles/Missile.cs @@ -142,10 +142,23 @@ namespace OpenRA.Mods.Common.Projectiles [Desc("Thickness of the emitted line.")] public readonly WDist ContrailWidth = new WDist(64); - public readonly Color ContrailColor = Color.White; + [Desc("RGB color at the contrail start.")] + public readonly Color ContrailStartColor = Color.White; - public readonly bool ContrailUsePlayerColor = false; + [Desc("Use player remap color instead of a custom color at the contrail the start.")] + public readonly bool ContrailStartColorUsePlayerColor = false; + [Desc("The alpha value [from 0 to 255] of color at the contrail the start.")] + public readonly int ContrailStartColorAlpha = 255; + + [Desc("RGB color at the contrail end. Set to start color if undefined")] + public readonly Color? ContrailEndColor; + + [Desc("Use player remap color instead of a custom color at the contrail end.")] + public readonly bool ContrailEndColorUsePlayerColor = false; + + [Desc("The alpha value [from 0 to 255] of color at the contrail end.")] + public readonly int ContrailEndColorAlpha = 0; [Desc("Should missile targeting be thrown off by nearby actors with JamsMissiles.")] public readonly bool Jammable = true; @@ -269,8 +282,9 @@ namespace OpenRA.Mods.Common.Projectiles if (info.ContrailLength > 0) { - var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; - contrail = new ContrailRenderable(world, color, info.ContrailWidth, info.ContrailLength, info.ContrailDelay, info.ContrailZOffset); + var startcolor = info.ContrailStartColorUsePlayerColor ? Color.FromArgb(info.ContrailStartColorAlpha, args.SourceActor.Owner.Color) : Color.FromArgb(info.ContrailStartColorAlpha, info.ContrailStartColor); + var endcolor = info.ContrailEndColorUsePlayerColor ? Color.FromArgb(info.ContrailEndColorAlpha, args.SourceActor.Owner.Color) : Color.FromArgb(info.ContrailEndColorAlpha, info.ContrailEndColor ?? info.ContrailStartColor); + contrail = new ContrailRenderable(world, startcolor, endcolor, info.ContrailWidth, info.ContrailLength, info.ContrailDelay, info.ContrailZOffset); } trailPalette = info.TrailPalette; diff --git a/OpenRA.Mods.Common/Traits/Render/Contrail.cs b/OpenRA.Mods.Common/Traits/Render/Contrail.cs index 3e40600d8c..19822d2033 100644 --- a/OpenRA.Mods.Common/Traits/Render/Contrail.cs +++ b/OpenRA.Mods.Common/Traits/Render/Contrail.cs @@ -24,23 +24,35 @@ namespace OpenRA.Mods.Common.Traits [Desc("Position relative to body")] public readonly WVec Offset = WVec.Zero; - [Desc("Offset for Z sorting.")] + [Desc("Equivalent to sequence ZOffset. Controls Z sorting.")] public readonly int ZOffset = 0; - [Desc("Length of the trail (in ticks).")] + [Desc("When set, display a line behind the actor. Length is measured in ticks after appearing.")] public readonly int TrailLength = 25; [Desc("Time (in ticks) after which the line should appear. Controls the distance to the actor.")] public readonly int TrailDelay = 0; - [Desc("Width of the trail.")] + [Desc("Thickness of the emitted line.")] public readonly WDist TrailWidth = new WDist(64); - [Desc("RGB color of the contrail.")] - public readonly Color Color = Color.White; + [Desc("RGB color at the contrail start.")] + public readonly Color StartColor = Color.White; - [Desc("Use player remap color instead of a custom color?")] - public readonly bool UsePlayerColor = true; + [Desc("Use player remap color instead of a custom color at the contrail the start.")] + public readonly bool StartColorUsePlayerColor = true; + + [Desc("The alpha value [from 0 to 255] of color at the contrail the start.")] + public readonly int StartColorAlpha = 255; + + [Desc("RGB color at the contrail end. Set to start color if undefined")] + public readonly Color? EndColor; + + [Desc("Use player remap color instead of a custom color at the contrail end.")] + public readonly bool EndColorUsePlayerColor = false; + + [Desc("The alpha value [from 0 to 255] of color at the contrail end.")] + public readonly int EndColorAlpha = 0; public override object Create(ActorInitializer init) { return new Contrail(init.Self, this); } } @@ -49,7 +61,8 @@ namespace OpenRA.Mods.Common.Traits { readonly ContrailInfo info; readonly BodyOrientation body; - readonly Color color; + readonly Color startcolor; + readonly Color endcolor; // This is a mutable struct, so it can't be readonly. ContrailRenderable trail; @@ -59,8 +72,9 @@ namespace OpenRA.Mods.Common.Traits { this.info = info; - color = info.UsePlayerColor ? ContrailRenderable.ChooseColor(self) : info.Color; - trail = new ContrailRenderable(self.World, color, info.TrailWidth, info.TrailLength, info.TrailDelay, info.ZOffset); + startcolor = info.StartColorUsePlayerColor ? Color.FromArgb(info.StartColorAlpha, self.Owner.Color) : Color.FromArgb(info.StartColorAlpha, info.StartColor); + endcolor = info.EndColorUsePlayerColor ? Color.FromArgb(info.EndColorAlpha, self.Owner.Color) : Color.FromArgb(info.EndColorAlpha, info.EndColor ?? info.StartColor); + trail = new ContrailRenderable(self.World, startcolor, endcolor, info.TrailWidth, info.TrailLength, info.TrailDelay, info.ZOffset); body = self.Trait(); } @@ -89,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits void INotifyAddedToWorld.AddedToWorld(Actor self) { - trail = new ContrailRenderable(self.World, color, info.TrailWidth, info.TrailLength, info.TrailDelay, info.ZOffset); + trail = new ContrailRenderable(self.World, startcolor, endcolor, info.TrailWidth, info.TrailLength, info.TrailDelay, info.ZOffset); } } } diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20210321/RenameContrailProperties.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20210321/RenameContrailProperties.cs new file mode 100644 index 0000000000..48138e5a79 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20210321/RenameContrailProperties.cs @@ -0,0 +1,50 @@ +#region Copyright & License Information +/* + * Copyright 2007-2022 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; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class RenameContrailProperties : UpdateRule + { + public override string Name => "Rename contrail color properties"; + + public override string Description => "Rename contrail color properties `Color` to `StartColor` and `UsePlayerColor` to `StartColorUsePlayerColor` in traits and weapons to acount for added `EndColor` functionality"; + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + foreach (var traitNode in actorNode.ChildrenMatching("Contrail")) + traitNode.RenameChildrenMatching("Color", "StartColor"); + + foreach (var traitNode in actorNode.ChildrenMatching("Contrail")) + traitNode.RenameChildrenMatching("UsePlayerColor", "StartColorUsePlayerColor"); + + yield break; + } + + public override IEnumerable UpdateWeaponNode(ModData modData, MiniYamlNode weaponNode) + { + foreach (var traitNode in weaponNode.ChildrenMatching("Missile")) + traitNode.RenameChildrenMatching("ContrailColor", "ContrailStartColor"); + + foreach (var traitNode in weaponNode.ChildrenMatching("Missile")) + traitNode.RenameChildrenMatching("ContrailUsePlayerColor", "ContrailStartColorUsePlayerColor"); + + foreach (var traitNode in weaponNode.ChildrenMatching("Bullet")) + traitNode.RenameChildrenMatching("ContrailColor", "ContrailStartColor"); + + foreach (var traitNode in weaponNode.ChildrenMatching("Bullet")) + traitNode.RenameChildrenMatching("ContrailUsePlayerColor", "ContrailStartColorUsePlayerColor"); + + yield break; + } + } +} diff --git a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs index 928ec9840d..d4731567a2 100644 --- a/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs +++ b/OpenRA.Mods.Common/UpdateRules/UpdatePath.cs @@ -96,6 +96,7 @@ namespace OpenRA.Mods.Common.UpdateRules new ReplaceSequenceEmbeddedPalette(), new UnhardcodeBaseBuilderBotModule(), new UnhardcodeVeteranProductionIconOverlay(), + new RenameContrailProperties(), }) }; diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 39207b3b7e..4341692000 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -213,15 +213,19 @@ C17: Contrail@1: Offset: -261,-650,0 TrailLength: 15 + StartColorAlpha: 128 Contrail@2: Offset: -85,-384,0 TrailLength: 16 + StartColorAlpha: 128 Contrail@3: Offset: -85,384,0 TrailLength: 16 + StartColorAlpha: 128 Contrail@4: Offset: -261,650,0 TrailLength: 15 + StartColorAlpha: 128 -MapEditorData: A10: @@ -252,9 +256,11 @@ A10: Contrail@1: Offset: -640,171,0 TrailLength: 15 + StartColorAlpha: 128 Contrail@2: Offset: -640,-171,0 TrailLength: 15 + StartColorAlpha: 128 -MapEditorData: TRAN.Husk: diff --git a/mods/cnc/rules/campaign-palettes.yaml b/mods/cnc/rules/campaign-palettes.yaml index c03156ef9a..80f5e43425 100644 --- a/mods/cnc/rules/campaign-palettes.yaml +++ b/mods/cnc/rules/campaign-palettes.yaml @@ -42,13 +42,13 @@ C17: RenderSprites: PlayerPalette: player-units Contrail@1: - UsePlayerColor: False + StartColorUsePlayerColor: False Contrail@2: - UsePlayerColor: False + StartColorUsePlayerColor: False Contrail@3: - UsePlayerColor: False + StartColorUsePlayerColor: False Contrail@4: - UsePlayerColor: False + StartColorUsePlayerColor: False HARV: RenderSprites: diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index e8d3b4afaf..d4f11c1e52 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -20,8 +20,10 @@ BADR: Name: Badger Contrail@1: Offset: -432,560,0 + StartColorAlpha: 128 Contrail@2: Offset: -432,-560,0 + StartColorAlpha: 128 SpawnActorOnDeath: Actor: BADR.Husk LeavesTrails@0: @@ -110,8 +112,10 @@ MIG: DecorationBounds: 1706, 1237, 0, 42 Contrail@1: Offset: -598,-683,0 + StartColorAlpha: 128 Contrail@2: Offset: -598,683,0 + StartColorAlpha: 128 SpawnActorOnDeath: Actor: MIG.Husk LeavesTrails: @@ -191,6 +195,7 @@ YAK: WithMuzzleOverlay: Contrail: Offset: -853,0,0 + StartColorAlpha: 128 SpawnActorOnDeath: Actor: YAK.Husk LeavesTrails: @@ -458,8 +463,10 @@ U2: -Targetable@AIRBORNE: Contrail@1: Offset: -725,683,0 + StartColorAlpha: 128 Contrail@2: Offset: -725,-683,0 + StartColorAlpha: 128 SpawnActorOnDeath: Actor: U2.Husk LeavesTrails: