From defba7aeced075f760214db8aaabe4023660d274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 19 Sep 2015 20:25:46 +0200 Subject: [PATCH] lint check player palette reference and tell which actor is affected when a problem is found --- OpenRA.Game/Traits/LintAttributes.cs | 25 +++++- .../Traits/Player/PlayerColorPalette.cs | 2 +- .../Traits/Player/PlayerHighlightPalette.cs | 2 +- OpenRA.Mods.Common/Effects/Bullet.cs | 3 +- OpenRA.Mods.Common/Effects/Missile.cs | 5 +- OpenRA.Mods.Common/Lint/CheckPalettes.cs | 77 +++++++++++++++---- .../Traits/Buildings/RallyPoint.cs | 2 +- OpenRA.Mods.Common/Traits/Cloak.cs | 2 +- .../Traits/Render/RenderSprites.cs | 2 +- .../Render/WithBuildingPlacedOverlay.cs | 2 +- .../Traits/Render/WithChargeOverlay.cs | 2 +- .../Traits/Render/WithDeathAnimation.cs | 4 +- .../Traits/Render/WithDockingOverlay.cs | 2 +- .../Traits/Render/WithIdleOverlay.cs | 2 +- .../Traits/Render/WithProductionOverlay.cs | 2 +- .../Traits/Render/WithRepairOverlay.cs | 2 +- .../PaletteFromPlayerPaletteWithAlpha.cs | 4 +- .../World/PlayerPaletteFromCurrentTileset.cs | 2 +- .../Warheads/CreateEffectWarhead.cs | 2 +- .../Traits/Render/WithAttackOverlay.cs | 2 +- .../Traits/Render/WithCrumbleOverlay.cs | 2 +- .../Traits/Render/WithDeliveryOverlay.cs | 2 +- 22 files changed, 110 insertions(+), 40 deletions(-) diff --git a/OpenRA.Game/Traits/LintAttributes.cs b/OpenRA.Game/Traits/LintAttributes.cs index 6efbd58c67..b339b5fae5 100644 --- a/OpenRA.Game/Traits/LintAttributes.cs +++ b/OpenRA.Game/Traits/LintAttributes.cs @@ -45,9 +45,28 @@ namespace OpenRA.Traits public sealed class UpgradeUsedReferenceAttribute : Attribute { } [AttributeUsage(AttributeTargets.Field)] - public sealed class PaletteDefinitionAttribute : Attribute { } + public sealed class PaletteDefinitionAttribute : Attribute + { + public readonly bool IsPlayerPalette; + public PaletteDefinitionAttribute(bool isPlayerPalette = false) + { + IsPlayerPalette = isPlayerPalette; + } + } - // TODO: differentiate player palettes [AttributeUsage(AttributeTargets.Field)] - public sealed class PaletteReferenceAttribute : Attribute { } + public sealed class PaletteReferenceAttribute : Attribute + { + public readonly bool IsPlayerPalette; + public PaletteReferenceAttribute(bool isPlayerPalette = false) + { + IsPlayerPalette = isPlayerPalette; + } + + public readonly string PlayerPaletteReferenceSwitch; + public PaletteReferenceAttribute(string playerPaletteReferenceSwitch) + { + PlayerPaletteReferenceSwitch = playerPaletteReferenceSwitch; + } + } } diff --git a/OpenRA.Game/Traits/Player/PlayerColorPalette.cs b/OpenRA.Game/Traits/Player/PlayerColorPalette.cs index 9942af3db3..2ab28ec136 100644 --- a/OpenRA.Game/Traits/Player/PlayerColorPalette.cs +++ b/OpenRA.Game/Traits/Player/PlayerColorPalette.cs @@ -20,7 +20,7 @@ namespace OpenRA.Traits [PaletteReference] public readonly string BasePalette = null; [Desc("The prefix for the resulting player palettes")] - public readonly string BaseName = "player"; + [PaletteDefinition(true)] public readonly string BaseName = "player"; [Desc("Remap these indices to player colors.")] public readonly int[] RemapIndex = { }; diff --git a/OpenRA.Game/Traits/Player/PlayerHighlightPalette.cs b/OpenRA.Game/Traits/Player/PlayerHighlightPalette.cs index 5990b5647e..08e2a5753f 100644 --- a/OpenRA.Game/Traits/Player/PlayerHighlightPalette.cs +++ b/OpenRA.Game/Traits/Player/PlayerHighlightPalette.cs @@ -19,7 +19,7 @@ namespace OpenRA.Traits public class PlayerHighlightPaletteInfo : ITraitInfo { [Desc("The prefix for the resulting player palettes")] - public readonly string BaseName = "highlight"; + [PaletteDefinition(true)] public readonly string BaseName = "highlight"; public object Create(ActorInitializer init) { return new PlayerHighlightPalette(this); } } diff --git a/OpenRA.Mods.Common/Effects/Bullet.cs b/OpenRA.Mods.Common/Effects/Bullet.cs index ac65568ad7..4f2b087757 100644 --- a/OpenRA.Mods.Common/Effects/Bullet.cs +++ b/OpenRA.Mods.Common/Effects/Bullet.cs @@ -58,8 +58,9 @@ namespace OpenRA.Mods.Common.Effects [Desc("Delay in ticks until trail animaion is spawned.")] public readonly int TrailDelay = 1; - public readonly string TrailPalette = "effect"; + [PaletteReference("TrailUsePlayerPalette")] public readonly string TrailPalette = "effect"; public readonly bool TrailUsePlayerPalette = false; + public readonly int ContrailLength = 0; public readonly Color ContrailColor = Color.White; public readonly bool ContrailUsePlayerColor = false; diff --git a/OpenRA.Mods.Common/Effects/Missile.cs b/OpenRA.Mods.Common/Effects/Missile.cs index f2499abab7..8740be76d1 100644 --- a/OpenRA.Mods.Common/Effects/Missile.cs +++ b/OpenRA.Mods.Common/Effects/Missile.cs @@ -59,10 +59,9 @@ namespace OpenRA.Mods.Common.Effects [Desc("Interval in ticks between each spawned Trail animation.")] public readonly int TrailInterval = 2; - // TODO: Re-add PaletteReference as soon as it handles player palettes - public readonly string TrailPalette = "effect"; - + [PaletteReference("TrailUsePlayerPalette")] public readonly string TrailPalette = "effect"; public readonly bool TrailUsePlayerPalette = false; + public readonly int ContrailLength = 0; public readonly Color ContrailColor = Color.White; public readonly bool ContrailUsePlayerColor = false; diff --git a/OpenRA.Mods.Common/Lint/CheckPalettes.cs b/OpenRA.Mods.Common/Lint/CheckPalettes.cs index c811792b3b..af4d4efe10 100644 --- a/OpenRA.Mods.Common/Lint/CheckPalettes.cs +++ b/OpenRA.Mods.Common/Lint/CheckPalettes.cs @@ -18,9 +18,12 @@ namespace OpenRA.Mods.Common.Lint { class CheckPalettes : ILintRulesPass { + List palettes = new List(); + List playerPalettes = new List(); + public void Run(Action emitError, Action emitWarning, Ruleset rules) { - var palettes = GetPalettes(emitError, rules).ToList(); + GetPalettes(emitError, rules); foreach (var actorInfo in rules.Actors) { @@ -29,14 +32,36 @@ namespace OpenRA.Mods.Common.Lint var fields = traitInfo.GetType().GetFields(); foreach (var field in fields.Where(x => x.HasAttribute())) { + var isPlayerPalette = false; + + var paletteReference = field.GetCustomAttributes(true).FirstOrDefault(); + if (paletteReference != null) + { + if (!string.IsNullOrEmpty(paletteReference.PlayerPaletteReferenceSwitch)) + { + var fieldInfo = fields.First(f => f.Name == paletteReference.PlayerPaletteReferenceSwitch); + isPlayerPalette = (bool)fieldInfo.GetValue(traitInfo); + } + else + isPlayerPalette = paletteReference.IsPlayerPalette; + } + var references = LintExts.GetFieldValues(traitInfo, field, emitError); foreach (var reference in references) { if (string.IsNullOrEmpty(reference)) continue; - if (!palettes.Contains(reference)) - emitError("Undefined palette reference {0} detected at {1}".F(reference, traitInfo)); + if (isPlayerPalette) + { + if (!playerPalettes.Contains(reference)) + emitError("Undefined player palette reference {0} detected at {1} for {2}".F(reference, traitInfo, actorInfo.Key)); + } + else + { + if (!palettes.Contains(reference)) + emitError("Undefined palette reference {0} detected at {1} for {2}".F(reference, traitInfo, actorInfo.Key)); + } } } } @@ -48,16 +73,36 @@ namespace OpenRA.Mods.Common.Lint if (projectileInfo == null) continue; - foreach (var field in projectileInfo.GetType().GetFields()) + var fields = projectileInfo.GetType().GetFields(); + foreach (var field in fields.Where(x => x.HasAttribute())) { - if (field.HasAttribute()) - { - var references = LintExts.GetFieldValues(projectileInfo, field, emitError); - foreach (var reference in references) - { - if (string.IsNullOrEmpty(reference)) - continue; + var isPlayerPalette = false; + var paletteReference = field.GetCustomAttributes(true).First(); + if (paletteReference != null) + { + if (!string.IsNullOrEmpty(paletteReference.PlayerPaletteReferenceSwitch)) + { + var fieldInfo = fields.First(f => f.Name == paletteReference.PlayerPaletteReferenceSwitch); + isPlayerPalette = (bool)fieldInfo.GetValue(projectileInfo); + } + else + isPlayerPalette = paletteReference.IsPlayerPalette; + } + + var references = LintExts.GetFieldValues(projectileInfo, field, emitError); + foreach (var reference in references) + { + if (string.IsNullOrEmpty(reference)) + continue; + + if (isPlayerPalette) + { + if (!playerPalettes.Contains(reference)) + emitError("Undefined player palette reference {0} detected at weapon {1}.".F(reference, weaponInfo.Key)); + } + else + { if (!palettes.Contains(reference)) emitError("Undefined palette reference {0} detected at weapon {1}.".F(reference, weaponInfo.Key)); } @@ -66,7 +111,7 @@ namespace OpenRA.Mods.Common.Lint } } - static IEnumerable GetPalettes(Action emitError, Ruleset rules) + void GetPalettes(Action emitError, Ruleset rules) { foreach (var actorInfo in rules.Actors) { @@ -75,9 +120,15 @@ namespace OpenRA.Mods.Common.Lint var fields = traitInfo.GetType().GetFields(); foreach (var field in fields.Where(x => x.HasAttribute())) { + var paletteDefinition = field.GetCustomAttributes(true).First(); var values = LintExts.GetFieldValues(traitInfo, field, emitError); foreach (var value in values) - yield return value; + { + if (paletteDefinition.IsPlayerPalette) + playerPalettes.Add(value); + else + palettes.Add(value); + } } } } diff --git a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs index ccffd21692..61e5fda934 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RallyPoint.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits [SequenceReference("Image")] public readonly string CirclesSequence = "circles"; [Desc("Custom indicator palette name")] - public readonly string Palette = "player"; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = "player"; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = true; diff --git a/OpenRA.Mods.Common/Traits/Cloak.cs b/OpenRA.Mods.Common/Traits/Cloak.cs index 2302efe673..783d476423 100644 --- a/OpenRA.Mods.Common/Traits/Cloak.cs +++ b/OpenRA.Mods.Common/Traits/Cloak.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits public readonly string CloakSound = null; public readonly string UncloakSound = null; - public readonly string Palette = "cloak"; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = "cloak"; public readonly bool IsPlayerPalette = false; public readonly HashSet CloakTypes = new HashSet { "Cloak" }; diff --git a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs index c69ac9f876..870f58e8f8 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits [PaletteReference] public readonly string Palette = null; [Desc("Custom PlayerColorPalette: BaseName")] - public readonly string PlayerPalette = "player"; + [PaletteReference(true)] public readonly string PlayerPalette = "player"; [Desc("Change the sprite image size.")] public readonly float Scale = 1f; diff --git a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs index 5b8efe8418..eca03ef3f8 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithChargeOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithChargeOverlay.cs index c83a938a5d..d8ffa057b7 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithChargeOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithChargeOverlay.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits [SequenceReference] public readonly string Sequence = "active"; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs index 3a928aca4a..1689a998f8 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits [SequenceReference(null, true)] public readonly string DeathSequence = "die"; [Desc("The palette used for `DeathSequence`.")] - public readonly string DeathSequencePalette = "player"; + [PaletteReference("DeathPaletteIsPlayerPalette")] public readonly string DeathSequencePalette = "player"; [Desc("Custom death animation palette is a player palette BaseName")] public readonly bool DeathPaletteIsPlayerPalette = true; @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits [SequenceReference] public readonly string CrushedSequence = null; [Desc("The palette used for `CrushedSequence`.")] - public readonly string CrushedSequencePalette = "effect"; + [PaletteReference("CrushedPaletteIsPlayerPalette")] public readonly string CrushedSequencePalette = "effect"; [Desc("Custom crushed animation palette is a player palette BaseName")] public readonly bool CrushedPaletteIsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs index a6ba429239..e21582a98e 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index f5e3795534..ff17176474 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs index aafc89a6fc..0fa080f023 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs @@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs index 370bfb4fd1..b270703063 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.Common/Traits/World/PaletteFromPlayerPaletteWithAlpha.cs b/OpenRA.Mods.Common/Traits/World/PaletteFromPlayerPaletteWithAlpha.cs index 23bde6ab8e..fc19d01bac 100644 --- a/OpenRA.Mods.Common/Traits/World/PaletteFromPlayerPaletteWithAlpha.cs +++ b/OpenRA.Mods.Common/Traits/World/PaletteFromPlayerPaletteWithAlpha.cs @@ -21,11 +21,11 @@ namespace OpenRA.Mods.Common.Traits { [FieldLoader.Require] [Desc("The prefix for the resulting player palettes")] - public readonly string BaseName = null; + [PaletteDefinition(true)] public readonly string BaseName = null; [FieldLoader.Require] [Desc("The name of the player palette to base off.")] - public readonly string BasePalette = null; + [PaletteReference(true)] public readonly string BasePalette = null; [Desc("Allow palette modifiers to change the palette.")] public readonly bool AllowModifiers = true; diff --git a/OpenRA.Mods.Common/Traits/World/PlayerPaletteFromCurrentTileset.cs b/OpenRA.Mods.Common/Traits/World/PlayerPaletteFromCurrentTileset.cs index e71b07b4ce..ca5240b506 100644 --- a/OpenRA.Mods.Common/Traits/World/PlayerPaletteFromCurrentTileset.cs +++ b/OpenRA.Mods.Common/Traits/World/PlayerPaletteFromCurrentTileset.cs @@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits { class PlayerPaletteFromCurrentTilesetInfo : ITraitInfo { - [FieldLoader.Require, PaletteDefinition] + [FieldLoader.Require, PaletteDefinition(true)] [Desc("internal palette name")] public readonly string Name = null; [Desc("Map listed indices to shadow.")] diff --git a/OpenRA.Mods.Common/Warheads/CreateEffectWarhead.cs b/OpenRA.Mods.Common/Warheads/CreateEffectWarhead.cs index 7df037ea72..3cbd12e564 100644 --- a/OpenRA.Mods.Common/Warheads/CreateEffectWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/CreateEffectWarhead.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Warheads public readonly string Explosion = null; [Desc("Palette to use for explosion effect.")] - public readonly string ExplosionPalette = "effect"; + [PaletteReference("UsePlayerPalette")] public readonly string ExplosionPalette = "effect"; [Desc("Remap explosion effect to player color, if art supports it.")] public readonly bool UsePlayerPalette = false; diff --git a/OpenRA.Mods.D2k/Traits/Render/WithAttackOverlay.cs b/OpenRA.Mods.D2k/Traits/Render/WithAttackOverlay.cs index 923ded4c1b..541d3633b8 100644 --- a/OpenRA.Mods.D2k/Traits/Render/WithAttackOverlay.cs +++ b/OpenRA.Mods.D2k/Traits/Render/WithAttackOverlay.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.D2k.Traits [SequenceReference] public readonly string Sequence = null; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs b/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs index 7597967c7c..2b9a285f75 100644 --- a/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs +++ b/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.D2k.Traits [SequenceReference] public readonly string Sequence = "crumble-overlay"; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false; diff --git a/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs b/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs index d11e2e1bad..21bae82a23 100644 --- a/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs +++ b/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.D2k.Traits public readonly WVec Offset = WVec.Zero; [Desc("Custom palette name")] - [PaletteReference] public readonly string Palette = null; + [PaletteReference("IsPlayerPalette")] public readonly string Palette = null; [Desc("Custom palette is a player palette BaseName")] public readonly bool IsPlayerPalette = false;