Actor.traits is implementation detail

This commit is contained in:
Bob
2010-08-14 15:19:30 +12:00
committed by alzeih
parent f6c6255f64
commit ae703d50b2
165 changed files with 586 additions and 561 deletions

View File

@@ -22,13 +22,13 @@ namespace OpenRA
public class Actor
{
[Sync]
public readonly TypeDictionary traits = new TypeDictionary();
readonly TypeDictionary traits = new TypeDictionary();
public readonly ActorInfo Info;
public readonly World World;
public readonly uint ActorID;
public int2 Location { get { return traits.Get<IOccupySpace>().TopLeft; } }
public int2 Location { get { return Trait<IOccupySpace>().TopLeft; } }
[Sync]
public Player Owner;
@@ -51,10 +51,10 @@ namespace OpenRA
Info = Rules.Info[name.ToLowerInvariant()];
foreach (var trait in Info.TraitsInConstructOrder())
traits.Add(trait.Create(init));
AddTrait(trait.Create(init));
}
if( CenterLocation == float2.Zero && traits.Contains<IOccupySpace>() )
if( CenterLocation == float2.Zero && HasTrait<IOccupySpace>() )
CenterLocation = Traits.Util.CenterOfCell(Location);
Size = Lazy.New(() =>
@@ -64,7 +64,7 @@ namespace OpenRA
return new float2(si.Bounds[0], si.Bounds[1]);
// auto size from render
var firstSprite = traits.WithInterface<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
var firstSprite = TraitsImplementing<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
if (firstSprite.Sprite == null) return float2.Zero;
return firstSprite.Sprite.size;
});
@@ -83,7 +83,7 @@ namespace OpenRA
if (currentActivity is Idle)
{
if (!wasIdle)
foreach (var ni in traits.WithInterface<INotifyIdle>())
foreach (var ni in TraitsImplementing<INotifyIdle>())
ni.Idle(this);
break;
@@ -102,8 +102,8 @@ namespace OpenRA
public IEnumerable<Renderable> Render()
{
var mods = traits.WithInterface<IRenderModifier>();
var sprites = traits.WithInterface<IRender>().SelectMany(x => x.Render(this));
var mods = TraitsImplementing<IRenderModifier>();
var sprites = TraitsImplementing<IRender>().SelectMany(x => x.Render(this));
return mods.Aggregate(sprites, (m, p) => p.ModifyRender(this, m));
}
@@ -120,7 +120,7 @@ namespace OpenRA
.OrderByDescending(a => a.Info.Traits.Contains<SelectableInfo>() ? a.Info.Traits.Get<SelectableInfo>().Priority : int.MinValue)
.FirstOrDefault();
return traits.WithInterface<IIssueOrder>()
return TraitsImplementing<IIssueOrder>()
.Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
.FirstOrDefault( x => x != null );
}
@@ -137,7 +137,7 @@ namespace OpenRA
if (useAltitude)
{
var move = traits.GetOrDefault<IMove>();
var move = TraitOrDefault<IMove>();
if (move != null) loc -= new float2(0, move.Altitude);
}
@@ -188,5 +188,30 @@ namespace OpenRA
{
return "{0} {1}{2}".F( Info.Name, ActorID, IsInWorld ? "" : " (not in world)" );
}
public T Trait<T>()
{
return traits.Get<T>();
}
public T TraitOrDefault<T>()
{
return traits.GetOrDefault<T>();
}
public IEnumerable<T> TraitsImplementing<T>()
{
return traits.WithInterface<T>();
}
public bool HasTrait<T>()
{
return traits.Contains<T>();
}
public void AddTrait( object t )
{
traits.Add( t );
}
}
}

View File

@@ -384,7 +384,7 @@ namespace OpenRA
LoadMap(map);
world.Queries = new World.AllQueries(world);
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
foreach (var gs in world.WorldActor.TraitsImplementing<IGameStarted>())
gs.GameStarted(world);
orderManager.StartGame();
}
@@ -398,7 +398,7 @@ namespace OpenRA
world.Queries = new World.AllQueries(world);
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
foreach (var gs in world.WorldActor.TraitsImplementing<IGameStarted>())
gs.GameStarted(world);
viewport.GoToStartLocation(world.LocalPlayer);

View File

@@ -98,7 +98,7 @@ namespace OpenRA.Graphics
new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow),
PrimitiveType.TriangleList, Game.Renderer.SpriteShader));
foreach (var r in world.WorldActor.traits.WithInterface<IRenderOverlay>())
foreach (var r in world.WorldActor.TraitsImplementing<IRenderOverlay>())
r.Render();
}
}

View File

@@ -76,7 +76,7 @@ namespace OpenRA.Graphics
public void RefreshPalette()
{
Game.world.WorldRenderer.palette.Update(
Game.world.WorldActor.traits.WithInterface<IPaletteModifier>());
Game.world.WorldActor.TraitsImplementing<IPaletteModifier>());
}
public void Tick()

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Network
order.Player.Stances[targetPlayer] = (Stance)order.TargetLocation.Y;
if (targetPlayer == world.LocalPlayer)
world.WorldActor.traits.Get<Shroud>().UpdatePlayerStance(world, order.Player, oldStance, order.Player.Stances[targetPlayer]);
world.WorldActor.Trait<Shroud>().UpdatePlayerStance(world, order.Player, oldStance, order.Player.Stances[targetPlayer]);
Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
order.Player.PlayerName, targetPlayer.PlayerName, order.Player.Stances[targetPlayer]));
@@ -79,7 +79,7 @@ namespace OpenRA.Network
default:
{
if( !order.IsImmediate )
foreach (var t in order.Subject.traits.WithInterface<IResolveOrder>())
foreach (var t in order.Subject.TraitsImplementing<IResolveOrder>())
t.ResolveOrder(order.Subject, order);
break;
}

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Orders
public void Tick( World world )
{
var producing = Producer.traits.Get<Traits.ProductionQueue>().CurrentItem( Rules.Info[ Building ].Category );
var producing = Producer.Trait<Traits.ProductionQueue>().CurrentItem( Rules.Info[ Building ].Category );
if (producing == null || producing.Item != Building || producing.RemainingTime != 0)
world.CancelInputMode();
}

View File

@@ -38,21 +38,21 @@ namespace OpenRA.Orders
public void RenderBeforeWorld(World world)
{
foreach (var a in world.Selection.Actors)
foreach (var t in a.traits.WithInterface<IPreRenderSelection>())
foreach (var t in a.TraitsImplementing<IPreRenderSelection>())
t.RenderBeforeWorld(a);
}
public void RenderAfterWorld( World world )
{
foreach (var a in world.Selection.Actors)
foreach (var t in a.traits.WithInterface<IPostRenderSelection>())
foreach (var t in a.TraitsImplementing<IPostRenderSelection>())
t.RenderAfterWorld(a);
}
public string GetCursor( World world, int2 xy, MouseInput mi )
{
var c = Order(world, xy, mi)
.Select(o => o.Subject.traits.WithInterface<IOrderCursor>()
.Select(o => o.Subject.TraitsImplementing<IOrderCursor>()
.Select(pc => pc.CursorForOrder(o.Subject, o)).FirstOrDefault(a => a != null))
.FirstOrDefault(a => a != null);

View File

@@ -69,7 +69,7 @@ namespace OpenRA
{
using( new PerfSample( "find_unit_path_multiple_src" ) )
{
var mobile = self.traits.Get<Mobile>();
var mobile = self.Trait<Mobile>();
var tilesInRange = world.FindTilesInCircle(target, range)
.Where( t => mobile.CanEnterCell(t));
@@ -86,7 +86,7 @@ namespace OpenRA
return q =>
p != q &&
((p - q).LengthSquared < dist * dist) &&
(world.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(q).Any(a => a.Group != self.Group));
(world.WorldActor.Trait<UnitInfluence>().GetUnitsAt(q).Any(a => a.Group != self.Group));
}
public List<int2> FindPath( PathSearch search )

View File

@@ -33,7 +33,7 @@ namespace OpenRA
this.self = self;
world = self.World;
cellInfo = InitCellInfo();
mobile = self.traits.Get<Mobile>();
mobile = self.Trait<Mobile>();
queue = new PriorityQueue<PathDistance>();
}

View File

@@ -21,7 +21,7 @@ namespace OpenRA
public void Add(World w, Actor a)
{
actors.Add(a);
foreach (var ns in w.WorldActor.traits.WithInterface<INotifySelection>())
foreach (var ns in w.WorldActor.TraitsImplementing<INotifySelection>())
ns.SelectionChanged();
}
@@ -44,7 +44,7 @@ namespace OpenRA
var voicedUnit = actors.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.HasVoice());
Sound.PlayVoice("Select", voicedUnit);
foreach (var ns in world.WorldActor.traits.WithInterface<INotifySelection>())
foreach (var ns in world.WorldActor.TraitsImplementing<INotifySelection>())
ns.SelectionChanged();
}

View File

@@ -28,7 +28,7 @@ namespace OpenRA
public ShroudRenderer(Player owner, Map map)
{
this.shroud = owner.World.WorldActor.traits.Get<Traits.Shroud>();
this.shroud = owner.World.WorldActor.Trait<Traits.Shroud>();
this.map = map;
sprites = new Sprite[map.MapSize.X, map.MapSize.Y];

View File

@@ -90,7 +90,7 @@ namespace OpenRA.Traits.Activities
public IActivity Tick( Actor self )
{
var mobile = self.traits.Get<Mobile>();
var mobile = self.Trait<Mobile>();
if( move != null )
{
@@ -165,10 +165,10 @@ namespace OpenRA.Traits.Activities
void NudgeBlocker(Actor self, int2 nextCell)
{
var blocker = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(nextCell).FirstOrDefault();
var blocker = self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(nextCell).FirstOrDefault();
if (blocker == null) return;
var nudge = blocker.traits.GetOrDefault<INudge>();
var nudge = blocker.TraitOrDefault<INudge>();
if (nudge != null)
nudge.OnNudge(blocker, self);
}

View File

@@ -23,12 +23,12 @@ namespace OpenRA.Traits.Activities
var csv = self.Info.Traits.GetOrDefault<CustomSellValueInfo>();
var cost = csv != null ? csv.Value : self.Info.Traits.Get<ValuedInfo>().Cost;
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
var refundFraction = self.Info.Traits.Get<BuildingInfo>().RefundPercent * (health == null ? 1f : health.HPFraction);
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash((int)(refundFraction * cost));
self.Owner.PlayerActor.Trait<PlayerResources>().GiveCash((int)(refundFraction * cost));
foreach (var ns in self.traits.WithInterface<INotifySold>())
foreach (var ns in self.TraitsImplementing<INotifySold>())
ns.Sold(self);
self.World.AddFrameEndTask( _ => self.World.Remove( self ) );
}
@@ -37,10 +37,10 @@ namespace OpenRA.Traits.Activities
{
if( !started )
{
framesRemaining = self.traits.Get<RenderSimple>().anim.HasSequence("make")
? self.traits.Get<RenderSimple>().anim.GetSequence( "make" ).Length : 0;
framesRemaining = self.Trait<RenderSimple>().anim.HasSequence("make")
? self.Trait<RenderSimple>().anim.GetSequence( "make" ).Length : 0;
foreach( var ns in self.traits.WithInterface<INotifySold>() )
foreach( var ns in self.TraitsImplementing<INotifySold>() )
ns.Selling( self );
started = true;

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Traits.Activities
public IActivity Tick( Actor self )
{
var facing = self.traits.Get<IFacing>();
var facing = self.Trait<IFacing>();
if( desiredFacing == facing.Facing )
return NextActivity;
@@ -35,7 +35,7 @@ namespace OpenRA.Traits.Activities
public void Cancel( Actor self )
{
desiredFacing = self.traits.Get<IFacing>().Facing;
desiredFacing = self.Trait<IFacing>().Facing;
NextActivity = null;
}
}

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Traits
public bool Disabled
{
get { return self.traits.WithInterface<IDisable>().Any(t => t.Disabled); }
get { return self.TraitsImplementing<IDisable>().Any(t => t.Disabled); }
}
public Building(ActorInitializer init)
@@ -61,14 +61,14 @@ namespace OpenRA.Traits
public int GetPowerUsage()
{
var modifier = self.traits
.WithInterface<IPowerModifier>()
var modifier = self
.TraitsImplementing<IPowerModifier>()
.Select(t => t.GetPowerModifier())
.Product();
if (Info.Power > 0)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
var healthFraction = (health == null) ? 1f : health.HPFraction;
return (int)(modifier * healthFraction * Info.Power);
}
@@ -80,7 +80,7 @@ namespace OpenRA.Traits
{
if (e.DamageState == DamageState.Dead)
{
self.World.WorldActor.traits.Get<ScreenShaker>().AddEffect(10, self.CenterLocation, 1);
self.World.WorldActor.Trait<ScreenShaker>().AddEffect(10, self.CenterLocation, 1);
Sound.Play(Info.DestroyedSound, self.CenterLocation);
}
}

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Traits
var oldState = this.DamageState;
/* apply the damage modifiers, if we have any. */
var modifier = (float)self.traits.WithInterface<IDamageModifier>()
var modifier = (float)self.TraitsImplementing<IDamageModifier>()
.Select(t => t.GetDamageModifier(warhead)).Product();
damage = (int)(damage * modifier);
@@ -103,7 +103,7 @@ namespace OpenRA.Traits
if (hp > MaxHP) hp = MaxHP;
foreach (var nd in self.traits.WithInterface<INotifyDamage>())
foreach (var nd in self.TraitsImplementing<INotifyDamage>())
nd.Damaged(self, new AttackInfo
{
Attacker = attacker,
@@ -140,26 +140,26 @@ namespace OpenRA.Traits
{
public static bool IsDead(this Actor self)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
return (health == null) ? true : health.IsDead;
}
public static DamageState GetDamageState(this Actor self)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
return (health == null) ? DamageState.Undamaged : health.DamageState;
}
public static void InflictDamage(this Actor self, Actor attacker, int damage, WarheadInfo warhead)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
if (health == null) return;
health.InflictDamage(self, attacker, damage, warhead);
}
public static void Kill(this Actor self, Actor attacker)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
if (health == null) return;
health.InflictDamage(self, attacker, health.HP, null);
}

View File

@@ -79,10 +79,10 @@ namespace OpenRA.Traits
this.self = init.self;
this.Info = info;
shroud = self.World.WorldActor.traits.Get<Shroud>();
uim = self.World.WorldActor.traits.Get<UnitInfluence>();
bim = self.World.WorldActor.traits.Get<BuildingInfluence>();
canShareCell = self.traits.Contains<SharesCell>();
shroud = self.World.WorldActor.Trait<Shroud>();
uim = self.World.WorldActor.Trait<UnitInfluence>();
bim = self.World.WorldActor.Trait<BuildingInfluence>();
canShareCell = self.HasTrait<SharesCell>();
if (init.Contains<LocationInit>())
{
@@ -149,7 +149,7 @@ namespace OpenRA.Traits
self.World.AddFrameEndTask(w =>
{
w.Add(new MoveFlash(self.World, order.TargetLocation));
var line = self.traits.GetOrDefault<DrawLineToTarget>();
var line = self.TraitOrDefault<DrawLineToTarget>();
if (line != null)
line.SetTarget(self, Target.FromOrder(order), Color.Green);
});
@@ -203,7 +203,7 @@ namespace OpenRA.Traits
if (Info.Crushes == null)
return false;
var crushable = building.traits.WithInterface<ICrushable>();
var crushable = building.TraitsImplementing<ICrushable>();
if (crushable.Count() == 0)
return false;
@@ -215,11 +215,11 @@ namespace OpenRA.Traits
if (checkTransientActors && uim.AnyUnitsAt(cell))
{
var actors = uim.GetUnitsAt(cell).Where(a => a != self && a != ignoreActor).ToArray();
var nonshareable = canShareCell ? actors : actors.Where(a => !a.traits.Contains<SharesCell>()).ToArray();
var nonshareable = canShareCell ? actors : actors.Where(a => !a.HasTrait<SharesCell>()).ToArray();
if (canShareCell)
{
var shareable = actors.Where(a => a.traits.Contains<SharesCell>());
var shareable = actors.Where(a => a.HasTrait<SharesCell>());
// only allow 5 in a cell
if (shareable.Count() >= 5)
@@ -230,8 +230,8 @@ namespace OpenRA.Traits
if (Info.Crushes == null && nonshareable.Length > 0)
return false;
if (nonshareable.Length > 0 && nonshareable.Any(a => !(a.traits.Contains<ICrushable>() &&
a.traits.WithInterface<ICrushable>().Any(b => b.CrushClasses.Intersect(Info.Crushes).Any()))))
if (nonshareable.Length > 0 && nonshareable.Any(a => !(a.HasTrait<ICrushable>() &&
a.TraitsImplementing<ICrushable>().Any(b => b.CrushClasses.Intersect(Info.Crushes).Any()))))
return false;
}
@@ -241,10 +241,10 @@ namespace OpenRA.Traits
public virtual void FinishedMoving(Actor self)
{
var crushable = uim.GetUnitsAt(toCell).Where(a => a != self && a.traits.Contains<ICrushable>());
var crushable = uim.GetUnitsAt(toCell).Where(a => a != self && a.HasTrait<ICrushable>());
foreach (var a in crushable)
{
var crushActions = a.traits.WithInterface<ICrushable>().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any());
var crushActions = a.TraitsImplementing<ICrushable>().Where(b => b.CrushClasses.Intersect(Info.Crushes).Any());
foreach (var b in crushActions)
b.OnCrush(self);
}
@@ -263,8 +263,8 @@ namespace OpenRA.Traits
{
var type = self.World.GetTerrainType(cell);
var modifier = self.traits
.WithInterface<ISpeedModifier>()
var modifier = self
.TraitsImplementing<ISpeedModifier>()
.Select(t => t.GetSpeedModifier())
.Product();
return Info.Speed * TerrainSpeed[type] * modifier;
@@ -323,7 +323,7 @@ namespace OpenRA.Traits
if (self.Owner == self.World.LocalPlayer)
self.World.AddFrameEndTask(w =>
{
var line = self.traits.GetOrDefault<DrawLineToTarget>();
var line = self.TraitOrDefault<DrawLineToTarget>();
if (line != null)
line.SetTargetSilently(self, Target.FromCell(moveTo.Value), Color.Green);
});

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Traits
}
case "DevGiveCash":
{
self.traits.Get<PlayerResources>().GiveCash(Info.Cash);
self.Trait<PlayerResources>().GiveCash(Info.Cash);
break;
}
case "DevShroud":

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Traits
{
var prevItems = GetNumBuildables(self.Owner);
var queue = self.traits.Get<ProductionQueue>();
var queue = self.Trait<ProductionQueue>();
var unit = Rules.Info[order.TargetString];
var producing = queue.CurrentItem(unit.Category);
@@ -86,7 +86,7 @@ namespace OpenRA.Traits
.FirstOrDefault();
if( producer.Actor != null )
producer.Actor.traits.WithInterface<RenderSimple>().First().PlayCustomAnim( producer.Actor, "build" );
producer.Actor.TraitsImplementing<RenderSimple>().First().PlayCustomAnim( producer.Actor, "build" );
}
static int GetNumBuildables(Player p)

View File

@@ -57,7 +57,7 @@ namespace OpenRA.Traits
void TickOre(Actor self)
{
OreCapacity = self.World.Queries.OwnedBy[Owner].WithTrait<IStoreOre>()
.Sum(a => a.Actor.traits.WithInterface<IStoreOre>().Sum(b => b.Capacity));
.Sum(a => a.Actor.TraitsImplementing<IStoreOre>().Sum(b => b.Capacity));
if (Ore > OreCapacity)
Ore = OreCapacity;

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Traits
{
while( p.Value.Count > 0 && !Rules.TechTree.BuildableItems( self.Owner, p.Key ).Contains( p.Value[ 0 ].Item ) )
{
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(p.Value[0].TotalCost - p.Value[0].RemainingCost); // refund what's been paid so far.
self.Owner.PlayerActor.Trait<PlayerResources>().GiveCash(p.Value[0].TotalCost - p.Value[0].RemainingCost); // refund what's been paid so far.
FinishProduction(p.Key);
}
if( p.Value.Count > 0 )
@@ -101,7 +101,7 @@ namespace OpenRA.Traits
if (unit == null || ! unit.Traits.Contains<BuildableInfo>())
return 0;
if (Game.LobbyInfo.GlobalSettings.AllowCheats && self.traits.Get<DeveloperMode>().FastBuild) return 0;
if (Game.LobbyInfo.GlobalSettings.AllowCheats && self.Trait<DeveloperMode>().FastBuild) return 0;
var ui = unit.Traits.Get<BuildableInfo>();
var time = ui.Cost
* self.Owner.PlayerActor.Info.Traits.Get<ProductionQueueInfo>().BuildSpeed /* todo: country-specific build speed bonus */
@@ -139,7 +139,7 @@ namespace OpenRA.Traits
else if( lastIndex == 0 )
{
var item = queue[0];
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(item.TotalCost - item.RemainingCost); // refund what's been paid so far.
self.Owner.PlayerActor.Trait<PlayerResources>().GiveCash(item.TotalCost - item.RemainingCost); // refund what's been paid so far.
FinishProduction(category);
}
}
@@ -158,7 +158,7 @@ namespace OpenRA.Traits
static bool IsDisabledBuilding(Actor a)
{
var building = a.traits.GetOrDefault<Building>();
var building = a.TraitOrDefault<Building>();
return building != null && building.Disabled;
}
@@ -227,7 +227,7 @@ namespace OpenRA.Traits
if (Paused) return;
if (player.PlayerActor.traits.Get<PlayerResources>().GetPowerState() != PowerState.Normal)
if (player.PlayerActor.Trait<PlayerResources>().GetPowerState() != PowerState.Normal)
{
if (--slowdown <= 0)
slowdown = player.PlayerActor.Info.Traits.Get<ProductionQueueInfo>().LowPowerSlowdown;
@@ -236,7 +236,7 @@ namespace OpenRA.Traits
}
var costThisFrame = RemainingCost / RemainingTime;
if (costThisFrame != 0 && !player.PlayerActor.traits.Get<PlayerResources>().TakeCash(costThisFrame)) return;
if (costThisFrame != 0 && !player.PlayerActor.Trait<PlayerResources>().TakeCash(costThisFrame)) return;
RemainingCost -= costThisFrame;
RemainingTime -= 1;
if (RemainingTime > 0) return;

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Traits
{
var effectivePrereq = prerequisites.Where( a => a.Traits.Get<BuildableInfo>().Owner.Contains( owner.Country.Race ) );
var nowHasPrerequisites = effectivePrereq.Any() &&
effectivePrereq.All( a => buildings[ a.Name ].Any( b => !b.traits.Get<Building>().Disabled ) );
effectivePrereq.All( a => buildings[ a.Name ].Any( b => !b.Trait<Building>().Disabled ) );
if( nowHasPrerequisites && !hasPrerequisites )
watcher.Available();

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Traits
{
public static bool IsPrimaryBuilding(this Actor a)
{
var pb = a.traits.GetOrDefault<PrimaryBuilding>();
var pb = a.TraitOrDefault<PrimaryBuilding>();
return pb != null && pb.IsPrimary;
}
}

View File

@@ -40,8 +40,8 @@ namespace OpenRA.Traits
public void DoProduction(Actor self, Actor newUnit, int2 exit, float2 spawn)
{
var move = newUnit.traits.Get<IMove>();
var facing = newUnit.traits.GetOrDefault<IFacing>();
var move = newUnit.Trait<IMove>();
var facing = newUnit.TraitOrDefault<IFacing>();
// Set the physical position of the unit as the exit cell
move.SetPosition(newUnit,exit);
@@ -58,7 +58,7 @@ namespace OpenRA.Traits
// For the target line
var target = exit;
var rp = self.traits.GetOrDefault<RallyPoint>();
var rp = self.TraitOrDefault<RallyPoint>();
if (rp != null)
{
target = rp.rallyPoint;
@@ -70,13 +70,13 @@ namespace OpenRA.Traits
{
self.World.AddFrameEndTask(w =>
{
var line = newUnit.traits.GetOrDefault<DrawLineToTarget>();
var line = newUnit.TraitOrDefault<DrawLineToTarget>();
if (line != null)
line.SetTargetSilently(newUnit, Target.FromCell(target), Color.Green);
});
}
foreach (var t in self.traits.WithInterface<INotifyProduction>())
foreach (var t in self.TraitsImplementing<INotifyProduction>())
t.UnitProduced(self, newUnit, exit);
Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID);
@@ -91,7 +91,7 @@ namespace OpenRA.Traits
// Todo: remove assumption on Mobile;
// required for 3-arg CanEnterCell
var mobile = newUnit.traits.Get<Mobile>();
var mobile = newUnit.Trait<Mobile>();
// Pick a spawn/exit point pair
// Todo: Reorder in a synced random way

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Traits
bool UpdateActive(Actor self)
{
// Check if powered
var b = self.traits.Get<Building>();
var b = self.Trait<Building>();
if (b.Disabled) return false;
var isJammed = self.World.Queries.WithTrait<JamsRadar>().Any(a => self.Owner != a.Actor.Owner

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Traits
RepairableBuildingInfo Info;
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
{
Health = self.traits.Get<Health>();
Health = self.Trait<Health>();
Info = info;
}
@@ -60,7 +60,7 @@ namespace OpenRA.Traits
var costPerHp = (Info.RepairPercent * buildingValue) / Health.MaxHP;
var hpToRepair = Math.Min(Info.RepairStep, Health.MaxHP - Health.HP);
var cost = (int)Math.Ceiling(costPerHp * hpToRepair);
if (!self.Owner.PlayerActor.traits.Get<PlayerResources>().TakeCash(cost))
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost))
{
remainingTicks = 1;
return;

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Traits
if (!self.IsIdle && previousLocation != self.Location)
{
previousLocation = self.Location;
self.World.WorldActor.traits.Get<Shroud>().UpdateActor(self);
self.World.WorldActor.Trait<Shroud>().UpdateActor(self);
}
}

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Traits
void DrawHealthBar(Actor self, float2 xy, float2 Xy)
{
var health = self.traits.GetOrDefault<Health>();
var health = self.TraitOrDefault<Health>();
if (self.IsDead() || health == null)
return;
@@ -107,7 +107,7 @@ namespace OpenRA.Traits
var pipxyBase = basePosition + new float2(-12, -7); // Correct for the offset in the shp file
var pipxyOffset = new float2(0, 0); // Correct for offset due to multiple columns/rows
foreach (var pips in self.traits.WithInterface<IPips>())
foreach (var pips in self.TraitsImplementing<IPips>())
{
foreach (var pip in pips.GetPips(self))
{
@@ -135,7 +135,7 @@ namespace OpenRA.Traits
var tagxyBase = basePosition + new float2(-16, 2); // Correct for the offset in the shp file
var tagxyOffset = new float2(0, 0); // Correct for offset due to multiple rows
foreach (var tags in self.traits.WithInterface<ITags>())
foreach (var tags in self.TraitsImplementing<ITags>())
{
foreach (var tag in tags.GetTags())
{
@@ -154,9 +154,9 @@ namespace OpenRA.Traits
void DrawUnitPath(Actor self)
{
if (!Game.world.LocalPlayer.PlayerActor.traits.Get<DeveloperMode>().PathDebug) return;
if (!Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().PathDebug) return;
var mobile = self.traits.GetOrDefault<IMove>();
var mobile = self.TraitOrDefault<IMove>();
if (mobile != null)
{
var alt = new float2(0, -mobile.Altitude);

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Traits
RemainingTime = TotalTime;
Owner = self.Owner;
self.traits.Get<TechTreeCache>().Add( Info.Prerequisites.Select( a => Rules.Info[ a.ToLowerInvariant() ] ).ToList(), this );
self.Trait<TechTreeCache>().Add( Info.Prerequisites.Select( a => Rules.Info[ a.ToLowerInvariant() ] ).ToList(), this );
}
public void Tick(Actor self)
@@ -69,7 +69,7 @@ namespace OpenRA.Traits
if (IsAvailable && (!Info.RequiresPower || IsPowered()))
{
if (Game.LobbyInfo.GlobalSettings.AllowCheats && self.traits.Get<DeveloperMode>().FastCharge) RemainingTime = 0;
if (Game.LobbyInfo.GlobalSettings.AllowCheats && self.Trait<DeveloperMode>().FastCharge) RemainingTime = 0;
if (RemainingTime > 0) --RemainingTime;
if (!notifiedCharging)
{
@@ -96,10 +96,10 @@ namespace OpenRA.Traits
.Where(a => Rules.Info[a].Traits.Get<ValuedInfo>().Owner.Contains(Owner.Country.Race));
if (Info.Prerequisites.Count() == 0)
return Owner.PlayerActor.traits.Get<PlayerResources>().GetPowerState() == PowerState.Normal;
return Owner.PlayerActor.Trait<PlayerResources>().GetPowerState() == PowerState.Normal;
return effectivePrereq.Any() &&
effectivePrereq.All(a => buildings[a].Any(b => !b.traits.Get<Building>().Disabled));
effectivePrereq.All(a => buildings[a].Any(b => !b.Trait<Building>().Disabled));
}
public void FinishActivate()

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Traits
{
this.info = info;
turretFacing = info.InitialFacing;
facing = self.traits.GetOrDefault<IFacing>();
facing = self.TraitOrDefault<IFacing>();
}
public void Tick( Actor self )

View File

@@ -1,17 +1,17 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 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. For more information,
* see LICENSE.
*/
#endregion
using System;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
#region Copyright & License Information
/*
* Copyright 2007-2010 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. For more information,
* see LICENSE.
*/
#endregion
using System;
using System.Drawing;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
namespace OpenRA.Traits
@@ -37,9 +37,9 @@ namespace OpenRA.Traits
bibSprites = info.BibTypes.Select(x => SpriteSheetBuilder.LoadAllSprites(x)).ToArray();
self.World.ActorAdded +=
a => { if (a.traits.Contains<Bib>()) DoBib(a,true); };
a => { if (a.HasTrait<Bib>()) DoBib(a,true); };
self.World.ActorRemoved +=
a => { if (a.traits.Contains<Bib>()) DoBib(a,false); };
a => { if (a.HasTrait<Bib>()) DoBib(a,false); };
}
public void WorldLoaded(World w)
@@ -56,7 +56,7 @@ namespace OpenRA.Traits
int bib = Array.IndexOf(info.BibWidths,size);
if (bib < 0)
{
{
Log.Write("debug", "Cannot bib {0}-wide building {1}", size, b.Info.Name);
return;
}
@@ -72,23 +72,23 @@ namespace OpenRA.Traits
}
public void Render()
{
var cliprect = Game.viewport.ShroudBounds().HasValue
? Rectangle.Intersect(Game.viewport.ShroudBounds().Value, world.Map.Bounds) : world.Map.Bounds;
var minx = cliprect.Left;
var maxx = cliprect.Right;
var miny = cliprect.Top;
var maxy = cliprect.Bottom;
for (int x = minx; x < maxx; x++)
{
var cliprect = Game.viewport.ShroudBounds().HasValue
? Rectangle.Intersect(Game.viewport.ShroudBounds().Value, world.Map.Bounds) : world.Map.Bounds;
var minx = cliprect.Left;
var maxx = cliprect.Right;
var miny = cliprect.Top;
var maxy = cliprect.Bottom;
for (int x = minx; x < maxx; x++)
for (int y = miny; y < maxy; y++)
{
var t = new int2(x, y);
if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(t) || tiles[x,y].type == 0) continue;
Game.Renderer.SpriteRenderer.DrawSprite(bibSprites[tiles[x, y].type - 1][tiles[x, y].image],
if (world.LocalPlayer != null && !world.LocalPlayer.Shroud.IsExplored(t) || tiles[x,y].type == 0) continue;
Game.Renderer.SpriteRenderer.DrawSprite(bibSprites[tiles[x, y].type - 1][tiles[x, y].image],
Game.CellSize * t, "terrain");
}
}

View File

@@ -32,11 +32,11 @@ namespace OpenRA.Traits
influence = new Actor[map.MapSize.X, map.MapSize.Y];
world.ActorAdded +=
a => { if (a.traits.Contains<Building>())
ChangeInfluence(a, a.traits.Get<Building>(), true); };
a => { if (a.HasTrait<Building>())
ChangeInfluence(a, a.Trait<Building>(), true); };
world.ActorRemoved +=
a => { if (a.traits.Contains<Building>())
ChangeInfluence(a, a.traits.Get<Building>(), false); };
a => { if (a.HasTrait<Building>())
ChangeInfluence(a, a.Trait<Building>(), false); };
}
void ChangeInfluence( Actor a, Building building, bool isAdd )

View File

@@ -55,7 +55,7 @@ namespace OpenRA.Traits
this.world = w;
content = new CellContents[w.Map.MapSize.X, w.Map.MapSize.Y];
resourceTypes = w.WorldActor.traits.WithInterface<ResourceType>().ToArray();
resourceTypes = w.WorldActor.TraitsImplementing<ResourceType>().ToArray();
foreach (var rt in resourceTypes)
rt.info.Sprites = rt.info.SpriteNames.Select(a => SpriteSheetBuilder.LoadAllSprites(a)).ToArray();

View File

@@ -64,7 +64,7 @@ namespace OpenRA.Traits
void AddActor(Actor a)
{
if (!a.traits.Contains<RevealsShroud>())
if (!a.HasTrait<RevealsShroud>())
return;
if (a.Owner == null || a.Owner.World.LocalPlayer == null
@@ -78,7 +78,7 @@ namespace OpenRA.Traits
var v = new ActorVisibility
{
range = a.traits.Get<RevealsShroud>().RevealRange,
range = a.Trait<RevealsShroud>().RevealRange,
vis = GetVisOrigins(a).ToArray()
};
@@ -129,7 +129,7 @@ namespace OpenRA.Traits
}
else
{
var mobile = a.traits.GetOrDefault<Mobile>();
var mobile = a.TraitOrDefault<Mobile>();
if (mobile != null)
return new[] { mobile.fromCell, mobile.toCell };
else

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Traits
for (int j = 0; j < world.Map.MapSize.Y; j++)
influence[ i, j ] = new List<Actor>();
world.ActorRemoved += a => Remove( a, a.traits.GetOrDefault<IOccupySpace>() );
world.ActorRemoved += a => Remove( a, a.TraitOrDefault<IOccupySpace>() );
}
public void Tick( Actor self )
@@ -49,7 +49,7 @@ namespace OpenRA.Traits
for( int y = 0 ; y < self.World.Map.MapSize.Y ; y++ )
if( influence[ x, y ] != null )
foreach (var a in influence[ x, y ])
if (!a.traits.Get<IOccupySpace>().OccupiedCells().Contains( new int2( x, y ) ) )
if (!a.Trait<IOccupySpace>().OccupiedCells().Contains( new int2( x, y ) ) )
throw new InvalidOperationException( "UIM: Sanity check failed A" );
foreach( var t in self.World.Queries.WithTraitMultiple<IOccupySpace>() )

View File

@@ -44,7 +44,7 @@ namespace OpenRA
{
if (Game.Settings.UnitDebug)
{
var uim = world.WorldActor.traits.Get<UnitInfluence>();
var uim = world.WorldActor.Trait<UnitInfluence>();
for (var i = world.Map.Bounds.Left; i < world.Map.Bounds.Right; i++)
for (var j = world.Map.Bounds.Top; j < world.Map.Bounds.Bottom; j++)
@@ -68,7 +68,7 @@ namespace OpenRA
}
else
{
var res = world.WorldActor.traits.Get<ResourceLayer>();
var res = world.WorldActor.Trait<ResourceLayer>();
var isCloseEnough = world.IsCloseEnoughToBase(world.LocalPlayer, name, bi, topLeft);
foreach (var t in Footprint.Tiles(name, bi, topLeft))
Game.Renderer.SpriteRenderer.DrawSprite((isCloseEnough && world.IsCellBuildable(t, bi.WaterBound) && res.GetResource(t) == null)

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Widgets.Delegates
};
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_CHECKBOX_SHROUD").Checked =
() => Game.world.LocalPlayer.PlayerActor.traits.Get<DeveloperMode>().DisableShroud;
() => Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().DisableShroud;
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_CHECKBOX_SHROUD").OnMouseDown = mi =>
{
Game.IssueOrder(new Order("DevShroud", Game.world.LocalPlayer.PlayerActor));
@@ -57,7 +57,7 @@ namespace OpenRA.Widgets.Delegates
};
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_CHECKBOX_PATHDEBUG").Checked =
() => Game.world.LocalPlayer.PlayerActor.traits.Get<DeveloperMode>().PathDebug;
() => Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().PathDebug;
devmodeBG.GetWidget("SETTINGS_CHECKBOX_PATHDEBUG").OnMouseDown = mi =>
{
Game.IssueOrder(new Order("DevPathDebug", Game.world.LocalPlayer.PlayerActor));
@@ -71,7 +71,7 @@ namespace OpenRA.Widgets.Delegates
};
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_BUILD_SPEED").Checked =
() => Game.world.LocalPlayer.PlayerActor.traits.Get<DeveloperMode>().FastBuild;
() => Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().FastBuild;
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_BUILD_SPEED").OnMouseDown = mi =>
{
Game.IssueOrder(new Order("DevFastBuild", Game.world.LocalPlayer.PlayerActor));
@@ -79,7 +79,7 @@ namespace OpenRA.Widgets.Delegates
};
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_CHARGE_TIME").Checked =
() => Game.world.LocalPlayer.PlayerActor.traits.Get<DeveloperMode>().FastCharge;
() => Game.world.LocalPlayer.PlayerActor.Trait<DeveloperMode>().FastCharge;
devmodeBG.GetWidget<CheckboxWidget>("SETTINGS_CHARGE_TIME").OnMouseDown = mi =>
{
Game.IssueOrder(new Order("DevFastCharge", Game.world.LocalPlayer.PlayerActor));

View File

@@ -96,7 +96,7 @@ namespace OpenRA.Widgets
var done = false;
foreach (var o in orders)
{
foreach (var v in o.Subject.traits.WithInterface<IOrderVoice>())
foreach (var v in o.Subject.TraitsImplementing<IOrderVoice>())
{
if (Sound.PlayVoice(v.VoicePhraseForOrder(o.Subject, o), o.Subject))
{
@@ -174,7 +174,7 @@ namespace OpenRA.Widgets
IEnumerable<Actor> SelectActorsInBox(World world, float2 a, float2 b)
{
return world.FindUnits(a, b)
.Where( x => x.traits.Contains<Selectable>() && x.IsVisible() )
.Where( x => x.HasTrait<Selectable>() && x.IsVisible() )
.GroupBy(x => (x.Owner == world.LocalPlayer) ? x.Info.Traits.Get<SelectableInfo>().Priority : 0)
.OrderByDescending(g => g.Key)
.Select( g => g.AsEnumerable() )

View File

@@ -116,7 +116,7 @@ namespace OpenRA
Timer.Time( "worldActor: {0}" );
foreach (var wlh in WorldActor.traits.WithInterface<ILoadWorldHook>())
foreach (var wlh in WorldActor.TraitsImplementing<ILoadWorldHook>())
wlh.WorldLoaded(this);
PathFinder = new PathFinder(this);
@@ -235,8 +235,8 @@ namespace OpenRA
return ret;
ret = new CachedView<Actor, TraitPair<T>>(
set,
x => x.traits.Contains<T>(),
x => new TraitPair<T> { Actor = x, Trait = x.traits.Get<T>() } );
x => x.HasTrait<T>(),
x => new TraitPair<T> { Actor = x, Trait = x.Trait<T>() } );
hasTrait.Add( ret );
return ret;
}
@@ -248,8 +248,8 @@ namespace OpenRA
return ret;
ret = new CachedView<Actor, TraitPair<T>>(
world.actors,
x => x.traits.Contains<T>(),
x => x.traits.WithInterface<T>().Select( t => new TraitPair<T> { Actor = x, Trait = t } ) );
x => x.HasTrait<T>(),
x => x.TraitsImplementing<T>().Select( t => new TraitPair<T> { Actor = x, Trait = t } ) );
hasTrait.Add( ret );
return ret;
}

View File

@@ -28,8 +28,8 @@ namespace OpenRA
public static bool IsCellBuildable(this World world, int2 a, bool waterBound, Actor toIgnore)
{
if (world.WorldActor.traits.Get<BuildingInfluence>().GetBuildingAt(a) != null) return false;
if (world.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(a).Any(b => b != toIgnore)) return false;
if (world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(a) != null) return false;
if (world.WorldActor.Trait<UnitInfluence>().GetUnitsAt(a).Any(b => b != toIgnore)) return false;
if (waterBound)
return world.Map.IsInMap(a.X,a.Y) && GetTerrainInfo(world,a).IsWater;
@@ -47,7 +47,7 @@ namespace OpenRA
{
var u = float2.Min(a, b).ToInt2();
var v = float2.Max(a, b).ToInt2();
return world.WorldActor.traits.Get<SpatialBins>().ActorsInBox(u,v);
return world.WorldActor.Trait<SpatialBins>().ActorsInBox(u,v);
}
public static IEnumerable<Actor> FindUnitsInCircle(this World world, float2 a, float r)
@@ -95,7 +95,7 @@ namespace OpenRA
public static bool CanPlaceBuilding(this World world, string name, BuildingInfo building, int2 topLeft, Actor toIgnore)
{
var res = world.WorldActor.traits.Get<ResourceLayer>();
var res = world.WorldActor.Trait<ResourceLayer>();
return Footprint.Tiles(name, building, topLeft).All(
t => world.Map.IsInMap(t.X, t.Y) && res.GetResource(t) == null &&
world.IsCellBuildable(t, building.WaterBound, toIgnore));
@@ -106,11 +106,11 @@ namespace OpenRA
if (a.World.LocalPlayer != null && a.World.LocalPlayer.Shroud.Disabled)
return true;
var shroud = a.World.WorldActor.traits.Get<Shroud>();
var shroud = a.World.WorldActor.Trait<Shroud>();
if (!Shroud.GetVisOrigins(a).Any(o => a.World.Map.IsInMap(o) && shroud.exploredCells[o.X, o.Y])) // covered by shroud
return false;
if (a.traits.WithInterface<IVisibilityModifier>().Any(t => !t.IsVisible(a)))
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a)))
return false;
return true;
@@ -131,7 +131,7 @@ namespace OpenRA
{
for( int x = scanStart.X ; x < scanEnd.X ; x++ )
{
var at = world.WorldActor.traits.Get<BuildingInfluence>().GetBuildingAt( new int2( x, y ) );
var at = world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt( new int2( x, y ) );
if( at != null && at.Owner.Stances[ p ] == Stance.Ally && at.Info.Traits.Get<BuildingInfo>().BaseNormal )
nearnessCandidates.Add( new int2( x, y ) );
}