actually working custom lint passes

This commit is contained in:
Chris Forbes
2011-04-05 21:56:31 +12:00
parent 55c609ee16
commit 24a205d992
5 changed files with 273 additions and 229 deletions

View File

@@ -82,7 +82,15 @@ namespace OpenRA
a[ i ] = args[ key ]; a[ i ] = args[ key ];
} }
return ctor.Invoke( a ); return ctor.Invoke( a );
} }
public IEnumerable<Type> GetTypesImplementing<T>()
{
var it = typeof(T);
return ModAssemblies.Select( ma => ma.First ).Distinct()
.SelectMany(ma => ma.GetTypes()
.Where(t => t != it && it.IsAssignableFrom(t)));
}
[AttributeUsage( AttributeTargets.Parameter )] [AttributeUsage( AttributeTargets.Parameter )]
public class ParamAttribute : Attribute public class ParamAttribute : Attribute

View File

@@ -13,229 +13,236 @@ using System.Drawing;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Network; using OpenRA.Network;
using System;
namespace OpenRA.Traits
{ namespace OpenRA.Traits
// depends on the order of pips in WorldRenderer.cs! {
public enum PipType { Transparent, Green, Yellow, Red, Gray }; // depends on the order of pips in WorldRenderer.cs!
public enum TagType { None, Fake, Primary }; public enum PipType { Transparent, Green, Yellow, Red, Gray };
public enum Stance { Enemy, Neutral, Ally }; public enum TagType { None, Fake, Primary };
public enum Stance { Enemy, Neutral, Ally };
public class AttackInfo
{ public class AttackInfo
public Actor Attacker; {
public WarheadInfo Warhead; public Actor Attacker;
public int Damage; public WarheadInfo Warhead;
public DamageState DamageState; public int Damage;
public DamageState PreviousDamageState; public DamageState DamageState;
public bool DamageStateChanged; public DamageState PreviousDamageState;
public int PreviousHealth; public bool DamageStateChanged;
public int Health; public int PreviousHealth;
} public int Health;
}
public interface ITick { void Tick(Actor self); }
public interface IRender { IEnumerable<Renderable> Render(Actor self); } public interface ITick { void Tick(Actor self); }
public interface IRender { IEnumerable<Renderable> Render(Actor self); }
public interface IIssueOrder
{ public interface IIssueOrder
IEnumerable<IOrderTargeter> Orders { get; } {
Order IssueOrder( Actor self, IOrderTargeter order, Target target, bool queued ); IEnumerable<IOrderTargeter> Orders { get; }
} Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued);
public interface IOrderTargeter }
{
string OrderID { get; } public interface IOrderTargeter
int OrderPriority { get; } {
bool CanTargetActor( Actor self, Actor target, bool forceAttack, bool forceMove, bool forceQueue, ref string cursor ); string OrderID { get; }
bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, bool forceMove, ref string cursor); int OrderPriority { get; }
bool IsQueued { get; } bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceMove, bool forceQueue, ref string cursor);
} bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceQueue, bool forceMove, ref string cursor);
public interface IResolveOrder { void ResolveOrder(Actor self, Order order); } bool IsQueued { get; }
public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); }
}
public interface IOrderCursor { string CursorForOrder(Actor self, Order order); } public interface IResolveOrder { void ResolveOrder(Actor self, Order order); }
public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); } public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); }
public interface ICustomUnitOrderGenerator : IOrderGenerator {}; public interface IOrderCursor { string CursorForOrder(Actor self, Order order); }
public interface INotifySold { void Selling( Actor self ); void Sold( Actor self ); } public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); }
public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } public interface ICustomUnitOrderGenerator : IOrderGenerator { };
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); } public interface INotifySold { void Selling(Actor self); void Sold(Actor self); }
public interface INotifyBuildComplete { void BuildingComplete(Actor self); } public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); } public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); } public interface INotifyBuildComplete { void BuildingComplete(Actor self); }
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); } public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); }
public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); } public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
public interface IStoreOre { int Capacity { get; }} public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
public interface IToolTip public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); }
{ public interface IStoreOre { int Capacity { get; } }
string Name(); public interface IToolTip
Player Owner(); {
Stance Stance(); string Name();
} Player Owner();
Stance Stance();
public interface IDisable { bool Disabled { get; } } }
public interface IExplodeModifier { bool ShouldExplode(Actor self); }
public interface INudge { void OnNudge(Actor self, Actor nudger); } public interface IDisable { bool Disabled { get; } }
public interface IExplodeModifier { bool ShouldExplode(Actor self); }
public interface IRadarSignature public interface INudge { void OnNudge(Actor self, Actor nudger); }
{
IEnumerable<int2> RadarSignatureCells(Actor self); public interface IRadarSignature
Color RadarSignatureColor(Actor self); {
} IEnumerable<int2> RadarSignatureCells(Actor self);
Color RadarSignatureColor(Actor self);
public interface IVisibilityModifier { bool IsVisible(Actor self); } }
public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
public interface IHasLocation public interface IVisibilityModifier { bool IsVisible(Actor self); }
{ public interface IRadarColorModifier { Color RadarColorOverride(Actor self); }
int2 PxPosition { get; } public interface IHasLocation
} {
int2 PxPosition { get; }
public enum SubCell }
{
FullCell, public enum SubCell
TopLeft, {
TopRight, FullCell,
Center, TopLeft,
BottomLeft, TopRight,
BottomRight Center,
} BottomLeft,
BottomRight
public interface IOccupySpace : IHasLocation }
{
int2 TopLeft { get; } public interface IOccupySpace : IHasLocation
IEnumerable<Pair<int2, SubCell>> OccupiedCells(); {
} int2 TopLeft { get; }
IEnumerable<Pair<int2, SubCell>> OccupiedCells();
public static class IOccupySpaceExts }
{
public static int2 NearestCellTo( this IOccupySpace ios, int2 other ) public static class IOccupySpaceExts
{ {
var nearest = ios.TopLeft; public static int2 NearestCellTo(this IOccupySpace ios, int2 other)
var nearestDistance = int.MaxValue; {
foreach( var cell in ios.OccupiedCells() ) var nearest = ios.TopLeft;
{ var nearestDistance = int.MaxValue;
var dist = ( other - cell.First ).LengthSquared; foreach (var cell in ios.OccupiedCells())
if( dist < nearestDistance ) {
{ var dist = (other - cell.First).LengthSquared;
nearest = cell.First; if (dist < nearestDistance)
nearestDistance = dist; {
} nearest = cell.First;
} nearestDistance = dist;
return nearest; }
} }
} return nearest;
}
public interface INotifyAttack { void Attacking(Actor self, Target target); } }
public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r); }
public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); } public interface INotifyAttack { void Attacking(Actor self, Target target); }
public interface ISpeedModifier { decimal GetSpeedModifier(); } public interface IRenderModifier { IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r); }
public interface IFirepowerModifier { float GetFirepowerModifier(); } public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); }
public interface ISelectionColorModifier { Color GetSelectionColorModifier(Actor self, Color defaultColor); } public interface ISpeedModifier { decimal GetSpeedModifier(); }
public interface IPalette { void InitPalette( WorldRenderer wr ); } public interface IFirepowerModifier { float GetFirepowerModifier(); }
public interface IPaletteModifier { void AdjustPalette(Dictionary<string,Palette> b); } public interface ISelectionColorModifier { Color GetSelectionColorModifier(Actor self, Color defaultColor); }
public interface IPips { IEnumerable<PipType> GetPips(Actor self); } public interface IPalette { void InitPalette(WorldRenderer wr); }
public interface ITags { IEnumerable<TagType> GetTags(); } public interface IPaletteModifier { void AdjustPalette(Dictionary<string, Palette> b); }
public interface ISelectionBar { float GetValue(); Color GetColor(); } public interface IPips { IEnumerable<PipType> GetPips(Actor self); }
public interface ITags { IEnumerable<TagType> GetTags(); }
public interface ITeleportable : IHasLocation /* crap name! */ public interface ISelectionBar { float GetValue(); Color GetColor(); }
{
bool CanEnterCell(int2 location); public interface ITeleportable : IHasLocation /* crap name! */
void SetPosition(Actor self, int2 cell); {
void SetPxPosition(Actor self, int2 px); bool CanEnterCell(int2 location);
void AdjustPxPosition(Actor self, int2 px); /* works like SetPxPosition, but visual only */ void SetPosition(Actor self, int2 cell);
} void SetPxPosition(Actor self, int2 px);
void AdjustPxPosition(Actor self, int2 px); /* works like SetPxPosition, but visual only */
public interface IMove : ITeleportable }
{
int Altitude { get; set; } public interface IMove : ITeleportable
} {
int Altitude { get; set; }
public interface IFacing }
{
int ROT { get; } public interface IFacing
int Facing { get; set; } {
int InitialFacing { get; } int ROT { get; }
} int Facing { get; set; }
int InitialFacing { get; }
public interface ICrushable }
{
void OnCrush(Actor crusher); public interface ICrushable
IEnumerable<string> CrushClasses { get; } {
} void OnCrush(Actor crusher);
IEnumerable<string> CrushClasses { get; }
public struct Renderable }
{
public readonly Sprite Sprite; public struct Renderable
public readonly float2 Pos; {
public readonly string Palette; public readonly Sprite Sprite;
public readonly int Z; public readonly float2 Pos;
public readonly int ZOffset; public readonly string Palette;
public float Scale; public readonly int Z;
public readonly int ZOffset;
public Renderable(Sprite sprite, float2 pos, string palette, int z, int zOffset, float scale) public float Scale;
{
Sprite = sprite; public Renderable(Sprite sprite, float2 pos, string palette, int z, int zOffset, float scale)
Pos = pos; {
Palette = palette; Sprite = sprite;
Z = z; Pos = pos;
ZOffset = zOffset; Palette = palette;
Scale = scale; /* default */ Z = z;
} ZOffset = zOffset;
Scale = scale; /* default */
public Renderable(Sprite sprite, float2 pos, string palette, int z) }
: this(sprite, pos, palette, z, 0, 1f) { }
public Renderable(Sprite sprite, float2 pos, string palette, int z)
public Renderable(Sprite sprite, float2 pos, string palette, int z, float scale) : this(sprite, pos, palette, z, 0, 1f) { }
: this(sprite, pos, palette, z, 0, scale) { }
public Renderable(Sprite sprite, float2 pos, string palette, int z, float scale)
public Renderable WithScale(float newScale) { return new Renderable(Sprite, Pos, Palette, Z, ZOffset, newScale); } : this(sprite, pos, palette, z, 0, scale) { }
public Renderable WithPalette(string newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
public Renderable WithZOffset(int newOffset) { return new Renderable(Sprite, Pos, Palette, Z, newOffset, Scale); } public Renderable WithScale(float newScale) { return new Renderable(Sprite, Pos, Palette, Z, ZOffset, newScale); }
public Renderable WithPos(float2 newPos) { return new Renderable(Sprite, newPos, Palette, Z, ZOffset, Scale); } public Renderable WithPalette(string newPalette) { return new Renderable(Sprite, Pos, newPalette, Z, ZOffset, Scale); }
} public Renderable WithZOffset(int newOffset) { return new Renderable(Sprite, Pos, Palette, Z, newOffset, Scale); }
public Renderable WithPos(float2 newPos) { return new Renderable(Sprite, newPos, Palette, Z, ZOffset, Scale); }
public interface ITraitInfo { object Create(ActorInitializer init); } }
public class TraitInfo<T> : ITraitInfo where T : new() { public virtual object Create(ActorInitializer init) { return new T(); } } public interface ITraitInfo { object Create(ActorInitializer init); }
public interface ITraitPrerequisite<T> where T : ITraitInfo { } public class TraitInfo<T> : ITraitInfo where T : new() { public virtual object Create(ActorInitializer init) { return new T(); } }
public interface INotifySelection { void SelectionChanged(); } public interface ITraitPrerequisite<T> where T : ITraitInfo { }
public interface IWorldLoaded { void WorldLoaded(World w); }
public interface ICreatePlayers { void CreatePlayers(World w); } public interface INotifySelection { void SelectionChanged(); }
public interface IWorldLoaded { void WorldLoaded(World w); }
public interface IBotInfo { string Name { get; } } public interface ICreatePlayers { void CreatePlayers(World w); }
public interface IBot
{ public interface IBotInfo { string Name { get; } }
void Activate(Player p); public interface IBot
IBotInfo Info { get; } {
} void Activate(Player p);
IBotInfo Info { get; }
public interface IActivity }
{
IActivity Tick(Actor self); public interface IActivity
void Cancel(Actor self); {
void Queue(IActivity activity); IActivity Tick(Actor self);
IEnumerable<float2> GetCurrentPath(); void Cancel(Actor self);
} void Queue(IActivity activity);
IEnumerable<float2> GetCurrentPath();
public interface IRenderOverlay { void Render( WorldRenderer wr ); } }
public interface INotifyIdle { void TickIdle(Actor self); }
public interface IRenderOverlay { void Render(WorldRenderer wr); }
public interface IBlocksBullets { } public interface INotifyIdle { void TickIdle(Actor self); }
public interface IPostRender { void RenderAfterWorld(WorldRenderer wr, Actor self); } public interface IBlocksBullets { }
public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr, Actor self); } public interface IPostRender { void RenderAfterWorld(WorldRenderer wr, Actor self); }
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(Actor self); } public interface IPostRenderSelection { void RenderAfterWorld(WorldRenderer wr, Actor self); }
public interface IPreRenderSelection { void RenderBeforeWorld(WorldRenderer wr, Actor self); }
public interface ITargetable public interface IRenderAsTerrain { IEnumerable<Renderable> RenderAsTerrain(Actor self); }
{
string[] TargetTypes { get; } public interface ITargetable
IEnumerable<int2> TargetableCells( Actor self ); {
bool TargetableBy(Actor self, Actor byActor); string[] TargetTypes { get; }
} IEnumerable<int2> TargetableCells(Actor self);
bool TargetableBy(Actor self, Actor byActor);
public interface INotifyStanceChanged { void StanceChanged(Actor self, Player a, Player b, }
Stance oldStance, Stance newStance); }
public interface INotifyStanceChanged
{
void StanceChanged(Actor self, Player a, Player b,
Stance oldStance, Stance newStance);
}
public interface ILintPass { void Run(Action<string> emitError); }
} }

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class LintBuildablePrerequisites : ILintPass
{
public void Run(Action<string> emitError)
{
emitError("Hello World");
}
}
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -63,6 +63,7 @@
<Compile Include="Air\FlyCircle.cs" /> <Compile Include="Air\FlyCircle.cs" />
<Compile Include="Buildings\Sellable.cs" /> <Compile Include="Buildings\Sellable.cs" />
<Compile Include="Effects\CashTick.cs" /> <Compile Include="Effects\CashTick.cs" />
<Compile Include="Lint\LintBuildablePrerequisites.cs" />
<Compile Include="ProductionBar.cs" /> <Compile Include="ProductionBar.cs" />
<Compile Include="Render\RenderEditorOnly.cs" /> <Compile Include="Render\RenderEditorOnly.cs" />
<Compile Include="SmokeTrailWhenDamaged.cs" /> <Compile Include="SmokeTrailWhenDamaged.cs" />

View File

@@ -29,7 +29,8 @@ namespace RALint
} }
static int Main(string[] args) static int Main(string[] args)
{ {
Console.WriteLine("This is teh sucks");
try try
{ {
// bind some nonfatal error handling into FieldLoader, so we don't just *explode*. // bind some nonfatal error handling into FieldLoader, so we don't just *explode*.
@@ -42,7 +43,18 @@ namespace RALint
foreach (var actorInfo in Rules.Info) foreach (var actorInfo in Rules.Info)
foreach (var traitInfo in actorInfo.Value.Traits.WithInterface<ITraitInfo>()) foreach (var traitInfo in actorInfo.Value.Traits.WithInterface<ITraitInfo>())
CheckTrait(actorInfo.Value, traitInfo); CheckTrait(actorInfo.Value, traitInfo);
foreach (var customPassType in Game.modData.ObjectCreator
.GetTypesImplementing<ILintPass>())
{
var customPass = (ILintPass)Game.modData.ObjectCreator
.CreateBasic(customPassType);
Console.WriteLine("CustomPass: {0}".F(customPassType.ToString()));
customPass.Run(EmitError);
}
if (errors > 0) if (errors > 0)
{ {