Add ActorsHavingTrait<TTrait>([Func<TTrait, bool])

This commit is contained in:
atlimit8
2015-10-25 04:45:53 -05:00
parent 0997f5b52f
commit b6f17df260
27 changed files with 132 additions and 125 deletions

View File

@@ -185,8 +185,7 @@ namespace OpenRA.Graphics
if (World.Type == WorldType.Regular && Game.Settings.Game.AlwaysShowStatusBars) if (World.Type == WorldType.Regular && Game.Settings.Game.AlwaysShowStatusBars)
{ {
foreach (var g in World.Actors.Where(a => !a.Disposed foreach (var g in World.ActorsHavingTrait<Selectable>().Where(a => !a.Disposed
&& a.Info.HasTraitInfo<SelectableInfo>()
&& !World.FogObscures(a) && !World.FogObscures(a)
&& !World.Selection.Actors.Contains(a))) && !World.Selection.Actors.Contains(a)))

View File

@@ -107,6 +107,16 @@ namespace OpenRA
return InnerGet<T>().All(); return InnerGet<T>().All();
} }
public IEnumerable<Actor> ActorsHavingTrait<T>()
{
return InnerGet<T>().Actors();
}
public IEnumerable<Actor> ActorsHavingTrait<T>(Func<T, bool> predicate)
{
return InnerGet<T>().Actors(predicate);
}
public void RemoveActor(Actor a) public void RemoveActor(Actor a)
{ {
foreach (var t in traits) foreach (var t in traits)
@@ -196,6 +206,33 @@ namespace OpenRA
return new AllEnumerable(this); return new AllEnumerable(this);
} }
public IEnumerable<Actor> Actors()
{
++Queries;
Actor last = null;
for (var i = 0; i < actors.Count; i++)
{
if (actors[i] == last)
continue;
yield return actors[i];
last = actors[i];
}
}
public IEnumerable<Actor> Actors(Func<T, bool> predicate)
{
++Queries;
Actor last = null;
for (var i = 0; i < actors.Count; i++)
{
if (actors[i] == last || !predicate(traits[i]))
continue;
yield return actors[i];
last = actors[i];
}
}
class AllEnumerable : IEnumerable<TraitPair<T>> class AllEnumerable : IEnumerable<TraitPair<T>>
{ {
readonly TraitContainer<T> container; readonly TraitContainer<T> container;

View File

@@ -351,6 +351,16 @@ namespace OpenRA
return TraitDict.ActorsWithTrait<T>(); return TraitDict.ActorsWithTrait<T>();
} }
public IEnumerable<Actor> ActorsHavingTrait<T>()
{
return TraitDict.ActorsHavingTrait<T>();
}
public IEnumerable<Actor> ActorsHavingTrait<T>(Func<T, bool> predicate)
{
return TraitDict.ActorsHavingTrait<T>(predicate);
}
public void OnPlayerWinStateChanged(Player player) public void OnPlayerWinStateChanged(Player player)
{ {
var pi = gameInfo.GetPlayer(player); var pi = gameInfo.GetPlayer(player);

View File

@@ -59,13 +59,8 @@ namespace OpenRA.Mods.Common.AI
// If failed to place something N consecutive times, wait M ticks until resuming building production // If failed to place something N consecutive times, wait M ticks until resuming building production
if (failCount >= ai.Info.MaximumFailedPlacementAttempts && --failRetryTicks <= 0) if (failCount >= ai.Info.MaximumFailedPlacementAttempts && --failRetryTicks <= 0)
{ {
var currentBuildings = world.ActorsWithTrait<Building>() var currentBuildings = world.ActorsHavingTrait<Building>().Count(a => a.Owner == player);
.Where(a => a.Actor.Owner == player) var baseProviders = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
.Count();
var baseProviders = world.ActorsWithTrait<BaseProvider>()
.Where(a => a.Actor.Owner == player)
.Count();
// Only bother resetting failCount if either a) the number of buildings has decreased since last failure M ticks ago, // Only bother resetting failCount if either a) the number of buildings has decreased since last failure M ticks ago,
// or b) number of BaseProviders (construction yard or similar) has increased since then. // or b) number of BaseProviders (construction yard or similar) has increased since then.
@@ -89,9 +84,7 @@ namespace OpenRA.Mods.Common.AI
if (waterState == Water.NotEnoughWater && --checkForBasesTicks <= 0) if (waterState == Water.NotEnoughWater && --checkForBasesTicks <= 0)
{ {
var currentBases = world.ActorsWithTrait<BaseProvider>() var currentBases = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
.Where(a => a.Actor.Owner == player)
.Count();
if (currentBases > cachedBases) if (currentBases > cachedBases)
{ {
@@ -104,10 +97,7 @@ namespace OpenRA.Mods.Common.AI
if (--waitTicks > 0) if (--waitTicks > 0)
return; return;
playerBuildings = world.ActorsWithTrait<Building>() playerBuildings = world.ActorsHavingTrait<Building>().Where(a => a.Owner == player).ToArray();
.Where(a => a.Actor.Owner == player)
.Select(a => a.Actor)
.ToArray();
var active = false; var active = false;
foreach (var queue in ai.FindQueues(category)) foreach (var queue in ai.FindQueues(category))
@@ -158,13 +148,8 @@ namespace OpenRA.Mods.Common.AI
// If we just reached the maximum fail count, cache the number of current structures // If we just reached the maximum fail count, cache the number of current structures
if (failCount == ai.Info.MaximumFailedPlacementAttempts) if (failCount == ai.Info.MaximumFailedPlacementAttempts)
{ {
cachedBuildings = world.ActorsWithTrait<Building>() cachedBuildings = world.ActorsHavingTrait<Building>().Count(a => a.Owner == player);
.Where(a => a.Actor.Owner == player) cachedBases = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
.Count();
cachedBases = world.ActorsWithTrait<BaseProvider>()
.Where(a => a.Actor.Owner == player)
.Count();
} }
} }
else else

View File

@@ -171,10 +171,8 @@ namespace OpenRA.Mods.Common.AI
public CPos GetRandomBaseCenter() public CPos GetRandomBaseCenter()
{ {
var randomBaseBuilding = World.Actors.Where( var randomBaseBuilding = World.ActorsHavingTrait<BaseBuilding>()
a => a.Owner == Player .Where(a => a.Owner == Player && !a.Info.HasTraitInfo<MobileInfo>())
&& a.Info.HasTraitInfo<BaseBuildingInfo>()
&& !a.Info.HasTraitInfo<MobileInfo>())
.RandomOrDefault(Random); .RandomOrDefault(Random);
return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter; return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter;
@@ -288,10 +286,8 @@ namespace OpenRA.Mods.Common.AI
// TODO: Possibly give this a more generic name when terrain type is unhardcoded // TODO: Possibly give this a more generic name when terrain type is unhardcoded
public bool EnoughWaterToBuildNaval() public bool EnoughWaterToBuildNaval()
{ {
var baseProviders = World.Actors.Where( var baseProviders = World.ActorsHavingTrait<BaseProvider>()
a => a.Owner == Player .Where(a => a.Owner == Player && !a.Info.HasTraitInfo<MobileInfo>());
&& a.Info.HasTraitInfo<BaseProviderInfo>()
&& !a.Info.HasTraitInfo<MobileInfo>());
foreach (var b in baseProviders) foreach (var b in baseProviders)
{ {
@@ -315,10 +311,8 @@ namespace OpenRA.Mods.Common.AI
// Check whether we have at least one building providing buildable area close enough to water to build naval structures // Check whether we have at least one building providing buildable area close enough to water to build naval structures
public bool CloseEnoughToWater() public bool CloseEnoughToWater()
{ {
var areaProviders = World.Actors.Where( var areaProviders = World.ActorsHavingTrait<GivesBuildableArea>()
a => a.Owner == Player .Where(a => a.Owner == Player && !a.Info.HasTraitInfo<MobileInfo>());
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>()
&& !a.Info.HasTraitInfo<MobileInfo>());
foreach (var a in areaProviders) foreach (var a in areaProviders)
{ {
@@ -361,9 +355,9 @@ namespace OpenRA.Mods.Common.AI
return null; return null;
var myUnits = Player.World var myUnits = Player.World
.ActorsWithTrait<IPositionable>() .ActorsHavingTrait<IPositionable>()
.Where(a => a.Actor.Owner == Player) .Where(a => a.Owner == Player)
.Select(a => a.Actor.Info.Name).ToList(); .Select(a => a.Info.Name).ToList();
foreach (var unit in Info.UnitsToBuild.Shuffle(Random)) foreach (var unit in Info.UnitsToBuild.Shuffle(Random))
if (buildableThings.Any(b => b.Name == unit.Key)) if (buildableThings.Any(b => b.Name == unit.Key))
@@ -376,14 +370,12 @@ namespace OpenRA.Mods.Common.AI
int CountBuilding(string frac, Player owner) int CountBuilding(string frac, Player owner)
{ {
return World.ActorsWithTrait<Building>() return World.ActorsHavingTrait<Building>().Count(a => a.Owner == owner && a.Info.Name == frac);
.Count(a => a.Actor.Owner == owner && a.Actor.Info.Name == frac);
} }
int CountUnits(string unit, Player owner) int CountUnits(string unit, Player owner)
{ {
return World.ActorsWithTrait<IPositionable>() return World.ActorsHavingTrait<IPositionable>().Count(a => a.Owner == owner && a.Info.Name == unit);
.Count(a => a.Actor.Owner == owner && a.Actor.Info.Name == unit);
} }
int? CountBuildingByCommonName(string commonName, Player owner) int? CountBuildingByCommonName(string commonName, Player owner)
@@ -391,8 +383,8 @@ namespace OpenRA.Mods.Common.AI
if (!Info.BuildingCommonNames.ContainsKey(commonName)) if (!Info.BuildingCommonNames.ContainsKey(commonName))
return null; return null;
return World.ActorsWithTrait<Building>() return World.ActorsHavingTrait<Building>()
.Count(a => a.Actor.Owner == owner && Info.BuildingCommonNames[commonName].Contains(a.Actor.Info.Name)); .Count(a => a.Owner == owner && Info.BuildingCommonNames[commonName].Contains(a.Info.Name));
} }
public ActorInfo GetBuildingInfoByCommonName(string commonName, Player owner) public ActorInfo GetBuildingInfoByCommonName(string commonName, Player owner)
@@ -498,7 +490,7 @@ namespace OpenRA.Mods.Common.AI
case BuildingType.Defense: case BuildingType.Defense:
// Build near the closest enemy structure // Build near the closest enemy structure
var closestEnemy = World.Actors.Where(a => !a.Disposed && a.Info.HasTraitInfo<BuildingInfo>() && Player.Stances[a.Owner] == Stance.Enemy) var closestEnemy = World.ActorsHavingTrait<Building>().Where(a => !a.Disposed && Player.Stances[a.Owner] == Stance.Enemy)
.ClosestTo(World.Map.CenterOfCell(defenseCenter)); .ClosestTo(World.Map.CenterOfCell(defenseCenter));
var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter; var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
@@ -573,8 +565,8 @@ namespace OpenRA.Mods.Common.AI
leastLikedEnemies.Random(Random) : liveEnemies.FirstOrDefault(); leastLikedEnemies.Random(Random) : liveEnemies.FirstOrDefault();
// Pick something worth attacking owned by that player // Pick something worth attacking owned by that player
var target = World.Actors var target = World.ActorsHavingTrait<IOccupySpace>()
.Where(a => a.Owner == enemy && a.OccupiesSpace != null) .Where(a => a.Owner == enemy)
.ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter())); .ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter()));
if (target == null) if (target == null)
@@ -605,8 +597,8 @@ namespace OpenRA.Mods.Common.AI
List<Actor> FindEnemyConstructionYards() List<Actor> FindEnemyConstructionYards()
{ {
return World.Actors.Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead return World.ActorsHavingTrait<BaseBuilding>()
&& a.Info.HasTraitInfo<BaseBuildingInfo>() && !a.Info.HasTraitInfo<MobileInfo>()).ToList(); .Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead && !a.Info.HasTraitInfo<MobileInfo>()).ToList();
} }
void CleanSquads() void CleanSquads()
@@ -716,10 +708,8 @@ namespace OpenRA.Mods.Common.AI
void FindNewUnits(Actor self) void FindNewUnits(Actor self)
{ {
var newUnits = self.World.ActorsWithTrait<IPositionable>() var newUnits = self.World.ActorsHavingTrait<IPositionable>()
.Where(a => a.Actor.Owner == Player && !a.Actor.Info.HasTraitInfo<BaseBuildingInfo>() .Where(a => a.Owner == Player && !a.Info.HasTraitInfo<BaseBuildingInfo>() && !activeUnits.Contains(a));
&& !activeUnits.Contains(a.Actor))
.Select(a => a.Actor);
foreach (var a in newUnits) foreach (var a in newUnits)
{ {
@@ -843,8 +833,7 @@ namespace OpenRA.Mods.Common.AI
void InitializeBase(Actor self) void InitializeBase(Actor self)
{ {
// Find and deploy our mcv // Find and deploy our mcv
var mcv = self.World.Actors var mcv = self.World.ActorsHavingTrait<BaseBuilding>().FirstOrDefault(a => a.Owner == Player);
.FirstOrDefault(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>());
if (mcv != null) if (mcv != null)
{ {
@@ -865,8 +854,8 @@ namespace OpenRA.Mods.Common.AI
void FindAndDeployBackupMcv(Actor self) void FindAndDeployBackupMcv(Actor self)
{ {
// HACK: This needs to query against MCVs directly // HACK: This needs to query against MCVs directly
var mcvs = self.World.Actors var mcvs = self.World.ActorsHavingTrait<BaseBuilding>()
.Where(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>()); .Where(a => a.Owner == Player && a.Info.HasTraitInfo<MobileInfo>());
foreach (var mcv in mcvs) foreach (var mcv in mcvs)
{ {
@@ -1023,8 +1012,8 @@ namespace OpenRA.Mods.Common.AI
return; return;
// No construction yards - Build a new MCV // No construction yards - Build a new MCV
if (!HasAdequateFact() && !self.World.Actors.Any(a => if (!HasAdequateFact() && !self.World.ActorsHavingTrait<BaseBuilding>()
a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>())) .Any(a => a.Owner == Player && a.Info.HasTraitInfo<MobileInfo>()))
BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name); BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name);
foreach (var q in Info.UnitQueues) foreach (var q in Info.UnitQueues)

View File

@@ -31,8 +31,8 @@ namespace OpenRA.Mods.Common.AI
protected static CPos RandomBuildingLocation(Squad squad) protected static CPos RandomBuildingLocation(Squad squad)
{ {
var location = squad.Bot.GetRandomBaseCenter(); var location = squad.Bot.GetRandomBaseCenter();
var buildings = squad.World.ActorsWithTrait<Building>() var buildings = squad.World.ActorsHavingTrait<Building>()
.Where(a => a.Actor.Owner == squad.Bot.Player).Select(a => a.Actor).ToList(); .Where(a => a.Owner == squad.Bot.Player).ToList();
if (buildings.Count > 0) if (buildings.Count > 0)
location = buildings.Random(squad.Random).Location; location = buildings.Random(squad.Random).Location;
return location; return location;

View File

@@ -42,9 +42,8 @@ namespace OpenRA.Mods.Common.Activities
if (dest == null) if (dest == null)
{ {
var rearmBuildings = heli.Info.RearmBuildings; var rearmBuildings = heli.Info.RearmBuildings;
var nearestHpad = self.World.ActorsWithTrait<Reservable>() var nearestHpad = self.World.ActorsHavingTrait<Reservable>()
.Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name)) .Where(a => a.Owner == self.Owner && rearmBuildings.Contains(a.Info.Name))
.Select(a => a.Actor)
.ClosestTo(self); .ClosestTo(self);
if (nearestHpad == null) if (nearestHpad == null)

View File

@@ -34,11 +34,10 @@ namespace OpenRA.Mods.Common.Activities
public static Actor ChooseAirfield(Actor self, bool unreservedOnly) public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
{ {
var rearmBuildings = self.Info.TraitInfo<AircraftInfo>().RearmBuildings; var rearmBuildings = self.Info.TraitInfo<AircraftInfo>().RearmBuildings;
return self.World.ActorsWithTrait<Reservable>() return self.World.ActorsHavingTrait<Reservable>()
.Where(a => a.Actor.Owner == self.Owner) .Where(a => a.Owner == self.Owner
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name) && rearmBuildings.Contains(a.Info.Name)
&& (!unreservedOnly || !Reservable.IsReserved(a.Actor))) && (!unreservedOnly || !Reservable.IsReserved(a)))
.Select(a => a.Actor)
.ClosestTo(self); .ClosestTo(self);
} }

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Activities
public Hunt(Actor self) public Hunt(Actor self)
{ {
var attack = self.Trait<AttackBase>(); var attack = self.Trait<AttackBase>();
targets = self.World.ActorsWithTrait<Huntable>().Select(p => p.Actor).Where( targets = self.World.ActorsHavingTrait<Huntable>().Where(
a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self) a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self)
&& IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a))); && IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
} }

View File

@@ -17,11 +17,9 @@ namespace OpenRA.Mods.Common
{ {
public static bool HasNoRequiredUnits(this Player player) public static bool HasNoRequiredUnits(this Player player)
{ {
return !player.World.ActorsWithTrait<MustBeDestroyed>().Any(p => if (player.World.LobbyInfo.GlobalSettings.ShortGame)
{ return !player.World.ActorsHavingTrait<MustBeDestroyed>(t => t.Info.RequiredForShortGame).Any(a => a.Owner == player);
return p.Actor.Owner == player && return !player.World.ActorsHavingTrait<MustBeDestroyed>().Any(a => a.Owner == player && a.IsInWorld);
(player.World.LobbyInfo.GlobalSettings.ShortGame ? p.Trait.Info.RequiredForShortGame : p.Actor.IsInWorld);
});
} }
} }
} }

View File

@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Scripting
[Desc("Returns an array of actors representing all ground attack units of this player.")] [Desc("Returns an array of actors representing all ground attack units of this player.")]
public Actor[] GetGroundAttackers() public Actor[] GetGroundAttackers()
{ {
return Player.World.ActorsWithTrait<AttackBase>().Select(a => a.Actor) return Player.World.ActorsHavingTrait<AttackBase>()
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo<MobileInfo>()) .Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo<MobileInfo>())
.ToArray(); .ToArray();
} }

View File

@@ -36,14 +36,12 @@ namespace OpenRA.Mods.Common.Traits
// nowhere to land, pick something friendly and circle over it. // nowhere to land, pick something friendly and circle over it.
// i'd prefer something we own // i'd prefer something we own
var someBuilding = self.World.ActorsWithTrait<Building>() var someBuilding = self.World.ActorsHavingTrait<Building>()
.Select(a => a.Actor)
.FirstOrDefault(a => a.Owner == self.Owner); .FirstOrDefault(a => a.Owner == self.Owner);
// failing that, something unlikely to shoot at us // failing that, something unlikely to shoot at us
if (someBuilding == null) if (someBuilding == null)
someBuilding = self.World.ActorsWithTrait<Building>() someBuilding = self.World.ActorsHavingTrait<Building>()
.Select(a => a.Actor)
.FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally); .FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally);
if (someBuilding == null) if (someBuilding == null)

View File

@@ -72,10 +72,9 @@ namespace OpenRA.Mods.Common.Traits
continue; // Cell is empty; continue search continue; // Cell is empty; continue search
// Cell contains an actor. Is it the type we want? // Cell contains an actor. Is it the type we want?
if (world.ActorsWithTrait<LineBuildNode>().Any(a => if (world.ActorsHavingTrait<LineBuildNode>()
(a.Actor.Location == cell && .Any(a => a.Location == cell
a.Actor.Info.TraitInfo<LineBuildNodeInfo>() && a.Info.TraitInfo<LineBuildNodeInfo>().Types.Overlaps(lbi.NodeTypes)))
.Types.Overlaps(lbi.NodeTypes))))
dirs[d] = i; // Cell contains actor of correct type dirs[d] = i; // Cell contains actor of correct type
else else
dirs[d] = -1; // Cell is blocked by another actor type dirs[d] = -1; // Cell is blocked by another actor type

View File

@@ -36,8 +36,8 @@ namespace OpenRA.Mods.Common.Traits
if (!CanGiveTo(collector)) if (!CanGiveTo(collector))
return 0; return 0;
var hasBase = collector.World.ActorsWithTrait<BaseBuilding>() var hasBase = collector.World.ActorsHavingTrait<BaseBuilding>()
.Any(a => a.Actor.Owner == collector.Owner); .Any(a => a.Owner == collector.Owner);
return hasBase ? info.SelectionShares : info.NoBaseSelectionShares; return hasBase ? info.SelectionShares : info.NoBaseSelectionShares;
} }

View File

@@ -114,9 +114,8 @@ namespace OpenRA.Mods.Common.Traits
if (proc == null) return; if (proc == null) return;
if (proc.Disposed) return; if (proc.Disposed) return;
var linkedHarvs = proc.World.ActorsWithTrait<Harvester>() var linkedHarvs = proc.World.ActorsHavingTrait<Harvester>(h => h.LinkedProc == proc)
.Where(a => a.Trait.LinkedProc == proc) .Select(a => Target.FromActor(a))
.Select(a => Target.FromActor(a.Actor))
.ToList(); .ToList();
proc.SetTargetLines(linkedHarvs, Color.Gold); proc.SetTargetLines(linkedHarvs, Color.Gold);
@@ -163,7 +162,7 @@ namespace OpenRA.Mods.Common.Traits
.Select(r => new { .Select(r => new {
Location = r.Actor.Location + r.Trait.DeliveryOffset, Location = r.Actor.Location + r.Trait.DeliveryOffset,
Actor = r.Actor, Actor = r.Actor,
Occupancy = self.World.ActorsWithTrait<Harvester>().Count(a => a.Trait.LinkedProc == r.Actor) }) Occupancy = self.World.ActorsHavingTrait<Harvester>(h => h.LinkedProc == r.Actor).Count() })
.ToDictionary(r => r.Location); .ToDictionary(r => r.Location);
// Start a search from each refinery's delivery location: // Start a search from each refinery's delivery location:

View File

@@ -133,10 +133,10 @@ namespace OpenRA.Mods.Common.Traits
{ {
var type = bi.BuildAtProductionType ?? info.Type; var type = bi.BuildAtProductionType ?? info.Type;
var selfsameBuildingsCount = self.World.ActorsWithTrait<Production>() var selfsameProductionsCount = self.World.ActorsWithTrait<Production>()
.Count(p => p.Actor.Owner == self.Owner && p.Trait.Info.Produces.Contains(type)); .Count(p => p.Actor.Owner == self.Owner && p.Trait.Info.Produces.Contains(type));
var speedModifier = selfsameBuildingsCount.Clamp(1, info.BuildTimeSpeedReduction.Length) - 1; var speedModifier = selfsameProductionsCount.Clamp(1, info.BuildTimeSpeedReduction.Length) - 1;
time = (time * info.BuildTimeSpeedReduction[speedModifier]) / 100; time = (time * info.BuildTimeSpeedReduction[speedModifier]) / 100;
} }

View File

@@ -266,7 +266,7 @@ namespace OpenRA.Mods.Common.Traits
if (!developerMode.AllTech && bi.BuildLimit > 0) if (!developerMode.AllTech && bi.BuildLimit > 0)
{ {
var inQueue = queue.Count(pi => pi.Item == order.TargetString); var inQueue = queue.Count(pi => pi.Item == order.TargetString);
var owned = self.Owner.World.ActorsWithTrait<Buildable>().Count(a => a.Actor.Info.Name == order.TargetString && a.Actor.Owner == self.Owner); var owned = self.Owner.World.ActorsHavingTrait<Buildable>().Count(a => a.Info.Name == order.TargetString && a.Owner == self.Owner);
fromLimit = bi.BuildLimit - (inQueue + owned); fromLimit = bi.BuildLimit - (inQueue + owned);
if (fromLimit <= 0) if (fromLimit <= 0)

View File

@@ -56,13 +56,13 @@ namespace OpenRA.Mods.Common.Traits
mo = self.Trait<MissionObjectives>(); mo = self.Trait<MissionObjectives>();
} }
public IEnumerable<TraitPair<StrategicPoint>> AllPoints public IEnumerable<Actor> AllPoints
{ {
get { return player.World.ActorsWithTrait<StrategicPoint>(); } get { return player.World.ActorsHavingTrait<StrategicPoint>(); }
} }
public int Total { get { return AllPoints.Count(); } } public int Total { get { return AllPoints.Count(); } }
int Owned { get { return AllPoints.Count(a => WorldUtils.AreMutualAllies(player, a.Actor.Owner)); } } int Owned { get { return AllPoints.Count(a => WorldUtils.AreMutualAllies(player, a.Owner)); } }
public bool Holding { get { return Owned >= info.RatioRequired * Total; } } public bool Holding { get { return Owned >= info.RatioRequired * Total; } }

View File

@@ -138,8 +138,7 @@ namespace OpenRA.Mods.Common.Traits
void UpdatePowerOutageActors() void UpdatePowerOutageActors()
{ {
var actors = self.World.ActorsWithTrait<AffectedByPowerOutage>() var actors = self.World.ActorsHavingTrait<AffectedByPowerOutage>()
.Select(tp => tp.Actor)
.Where(a => !a.IsDead && a.IsInWorld && a.Owner == self.Owner); .Where(a => !a.IsDead && a.IsInWorld && a.Owner == self.Owner);
foreach (var a in actors) foreach (var a in actors)

View File

@@ -31,8 +31,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var ticker = widget.Get<LogicTickerWidget>("RADAR_TICKER"); var ticker = widget.Get<LogicTickerWidget>("RADAR_TICKER");
ticker.OnTick = () => ticker.OnTick = () =>
{ {
radarEnabled = devMode.DisableShroud || world.ActorsWithTrait<ProvidesRadar>() radarEnabled = devMode.DisableShroud || world.ActorsHavingTrait<ProvidesRadar>(r => r.IsActive)
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive); .Any(a => a.Owner == world.LocalPlayer);
if (radarEnabled != cachedRadarEnabled) if (radarEnabled != cachedRadarEnabled)
Game.Sound.PlayNotification(world.Map.Rules, null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null); Game.Sound.PlayNotification(world.Map.Rules, null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null);

View File

@@ -240,12 +240,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
template.Get<LabelWidget>("SPENT").GetText = () => "$" + res.Spent; template.Get<LabelWidget>("SPENT").GetText = () => "$" + res.Spent;
var assets = template.Get<LabelWidget>("ASSETS"); var assets = template.Get<LabelWidget>("ASSETS");
assets.GetText = () => "$" + world.Actors assets.GetText = () => "$" + world.ActorsHavingTrait<Valued>()
.Where(a => a.Owner == player && !a.IsDead && a.Info.HasTraitInfo<ValuedInfo>()) .Where(a => a.Owner == player && !a.IsDead)
.Sum(a => a.Info.TraitInfos<ValuedInfo>().First().Cost); .Sum(a => a.Info.TraitInfos<ValuedInfo>().First().Cost);
var harvesters = template.Get<LabelWidget>("HARVESTERS"); var harvesters = template.Get<LabelWidget>("HARVESTERS");
harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.Info.HasTraitInfo<HarvesterInfo>()).ToString(); harvesters.GetText = () => world.ActorsHavingTrait<Harvester>().Count(a => a.Owner == player && !a.IsDead).ToString();
return template; return template;
} }
@@ -280,7 +280,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
return ScrollItemWidget.Setup(template, () => false, () => return ScrollItemWidget.Setup(template, () => false, () =>
{ {
var playerBase = world.Actors.FirstOrDefault(a => !a.IsDead && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Owner == player); var playerBase = world.ActorsHavingTrait<BaseBuilding>().FirstOrDefault(a => !a.IsDead && a.Owner == player);
if (playerBase != null) if (playerBase != null)
worldRenderer.Viewport.Center(playerBase.CenterPosition); worldRenderer.Viewport.Center(playerBase.CenterPosition);
}); });

View File

@@ -47,9 +47,9 @@ namespace OpenRA.Mods.Common.Widgets
{ {
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "critical_unowned"), offset + new float2(rb.Left + curX, rb.Top)); WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "critical_unowned"), offset + new float2(rb.Left + curX, rb.Top));
if (world.LocalPlayer != null && WorldUtils.AreMutualAllies(a.Actor.Owner, world.LocalPlayer)) if (world.LocalPlayer != null && WorldUtils.AreMutualAllies(a.Owner, world.LocalPlayer))
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(rb.Left + curX, rb.Top)); WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(rb.Left + curX, rb.Top));
else if (!a.Actor.Owner.NonCombatant) else if (!a.Owner.NonCombatant)
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(rb.Left + curX, rb.Top)); WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(rb.Left + curX, rb.Top));
curX += 32; curX += 32;
@@ -96,8 +96,8 @@ namespace OpenRA.Mods.Common.Widgets
void Init() void Init()
{ {
var visible = world.ActorsWithTrait<StrategicVictoryConditions>().Any() && var visible = world.ActorsHavingTrait<StrategicVictoryConditions>().Any() &&
world.ActorsWithTrait<StrategicPoint>().Any(); world.ActorsHavingTrait<StrategicPoint>().Any();
IsVisible = () => visible; IsVisible = () => visible;
initialised = true; initialised = true;

View File

@@ -193,16 +193,14 @@ namespace OpenRA.Mods.Common.Widgets
{ {
var player = world.RenderPlayer ?? world.LocalPlayer; var player = world.RenderPlayer ?? world.LocalPlayer;
var bases = world.ActorsWithTrait<BaseBuilding>() var bases = world.ActorsHavingTrait<BaseBuilding>()
.Where(a => a.Actor.Owner == player) .Where(a => a.Owner == player)
.Select(b => b.Actor)
.ToList(); .ToList();
// If no BaseBuilding exist pick the first selectable Building. // If no BaseBuilding exist pick the first selectable Building.
if (!bases.Any()) if (!bases.Any())
{ {
var building = world.ActorsWithTrait<Building>() var building = world.ActorsHavingTrait<Building>()
.Select(b => b.Actor)
.FirstOrDefault(a => a.Owner == player && a.Info.HasTraitInfo<SelectableInfo>()); .FirstOrDefault(a => a.Owner == player && a.Info.HasTraitInfo<SelectableInfo>());
// No buildings left // No buildings left
@@ -230,10 +228,9 @@ namespace OpenRA.Mods.Common.Widgets
{ {
var player = world.RenderPlayer ?? world.LocalPlayer; var player = world.RenderPlayer ?? world.LocalPlayer;
var facilities = world.ActorsWithTrait<Production>() var facilities = world.ActorsHavingTrait<Production>()
.Where(a => a.Actor.Owner == player && !a.Actor.Info.HasTraitInfo<BaseBuildingInfo>()) .Where(a => a.Owner == player && !a.Info.HasTraitInfo<BaseBuildingInfo>())
.OrderBy(f => f.Actor.Info.TraitInfo<ProductionInfo>().Produces.First()) .OrderBy(f => f.Info.TraitInfo<ProductionInfo>().Produces.First())
.Select(b => b.Actor)
.ToList(); .ToList();
if (!facilities.Any()) if (!facilities.Any())

View File

@@ -100,9 +100,8 @@ namespace OpenRA.Mods.D2k.Traits
public Actor GetClosestIdleCarrier() public Actor GetClosestIdleCarrier()
{ {
// Find carriers // Find carriers
var carriers = self.World.ActorsWithTrait<Carryall>() var carriers = self.World.ActorsHavingTrait<Carryall>(c => !c.IsBusy)
.Where(p => p.Actor.Owner == self.Owner && !p.Trait.IsBusy && p.Actor.IsInWorld) .Where(a => a.Owner == self.Owner && a.IsInWorld);
.Select(h => h.Actor);
return carriers.ClosestTo(self); return carriers.ClosestTo(self);
} }

View File

@@ -31,15 +31,15 @@ namespace OpenRA.Mods.D2k.Traits
public void TryActivate() public void TryActivate()
{ {
var harvesters = self.World.ActorsWithTrait<Harvester>().Where(x => x.Actor.Owner == self.Owner); var harvesters = self.World.ActorsHavingTrait<Harvester>().Where(x => x.Owner == self.Owner);
if (harvesters.Any()) if (harvesters.Any())
return; return;
var refineries = self.World.ActorsWithTrait<Refinery>().Where(x => x.Actor.Owner == self.Owner); var refineries = self.World.ActorsHavingTrait<Refinery>().Where(x => x.Owner == self.Owner);
if (!refineries.Any()) if (!refineries.Any())
return; return;
var refinery = refineries.First().Actor; var refinery = refineries.First();
var delivery = refinery.Trait<FreeActorWithDelivery>(); var delivery = refinery.Trait<FreeActorWithDelivery>();
delivery.DoDelivery(refinery.Location + delivery.Info.DeliveryOffset, delivery.Info.Actor, delivery.DoDelivery(refinery.Location + delivery.Info.DeliveryOffset, delivery.Info.Actor,
delivery.Info.DeliveringActor); delivery.Info.DeliveringActor);

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.D2k.Traits
public WormManager(Actor self, WormManagerInfo info) public WormManager(Actor self, WormManagerInfo info)
{ {
this.info = info; this.info = info;
spawnPointActors = Exts.Lazy(() => self.World.ActorsWithTrait<WormSpawner>().Select(x => x.Actor).ToArray()); spawnPointActors = Exts.Lazy(() => self.World.ActorsHavingTrait<WormSpawner>().ToArray());
} }
public void Tick(Actor self) public void Tick(Actor self)

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Traits
void RefreshGranted() void RefreshGranted()
{ {
Granted = actors.Count > 0 && Launched; Granted = actors.Count > 0 && Launched;
GrantedAllies = Owner.World.ActorsWithTrait<GpsWatcher>().Any(p => p.Actor.Owner.IsAlliedWith(Owner) && p.Trait.Granted); GrantedAllies = Owner.World.ActorsHavingTrait<GpsWatcher>(g => g.Granted).Any(p => p.Owner.IsAlliedWith(Owner));
if (Granted || GrantedAllies) if (Granted || GrantedAllies)
Owner.Shroud.ExploreAll(Owner.World); Owner.Shroud.ExploreAll(Owner.World);