Merge pull request #8685 from Mailaender/lint-projectile-sprites
Added projectile sprite testing to the CheckYaml lint rules
This commit is contained in:
@@ -31,8 +31,8 @@ namespace OpenRA.Mods.Common.Effects
|
||||
[Desc("Image to display.")]
|
||||
public readonly string Image = null;
|
||||
|
||||
[Desc("Loop this sequence of Image while this projectile is moving."), SequenceReference("Image")]
|
||||
public readonly string Sequence = "idle";
|
||||
[Desc("Loop this sequence of Image while this projectile is moving.")]
|
||||
[SequenceReference("Image")] public readonly string Sequence = "idle";
|
||||
|
||||
[Desc("The palette used to draw this projectile.")]
|
||||
public readonly string Palette = "effect";
|
||||
|
||||
@@ -19,13 +19,19 @@ namespace OpenRA.Mods.Common.Effects
|
||||
public class GravityBombInfo : IProjectileInfo
|
||||
{
|
||||
public readonly string Image = null;
|
||||
|
||||
[Desc("Sequence to loop while falling.")]
|
||||
public readonly string Sequence = "idle";
|
||||
[SequenceReference("Image")] public readonly string Sequence = "idle";
|
||||
|
||||
[Desc("Sequence to play when launched. Skipped if null or empty.")]
|
||||
public readonly string OpenSequence = null;
|
||||
[SequenceReference("Image")] public readonly string OpenSequence = null;
|
||||
|
||||
public readonly string Palette = "effect";
|
||||
|
||||
public readonly bool Shadow = false;
|
||||
|
||||
public readonly WDist Velocity = WDist.Zero;
|
||||
|
||||
[Desc("Value added to velocity every tick.")]
|
||||
public readonly WDist Acceleration = new WDist(15);
|
||||
|
||||
|
||||
@@ -22,14 +22,20 @@ namespace OpenRA.Mods.Common.Effects
|
||||
class LaserZapInfo : IProjectileInfo
|
||||
{
|
||||
public readonly int BeamWidth = 2;
|
||||
|
||||
public readonly int BeamDuration = 10;
|
||||
|
||||
public readonly bool UsePlayerColor = false;
|
||||
|
||||
[Desc("Laser color in (A,)R,G,B.")]
|
||||
public readonly Color Color = Color.Red;
|
||||
|
||||
[Desc("Impact animation.")]
|
||||
public readonly string HitAnim = null;
|
||||
|
||||
[Desc("Sequence of impact animation to use.")]
|
||||
public readonly string HitAnimSequence = "idle";
|
||||
[SequenceReference("HitAnim")] public readonly string HitAnimSequence = "idle";
|
||||
|
||||
public readonly string HitAnimPalette = "effect";
|
||||
|
||||
public IEffect Create(ProjectileArgs args)
|
||||
|
||||
@@ -24,38 +24,54 @@ namespace OpenRA.Mods.Common.Effects
|
||||
{
|
||||
public readonly string Image = null;
|
||||
[SequenceReference("Image")] public readonly string Sequence = "idle";
|
||||
|
||||
public readonly string Palette = "effect";
|
||||
|
||||
public readonly bool Shadow = false;
|
||||
|
||||
[Desc("Projectile speed in WDist / tick")]
|
||||
public readonly WDist Speed = new WDist(8);
|
||||
|
||||
[Desc("Maximum vertical pitch when changing altitude.")]
|
||||
public readonly WAngle MaximumPitch = WAngle.FromDegrees(30);
|
||||
|
||||
[Desc("How many ticks before this missile is armed and can explode.")]
|
||||
public readonly int Arm = 0;
|
||||
|
||||
[Desc("Is the missile blocked by actors with BlocksProjectiles: trait.")]
|
||||
public readonly bool Blockable = true;
|
||||
|
||||
[Desc("Maximum offset at the maximum range")]
|
||||
public readonly WDist Inaccuracy = WDist.Zero;
|
||||
|
||||
[Desc("Probability of locking onto and following target.")]
|
||||
public readonly int LockOnProbability = 100;
|
||||
|
||||
[Desc("In n/256 per tick.")]
|
||||
public readonly int RateOfTurn = 5;
|
||||
|
||||
[Desc("Explode when following the target longer than this many ticks.")]
|
||||
public readonly int RangeLimit = 0;
|
||||
|
||||
[Desc("Trail animation.")]
|
||||
public readonly string Trail = null;
|
||||
|
||||
[Desc("Interval in ticks between each spawned Trail animation.")]
|
||||
public readonly int TrailInterval = 2;
|
||||
|
||||
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;
|
||||
public readonly int ContrailDelay = 1;
|
||||
|
||||
[Desc("Should missile targeting be thrown off by nearby actors with JamsMissiles.")]
|
||||
public readonly bool Jammable = true;
|
||||
|
||||
[Desc("Explodes when leaving the following terrain type, e.g., Water for torpedoes.")]
|
||||
public readonly string BoundToTerrainType = "";
|
||||
|
||||
[Desc("Explodes when inside this proximity radius to target.",
|
||||
"Note: If this value is lower than the missile speed, this check might",
|
||||
"not trigger fast enough, causing the missile to fly past the target.")]
|
||||
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -89,6 +90,48 @@ namespace OpenRA.Mods.Common.Lint
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var weaponInfo in map.Rules.Weapons)
|
||||
{
|
||||
var projectileInfo = weaponInfo.Value.Projectile;
|
||||
if (projectileInfo == null)
|
||||
continue;
|
||||
|
||||
var fields = projectileInfo.GetType().GetFields();
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.HasAttribute<SequenceReferenceAttribute>())
|
||||
{
|
||||
var sequences = LintExts.GetFieldValues(projectileInfo, field, emitError);
|
||||
foreach (var sequence in sequences)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sequence))
|
||||
continue;
|
||||
|
||||
var sequenceReference = field.GetCustomAttributes<SequenceReferenceAttribute>(true).FirstOrDefault();
|
||||
if (sequenceReference != null && !string.IsNullOrEmpty(sequenceReference.ImageReference))
|
||||
{
|
||||
var imageField = fields.FirstOrDefault(f => f.Name == sequenceReference.ImageReference);
|
||||
if (imageField != null)
|
||||
{
|
||||
foreach (var imageOverride in LintExts.GetFieldValues(projectileInfo, imageField, emitError))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(imageOverride))
|
||||
{
|
||||
var definitions = sequenceDefinitions.FirstOrDefault(n => n.Key == imageOverride.ToLowerInvariant());
|
||||
if (definitions == null)
|
||||
emitWarning("Can't find sequence definition for projectile image {0} at weapon {1}.".F(imageOverride, weaponInfo.Key));
|
||||
else if (!definitions.Value.Nodes.Any(n => n.Key == sequence))
|
||||
emitWarning("Projectile sprite image {0} from weapon {1} does not define sequence {2} from field {3} of {4}"
|
||||
.F(imageOverride, weaponInfo.Key, sequence, field.Name, projectileInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EmitError("{0} failed with exception: {0}".F(customPassType, e));
|
||||
EmitError("{0} failed with exception: {1}".F(customPassType, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,15 @@ namespace OpenRA.Mods.RA.Effects
|
||||
class TeslaZapInfo : IProjectileInfo
|
||||
{
|
||||
public readonly string Image = "litning";
|
||||
|
||||
[SequenceReference("Image")] public readonly string BrightSequence = "bright";
|
||||
[SequenceReference("Image")] public readonly string DimSequence = "dim";
|
||||
|
||||
public readonly string Palette = "effect";
|
||||
|
||||
public readonly int BrightZaps = 1;
|
||||
public readonly int DimZaps = 2;
|
||||
|
||||
public IEffect Create(ProjectileArgs args) { return new TeslaZap(this, args); }
|
||||
}
|
||||
|
||||
@@ -59,7 +65,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
if (!initialized)
|
||||
{
|
||||
var pos = args.GuidedTarget.IsValidFor(args.SourceActor) ? args.GuidedTarget.CenterPosition : args.PassiveTarget;
|
||||
zap = new TeslaZapRenderable(args.Source, 0, pos - args.Source, info.Image, info.BrightZaps, info.DimZaps, info.Palette);
|
||||
zap = new TeslaZapRenderable(args.Source, 0, pos - args.Source,
|
||||
info.Image, info.BrightSequence, info.BrightZaps, info.DimSequence, info.DimZaps, info.Palette);
|
||||
}
|
||||
|
||||
yield return zap;
|
||||
|
||||
@@ -35,13 +35,15 @@ namespace OpenRA.Mods.RA.Graphics
|
||||
readonly WVec length;
|
||||
readonly string image;
|
||||
readonly string palette;
|
||||
readonly string dimSequence;
|
||||
readonly string brightSequence;
|
||||
readonly int brightZaps, dimZaps;
|
||||
|
||||
WPos cachedPos;
|
||||
WVec cachedLength;
|
||||
IEnumerable<IFinalizedRenderable> cache;
|
||||
|
||||
public TeslaZapRenderable(WPos pos, int zOffset, WVec length, string image, int brightZaps, int dimZaps, string palette)
|
||||
public TeslaZapRenderable(WPos pos, int zOffset, WVec length, string image, string brightSequence, int brightZaps, string dimSequence, int dimZaps, string palette)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.zOffset = zOffset;
|
||||
@@ -50,6 +52,8 @@ namespace OpenRA.Mods.RA.Graphics
|
||||
this.palette = palette;
|
||||
this.brightZaps = brightZaps;
|
||||
this.dimZaps = dimZaps;
|
||||
this.dimSequence = dimSequence;
|
||||
this.brightSequence = brightSequence;
|
||||
|
||||
cachedPos = WPos.Zero;
|
||||
cachedLength = WVec.Zero;
|
||||
@@ -61,17 +65,20 @@ namespace OpenRA.Mods.RA.Graphics
|
||||
public int ZOffset { get { return zOffset; } }
|
||||
public bool IsDecoration { get { return true; } }
|
||||
|
||||
public IRenderable WithPalette(PaletteReference newPalette) { return new TeslaZapRenderable(pos, zOffset, length, image, brightZaps, dimZaps, palette); }
|
||||
public IRenderable WithZOffset(int newOffset) { return new TeslaZapRenderable(pos, zOffset, length, image, brightZaps, dimZaps, palette); }
|
||||
public IRenderable OffsetBy(WVec vec) { return new TeslaZapRenderable(pos + vec, zOffset, length, image, brightZaps, dimZaps, palette); }
|
||||
public IRenderable WithPalette(PaletteReference newPalette)
|
||||
{
|
||||
return new TeslaZapRenderable(pos, zOffset, length, image, brightSequence, brightZaps, dimSequence, dimZaps, palette);
|
||||
}
|
||||
|
||||
public IRenderable WithZOffset(int newOffset) { return new TeslaZapRenderable(pos, zOffset, length, image, brightSequence, brightZaps, dimSequence, dimZaps, palette); }
|
||||
public IRenderable OffsetBy(WVec vec) { return new TeslaZapRenderable(pos + vec, zOffset, length, image, brightSequence, brightZaps, dimSequence, dimZaps, palette); }
|
||||
public IRenderable AsDecoration() { return this; }
|
||||
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
public void RenderDebugGeometry(WorldRenderer wr) { }
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
if (wr.World.FogObscures(pos) &&
|
||||
wr.World.FogObscures(pos + length))
|
||||
if (wr.World.FogObscures(pos) && wr.World.FogObscures(pos + length))
|
||||
return;
|
||||
|
||||
if (!cache.Any() || length != cachedLength || pos != cachedPos)
|
||||
@@ -84,8 +91,8 @@ namespace OpenRA.Mods.RA.Graphics
|
||||
|
||||
public IEnumerable<IFinalizedRenderable> GenerateRenderables(WorldRenderer wr)
|
||||
{
|
||||
var bright = wr.World.Map.SequenceProvider.GetSequence(image, "bright");
|
||||
var dim = wr.World.Map.SequenceProvider.GetSequence(image, "dim");
|
||||
var bright = wr.World.Map.SequenceProvider.GetSequence(image, brightSequence);
|
||||
var dim = wr.World.Map.SequenceProvider.GetSequence(image, dimSequence);
|
||||
|
||||
var source = wr.ScreenPosition(pos);
|
||||
var target = wr.ScreenPosition(pos + length);
|
||||
|
||||
Reference in New Issue
Block a user