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)
{
foreach (var g in World.Actors.Where(a => !a.Disposed
&& a.Info.HasTraitInfo<SelectableInfo>()
foreach (var g in World.ActorsHavingTrait<Selectable>().Where(a => !a.Disposed
&& !World.FogObscures(a)
&& !World.Selection.Actors.Contains(a)))

View File

@@ -107,6 +107,16 @@ namespace OpenRA
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)
{
foreach (var t in traits)
@@ -196,6 +206,33 @@ namespace OpenRA
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>>
{
readonly TraitContainer<T> container;

View File

@@ -351,6 +351,16 @@ namespace OpenRA
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)
{
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 (failCount >= ai.Info.MaximumFailedPlacementAttempts && --failRetryTicks <= 0)
{
var currentBuildings = world.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == player)
.Count();
var baseProviders = world.ActorsWithTrait<BaseProvider>()
.Where(a => a.Actor.Owner == player)
.Count();
var currentBuildings = world.ActorsHavingTrait<Building>().Count(a => a.Owner == player);
var baseProviders = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
// 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.
@@ -89,9 +84,7 @@ namespace OpenRA.Mods.Common.AI
if (waterState == Water.NotEnoughWater && --checkForBasesTicks <= 0)
{
var currentBases = world.ActorsWithTrait<BaseProvider>()
.Where(a => a.Actor.Owner == player)
.Count();
var currentBases = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
if (currentBases > cachedBases)
{
@@ -104,10 +97,7 @@ namespace OpenRA.Mods.Common.AI
if (--waitTicks > 0)
return;
playerBuildings = world.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == player)
.Select(a => a.Actor)
.ToArray();
playerBuildings = world.ActorsHavingTrait<Building>().Where(a => a.Owner == player).ToArray();
var active = false;
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 (failCount == ai.Info.MaximumFailedPlacementAttempts)
{
cachedBuildings = world.ActorsWithTrait<Building>()
.Where(a => a.Actor.Owner == player)
.Count();
cachedBases = world.ActorsWithTrait<BaseProvider>()
.Where(a => a.Actor.Owner == player)
.Count();
cachedBuildings = world.ActorsHavingTrait<Building>().Count(a => a.Owner == player);
cachedBases = world.ActorsHavingTrait<BaseProvider>().Count(a => a.Owner == player);
}
}
else

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Activities
public Hunt(Actor self)
{
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)
&& 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)
{
return !player.World.ActorsWithTrait<MustBeDestroyed>().Any(p =>
{
return p.Actor.Owner == player &&
(player.World.LobbyInfo.GlobalSettings.ShortGame ? p.Trait.Info.RequiredForShortGame : p.Actor.IsInWorld);
});
if (player.World.LobbyInfo.GlobalSettings.ShortGame)
return !player.World.ActorsHavingTrait<MustBeDestroyed>(t => t.Info.RequiredForShortGame).Any(a => a.Owner == player);
return !player.World.ActorsHavingTrait<MustBeDestroyed>().Any(a => a.Owner == player && a.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.")]
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>())
.ToArray();
}

View File

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

View File

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

View File

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

View File

@@ -114,9 +114,8 @@ namespace OpenRA.Mods.Common.Traits
if (proc == null) return;
if (proc.Disposed) return;
var linkedHarvs = proc.World.ActorsWithTrait<Harvester>()
.Where(a => a.Trait.LinkedProc == proc)
.Select(a => Target.FromActor(a.Actor))
var linkedHarvs = proc.World.ActorsHavingTrait<Harvester>(h => h.LinkedProc == proc)
.Select(a => Target.FromActor(a))
.ToList();
proc.SetTargetLines(linkedHarvs, Color.Gold);
@@ -163,7 +162,7 @@ namespace OpenRA.Mods.Common.Traits
.Select(r => new {
Location = r.Actor.Location + r.Trait.DeliveryOffset,
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);
// 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 selfsameBuildingsCount = self.World.ActorsWithTrait<Production>()
var selfsameProductionsCount = self.World.ActorsWithTrait<Production>()
.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;
}

View File

@@ -266,7 +266,7 @@ namespace OpenRA.Mods.Common.Traits
if (!developerMode.AllTech && bi.BuildLimit > 0)
{
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);
if (fromLimit <= 0)

View File

@@ -56,13 +56,13 @@ namespace OpenRA.Mods.Common.Traits
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(); } }
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; } }

View File

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

View File

@@ -31,8 +31,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var ticker = widget.Get<LogicTickerWidget>("RADAR_TICKER");
ticker.OnTick = () =>
{
radarEnabled = devMode.DisableShroud || world.ActorsWithTrait<ProvidesRadar>()
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive);
radarEnabled = devMode.DisableShroud || world.ActorsHavingTrait<ProvidesRadar>(r => r.IsActive)
.Any(a => a.Owner == world.LocalPlayer);
if (radarEnabled != cachedRadarEnabled)
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;
var assets = template.Get<LabelWidget>("ASSETS");
assets.GetText = () => "$" + world.Actors
.Where(a => a.Owner == player && !a.IsDead && a.Info.HasTraitInfo<ValuedInfo>())
assets.GetText = () => "$" + world.ActorsHavingTrait<Valued>()
.Where(a => a.Owner == player && !a.IsDead)
.Sum(a => a.Info.TraitInfos<ValuedInfo>().First().Cost);
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;
}
@@ -280,7 +280,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
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)
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));
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));
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));
curX += 32;
@@ -96,8 +96,8 @@ namespace OpenRA.Mods.Common.Widgets
void Init()
{
var visible = world.ActorsWithTrait<StrategicVictoryConditions>().Any() &&
world.ActorsWithTrait<StrategicPoint>().Any();
var visible = world.ActorsHavingTrait<StrategicVictoryConditions>().Any() &&
world.ActorsHavingTrait<StrategicPoint>().Any();
IsVisible = () => visible;
initialised = true;

View File

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

View File

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

View File

@@ -31,15 +31,15 @@ namespace OpenRA.Mods.D2k.Traits
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())
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())
return;
var refinery = refineries.First().Actor;
var refinery = refineries.First();
var delivery = refinery.Trait<FreeActorWithDelivery>();
delivery.DoDelivery(refinery.Location + delivery.Info.DeliveryOffset, delivery.Info.Actor,
delivery.Info.DeliveringActor);

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.D2k.Traits
public WormManager(Actor self, WormManagerInfo 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)

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Traits
void RefreshGranted()
{
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)
Owner.Shroud.ExploreAll(Owner.World);