Add ActorsHavingTrait<TTrait>([Func<TTrait, bool])
This commit is contained in:
@@ -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)))
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; } }
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user