From 8162fa27ab8bb378c866ccf871de95d898d568be Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sun, 2 Aug 2015 12:44:46 -0500 Subject: [PATCH] Add ActorInfo.HasTraitInfo() requiring ITraitInfo types --- OpenRA.Game/GameRules/ActorInfo.cs | 2 + OpenRA.Game/Graphics/WorldRenderer.cs | 4 +- OpenRA.Game/Orders/UnitOrderGenerator.cs | 10 ++-- .../WorldInteractionControllerWidget.cs | 4 +- OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs | 6 +-- OpenRA.Mods.Common/AI/HackyAI.cs | 50 +++++++++---------- OpenRA.Mods.Common/AI/Squad.cs | 2 +- OpenRA.Mods.Common/AI/States/AirStates.cs | 4 +- OpenRA.Mods.Common/AI/States/GroundStates.cs | 2 +- OpenRA.Mods.Common/AI/States/StateBase.cs | 6 +-- .../Activities/Air/HeliAttack.cs | 2 +- OpenRA.Mods.Common/Activities/Attack.cs | 2 +- OpenRA.Mods.Common/Activities/Hunt.cs | 2 +- .../Activities/Move/MoveAdjacentTo.cs | 2 +- OpenRA.Mods.Common/Activities/Rearm.cs | 2 +- OpenRA.Mods.Common/ActorExts.cs | 6 +-- OpenRA.Mods.Common/Commands/DevCommands.cs | 2 +- .../EditorBrushes/EditorActorBrush.cs | 4 +- OpenRA.Mods.Common/Effects/Bullet.cs | 2 +- OpenRA.Mods.Common/Effects/Missile.cs | 2 +- OpenRA.Mods.Common/Lint/CheckPlayers.cs | 2 +- .../Orders/EnterAlliedActorTargeter.cs | 2 +- .../Orders/PlaceBuildingOrderGenerator.cs | 4 +- .../Orders/RepairOrderGenerator.cs | 2 +- .../Scripting/Properties/CombatProperties.cs | 2 +- .../Scripting/Properties/GuardProperties.cs | 2 +- .../Scripting/Properties/PlayerProperties.cs | 2 +- OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 6 +-- .../Traits/Attack/AttackBase.cs | 2 +- .../Traits/Attack/AttackFollow.cs | 4 +- OpenRA.Mods.Common/Traits/AutoTarget.cs | 2 +- OpenRA.Mods.Common/Traits/BodyOrientation.cs | 2 +- OpenRA.Mods.Common/Traits/Buildings/Bridge.cs | 2 +- .../Traits/Buildings/Building.cs | 6 +-- .../Traits/CustomBuildTimeValue.cs | 2 +- OpenRA.Mods.Common/Traits/EngineerRepair.cs | 4 +- OpenRA.Mods.Common/Traits/Guard.cs | 4 +- OpenRA.Mods.Common/Traits/KillsSelf.cs | 2 +- OpenRA.Mods.Common/Traits/Mobile.cs | 2 +- .../Traits/Player/AllyRepair.cs | 2 +- .../Traits/Player/BaseAttackNotifier.cs | 2 +- .../Traits/Player/HarvesterAttackNotifier.cs | 2 +- .../Traits/Player/PlayerStatistics.cs | 6 +-- .../Traits/Player/ProductionQueue.cs | 8 +-- OpenRA.Mods.Common/Traits/Player/TechTree.cs | 2 +- OpenRA.Mods.Common/Traits/Production.cs | 2 +- OpenRA.Mods.Common/Traits/Render/Hovers.cs | 2 +- .../Render/WithBuildingPlacedAnimation.cs | 2 +- .../Render/WithBuildingPlacedOverlay.cs | 2 +- .../Traits/Render/WithDockingOverlay.cs | 2 +- .../Traits/Render/WithIdleOverlay.cs | 2 +- .../Traits/Render/WithProductionOverlay.cs | 2 +- .../Traits/Render/WithRepairOverlay.cs | 2 +- .../Traits/Sound/AmbientSound.cs | 2 +- OpenRA.Mods.Common/Traits/SupplyTruck.cs | 4 +- .../SupportPowers/SupportPowerManager.cs | 4 +- OpenRA.Mods.Common/Traits/Targetable.cs | 2 +- OpenRA.Mods.Common/Traits/Transforms.cs | 4 +- .../Traits/World/DomainIndex.cs | 2 +- OpenRA.Mods.Common/TraitsInterfaces.cs | 4 +- .../Logic/Editor/ActorSelectorLogic.cs | 4 +- .../Logic/Ingame/ObserverStatsLogic.cs | 4 +- .../Logic/Ingame/ProductionTooltipLogic.cs | 2 +- .../Widgets/ProductionPaletteWidget.cs | 2 +- .../Widgets/ProductionTabsWidget.cs | 2 +- .../Widgets/ViewportControllerWidget.cs | 2 +- .../Widgets/WorldCommandWidget.cs | 6 +-- OpenRA.Mods.D2k/Activities/SwallowActor.cs | 2 +- OpenRA.Mods.D2k/Traits/Carryable.cs | 2 +- .../Traits/Render/WithDeliveryOverlay.cs | 2 +- OpenRA.Mods.D2k/Traits/Sandworm.cs | 4 +- OpenRA.Mods.RA/Activities/Infiltrate.cs | 2 +- .../Traits/Buildings/ClonesProducedUnits.cs | 2 +- OpenRA.Mods.RA/Traits/Chronoshiftable.cs | 2 +- OpenRA.Mods.RA/Traits/Mine.cs | 2 +- OpenRA.Mods.RA/Traits/Minelayer.cs | 2 +- .../Traits/SupportPowers/ChronoshiftPower.cs | 2 +- 77 files changed, 138 insertions(+), 136 deletions(-) diff --git a/OpenRA.Game/GameRules/ActorInfo.cs b/OpenRA.Game/GameRules/ActorInfo.cs index 4e55518edf..b09140e4e0 100644 --- a/OpenRA.Game/GameRules/ActorInfo.cs +++ b/OpenRA.Game/GameRules/ActorInfo.cs @@ -183,5 +183,7 @@ namespace OpenRA i => Pair.New( i.Name.Replace("Init", ""), i)); } + + public bool HasTraitInfo() where T : ITraitInfo { return Traits.Contains(); } } } diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 9fd39bf910..69d0c718b1 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -181,7 +181,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.Traits.Contains() + && a.Info.HasTraitInfo() && !World.FogObscures(a) && !World.Selection.Actors.Contains(a))) @@ -193,7 +193,7 @@ namespace OpenRA.Graphics public void DrawRollover(Actor unit) { - if (unit.Info.Traits.Contains()) + if (unit.Info.HasTraitInfo()) new SelectionBarsRenderable(unit).Render(this); } diff --git a/OpenRA.Game/Orders/UnitOrderGenerator.cs b/OpenRA.Game/Orders/UnitOrderGenerator.cs index ea583a437c..d5bf8ea790 100644 --- a/OpenRA.Game/Orders/UnitOrderGenerator.cs +++ b/OpenRA.Game/Orders/UnitOrderGenerator.cs @@ -20,7 +20,7 @@ namespace OpenRA.Orders public IEnumerable Order(World world, CPos xy, MouseInput mi) { var underCursor = world.ScreenMap.ActorsAt(mi) - .Where(a => !world.FogObscures(a) && a.Info.Traits.Contains()) + .Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo()) .WithHighestSelectionPriority(); Target target; @@ -29,7 +29,7 @@ namespace OpenRA.Orders else { var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi) - .Where(a => a.Info.Traits.Contains() && !a.Footprint.All(world.ShroudObscures)) + .Where(a => a.Info.HasTraitInfo() && !a.Footprint.All(world.ShroudObscures)) .WithHighestSelectionPriority(); target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy); } @@ -58,12 +58,12 @@ namespace OpenRA.Orders { var useSelect = false; var underCursor = world.ScreenMap.ActorsAt(mi) - .Where(a => !world.FogObscures(a) && a.Info.Traits.Contains()) + .Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo()) .WithHighestSelectionPriority(); if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any())) { - if (underCursor.Info.Traits.Contains()) + if (underCursor.Info.HasTraitInfo()) useSelect = true; } @@ -73,7 +73,7 @@ namespace OpenRA.Orders else { var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi) - .Where(a => a.Info.Traits.Contains() && !a.Footprint.All(world.ShroudObscures)) + .Where(a => a.Info.HasTraitInfo() && !a.Footprint.All(world.ShroudObscures)) .WithHighestSelectionPriority(); target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy); } diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index c9188b3fe5..ce2d777554 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -89,7 +89,7 @@ namespace OpenRA.Widgets { if (!hasBox && World.Selection.Actors.Any() && !multiClick) { - if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.Info.Traits.Contains() && + if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.Info.HasTraitInfo() && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) && !mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi))) { @@ -301,7 +301,7 @@ namespace OpenRA.Widgets a = b; return world.ScreenMap.ActorsInBox(a, b) - .Where(x => x.Info.Traits.Contains() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x))) + .Where(x => x.Info.HasTraitInfo() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x))) .SubsetWithHighestSelectionPriority(); } diff --git a/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs b/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs index 7fb05dd331..a102996dbb 100644 --- a/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs +++ b/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs @@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.AI var sumOfHp = 0; foreach (var a in actors) { - if (a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo()) { sumOfMaxHp += a.Trait().MaxHP; sumOfHp += a.Trait().HP; @@ -228,7 +228,7 @@ namespace OpenRA.Mods.Common.AI { var sum = 0; foreach (var a in actors) - if (a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo()) sum += getValue(a); return sum; @@ -240,7 +240,7 @@ namespace OpenRA.Mods.Common.AI var countActors = 0; foreach (var a in actors) { - if (a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo()) { sum += getValue(a); countActors++; diff --git a/OpenRA.Mods.Common/AI/HackyAI.cs b/OpenRA.Mods.Common/AI/HackyAI.cs index b0f6fd748e..fbbb79ef71 100644 --- a/OpenRA.Mods.Common/AI/HackyAI.cs +++ b/OpenRA.Mods.Common/AI/HackyAI.cs @@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.AI { var randomBaseBuilding = World.Actors.Where( a => a.Owner == Player - && a.Info.Traits.Contains() - && !a.Info.Traits.Contains()) + && a.Info.HasTraitInfo() + && !a.Info.HasTraitInfo()) .RandomOrDefault(Random); return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter; @@ -233,8 +233,8 @@ namespace OpenRA.Mods.Common.AI isEnemyUnit = unit => Player.Stances[unit.Owner] == Stance.Enemy - && !unit.Info.Traits.Contains() - && unit.Info.Traits.Contains(); + && !unit.Info.HasTraitInfo() + && unit.Info.HasTraitInfo(); foreach (var decision in info.PowerDecisions) powerDecisions.Add(decision.OrderName, decision); @@ -281,8 +281,8 @@ namespace OpenRA.Mods.Common.AI { var baseProviders = World.Actors.Where( a => a.Owner == Player - && a.Info.Traits.Contains() - && !a.Info.Traits.Contains()); + && a.Info.HasTraitInfo() + && !a.Info.HasTraitInfo()); foreach (var b in baseProviders) { @@ -308,8 +308,8 @@ namespace OpenRA.Mods.Common.AI { var areaProviders = World.Actors.Where( a => a.Owner == Player - && a.Info.Traits.Contains() - && !a.Info.Traits.Contains()); + && a.Info.HasTraitInfo() + && !a.Info.HasTraitInfo()); foreach (var a in areaProviders) { @@ -489,7 +489,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.Traits.Contains() && Player.Stances[a.Owner] == Stance.Enemy) + var closestEnemy = World.Actors.Where(a => !a.Disposed && a.Info.HasTraitInfo() && Player.Stances[a.Owner] == Stance.Enemy) .ClosestTo(World.Map.CenterOfCell(defenseCenter)); var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter; @@ -565,7 +565,7 @@ namespace OpenRA.Mods.Common.AI // Pick something worth attacking owned by that player var target = World.Actors - .Where(a => a.Owner == enemy && a.Info.Traits.Contains()) + .Where(a => a.Owner == enemy && a.Info.HasTraitInfo()) .ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter())); if (target == null) @@ -597,7 +597,7 @@ namespace OpenRA.Mods.Common.AI List FindEnemyConstructionYards() { return World.Actors.Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead - && a.Info.Traits.Contains() && !a.Info.Traits.Contains()).ToList(); + && a.Info.HasTraitInfo() && !a.Info.HasTraitInfo()).ToList(); } void CleanSquads() @@ -707,18 +707,18 @@ namespace OpenRA.Mods.Common.AI void FindNewUnits(Actor self) { var newUnits = self.World.ActorsWithTrait() - .Where(a => a.Actor.Owner == Player && !a.Actor.Info.Traits.Contains() + .Where(a => a.Actor.Owner == Player && !a.Actor.Info.HasTraitInfo() && !activeUnits.Contains(a.Actor)) .Select(a => a.Actor); foreach (var a in newUnits) { - if (a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo()) QueueOrder(new Order("Harvest", a, false)); else unitsHangingAroundTheBase.Add(a); - if (a.Info.Traits.Contains() && a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo() && a.Info.HasTraitInfo()) { var air = GetSquadOfType(SquadType.Air); if (air == null) @@ -742,7 +742,7 @@ namespace OpenRA.Mods.Common.AI var attackForce = RegisterNewSquad(SquadType.Assault); foreach (var a in unitsHangingAroundTheBase) - if (!a.Info.Traits.Contains()) + if (!a.Info.HasTraitInfo()) attackForce.Units.Add(a); unitsHangingAroundTheBase.Clear(); @@ -753,7 +753,7 @@ namespace OpenRA.Mods.Common.AI { var allEnemyBaseBuilder = FindEnemyConstructionYards(); var ownUnits = activeUnits - .Where(unit => unit.Info.Traits.Contains() && !unit.Info.Traits.Contains() && unit.IsIdle).ToList(); + .Where(unit => unit.Info.HasTraitInfo() && !unit.Info.HasTraitInfo() && unit.IsIdle).ToList(); if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize)) return; @@ -761,7 +761,7 @@ namespace OpenRA.Mods.Common.AI foreach (var b in allEnemyBaseBuilder) { var enemies = World.FindActorsInCircle(b.CenterPosition, WDist.FromCells(Info.RushAttackScanRadius)) - .Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.Traits.Contains()).ToList(); + .Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo()).ToList(); if (rushFuzzy.CanAttack(ownUnits, enemies)) { @@ -790,8 +790,8 @@ namespace OpenRA.Mods.Common.AI if (!protectSq.IsValid) { var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(GetRandomBaseCenter()), WDist.FromCells(Info.ProtectUnitScanRadius)) - .Where(unit => unit.Owner == Player && !unit.Info.Traits.Contains() - && unit.Info.Traits.Contains()); + .Where(unit => unit.Owner == Player && !unit.Info.HasTraitInfo() + && unit.Info.HasTraitInfo()); foreach (var a in ownUnits) protectSq.Units.Add(a); @@ -832,7 +832,7 @@ namespace OpenRA.Mods.Common.AI { // Find and deploy our mcv var mcv = self.World.Actors - .FirstOrDefault(a => a.Owner == Player && a.Info.Traits.Contains()); + .FirstOrDefault(a => a.Owner == Player && a.Info.HasTraitInfo()); if (mcv != null) { @@ -841,7 +841,7 @@ namespace OpenRA.Mods.Common.AI // Don't transform the mcv if it is a fact // HACK: This needs to query against MCVs directly - if (mcv.Info.Traits.Contains()) + if (mcv.Info.HasTraitInfo()) QueueOrder(new Order("DeployTransform", mcv, false)); } else @@ -854,7 +854,7 @@ namespace OpenRA.Mods.Common.AI { // HACK: This needs to query against MCVs directly var mcvs = self.World.Actors - .Where(a => a.Owner == Player && a.Info.Traits.Contains() && a.Info.Traits.Contains()); + .Where(a => a.Owner == Player && a.Info.HasTraitInfo() && a.Info.HasTraitInfo()); if (!mcvs.Any()) return; @@ -1014,7 +1014,7 @@ namespace OpenRA.Mods.Common.AI // No construction yards - Build a new MCV if (!HasAdequateFact() && !self.World.Actors.Any(a => - a.Owner == Player && a.Info.Traits.Contains() && a.Info.Traits.Contains())) + a.Owner == Player && a.Info.HasTraitInfo() && a.Info.HasTraitInfo())) BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name); foreach (var q in Info.UnitQueues) @@ -1073,14 +1073,14 @@ namespace OpenRA.Mods.Common.AI if (e.Attacker.Disposed) return; - if (!e.Attacker.Info.Traits.Contains()) + if (!e.Attacker.Info.HasTraitInfo()) return; if (e.Damage > 0) aggro[e.Attacker.Owner].Aggro += e.Damage; // Protected harvesters or building - if ((self.Info.Traits.Contains() || self.Info.Traits.Contains()) && + if ((self.Info.HasTraitInfo() || self.Info.HasTraitInfo()) && Player.Stances[e.Attacker.Owner] == Stance.Enemy) { defenseCenter = e.Attacker.Location; diff --git a/OpenRA.Mods.Common/AI/Squad.cs b/OpenRA.Mods.Common/AI/Squad.cs index c21b41a7e5..9c528fe982 100644 --- a/OpenRA.Mods.Common/AI/Squad.cs +++ b/OpenRA.Mods.Common/AI/Squad.cs @@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.AI public bool IsTargetValid { - get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.Traits.Contains(); } + get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.HasTraitInfo(); } } public bool IsTargetVisible diff --git a/OpenRA.Mods.Common/AI/States/AirStates.cs b/OpenRA.Mods.Common/AI/States/AirStates.cs index eed023eb9f..7044941aac 100644 --- a/OpenRA.Mods.Common/AI/States/AirStates.cs +++ b/OpenRA.Mods.Common/AI/States/AirStates.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.AI var missileUnitsCount = 0; foreach (var unit in units) { - if (unit != null && unit.Info.Traits.Contains() && !unit.Info.Traits.Contains() + if (unit != null && unit.Info.HasTraitInfo() && !unit.Info.HasTraitInfo() && !unit.IsDisabled()) { var arms = unit.TraitsImplementing(); @@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.AI continue; } - if (owner.TargetActor.Info.Traits.Contains() && CanAttackTarget(a, owner.TargetActor)) + if (owner.TargetActor.Info.HasTraitInfo() && CanAttackTarget(a, owner.TargetActor)) owner.Bot.QueueOrder(new Order("Attack", a, false) { TargetActor = owner.TargetActor }); } } diff --git a/OpenRA.Mods.Common/AI/States/GroundStates.cs b/OpenRA.Mods.Common/AI/States/GroundStates.cs index 87115e3ae6..a35af0c358 100644 --- a/OpenRA.Mods.Common/AI/States/GroundStates.cs +++ b/OpenRA.Mods.Common/AI/States/GroundStates.cs @@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.AI { var enemies = owner.World.FindActorsInCircle(leader.CenterPosition, WDist.FromCells(12)) .Where(a1 => !a1.Disposed && !a1.IsDead); - var enemynearby = enemies.Where(a1 => a1.Info.Traits.Contains() && leader.Owner.Stances[a1.Owner] == Stance.Enemy); + var enemynearby = enemies.Where(a1 => a1.Info.HasTraitInfo() && leader.Owner.Stances[a1.Owner] == Stance.Enemy); var target = enemynearby.ClosestTo(leader.CenterPosition); if (target != null) { diff --git a/OpenRA.Mods.Common/AI/States/StateBase.cs b/OpenRA.Mods.Common/AI/States/StateBase.cs index 81bc6ff132..d8c5143ec1 100644 --- a/OpenRA.Mods.Common/AI/States/StateBase.cs +++ b/OpenRA.Mods.Common/AI/States/StateBase.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.AI protected static bool CanAttackTarget(Actor a, Actor target) { - if (!a.Info.Traits.Contains()) + if (!a.Info.HasTraitInfo()) return false; var targetTypes = target.TraitsImplementing().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes); @@ -82,11 +82,11 @@ namespace OpenRA.Mods.Common.AI var u = squad.Units.Random(squad.Random); var units = squad.World.FindActorsInCircle(u.CenterPosition, WDist.FromCells(DangerRadius)).ToList(); - var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.Traits.Contains()); + var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.HasTraitInfo()); if (ownBaseBuildingAround.Any()) return false; - var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.Traits.Contains()); + var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo()); if (!enemyAroundUnit.Any()) return false; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index 7840172f48..0d501ec01a 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Activities { target = value; if (target.Type == TargetType.Actor) - canHideUnderFog = target.Actor.Info.Traits.Contains(); + canHideUnderFog = target.Actor.Info.HasTraitInfo(); } } diff --git a/OpenRA.Mods.Common/Activities/Attack.cs b/OpenRA.Mods.Common/Activities/Attack.cs index a940ff235d..9036d5fff7 100644 --- a/OpenRA.Mods.Common/Activities/Attack.cs +++ b/OpenRA.Mods.Common/Activities/Attack.cs @@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities // HACK: This would otherwise break targeting frozen actors // The problem is that Shroud.IsTargetable returns false (as it should) for // frozen actors, but we do want to explicitly target the underlying actor here. - if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.Traits.Contains() && !self.Owner.CanTargetActor(Target.Actor)) + if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo() && !self.Owner.CanTargetActor(Target.Actor)) return NextActivity; // Try to move within range diff --git a/OpenRA.Mods.Common/Activities/Hunt.cs b/OpenRA.Mods.Common/Activities/Hunt.cs index 7bb9225e7a..aabac0df67 100644 --- a/OpenRA.Mods.Common/Activities/Hunt.cs +++ b/OpenRA.Mods.Common/Activities/Hunt.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities { var attack = self.Trait(); targets = self.World.Actors.Where(a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self) - && a.Info.Traits.Contains() && IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a))); + && a.Info.HasTraitInfo() && IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a))); } bool IsTargetable(Actor self, Actor viewer) diff --git a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs index 255807ca26..d99150f2a1 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Activities { target = value; if (target.Type == TargetType.Actor) - canHideUnderFog = target.Actor.Info.Traits.Contains(); + canHideUnderFog = target.Actor.Info.HasTraitInfo(); } } diff --git a/OpenRA.Mods.Common/Activities/Rearm.cs b/OpenRA.Mods.Common/Activities/Rearm.cs index 5fa3824933..47daa05840 100644 --- a/OpenRA.Mods.Common/Activities/Rearm.cs +++ b/OpenRA.Mods.Common/Activities/Rearm.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Activities // HACK to check if we are on the helipad/airfield/etc. var hostBuilding = self.World.ActorMap.GetUnitsAt(self.Location) - .FirstOrDefault(a => a.Info.Traits.Contains()); + .FirstOrDefault(a => a.Info.HasTraitInfo()); if (hostBuilding == null || !hostBuilding.IsInWorld) return NextActivity; diff --git a/OpenRA.Mods.Common/ActorExts.cs b/OpenRA.Mods.Common/ActorExts.cs index 4c58c25e19..3d3633758c 100644 --- a/OpenRA.Mods.Common/ActorExts.cs +++ b/OpenRA.Mods.Common/ActorExts.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common if (self.IsDead) return false; - if (!self.Info.Traits.Contains()) + if (!self.Info.HasTraitInfo()) return false; if (!self.IsInWorld) @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common if (stance == Stance.Ally) return true; - if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.Traits.Contains()) + if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo()) return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Ally; return stance == Stance.Ally; @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common if (stance == Stance.Ally) return false; /* otherwise, we'll hate friendly disguised spies */ - if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.Traits.Contains()) + if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo()) return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Enemy; return stance == Stance.Enemy; diff --git a/OpenRA.Mods.Common/Commands/DevCommands.cs b/OpenRA.Mods.Common/Commands/DevCommands.cs index ec71d825ee..dff76295e9 100644 --- a/OpenRA.Mods.Common/Commands/DevCommands.cs +++ b/OpenRA.Mods.Common/Commands/DevCommands.cs @@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Commands var leveluporder = new Order("DevLevelUp", actor, false); leveluporder.ExtraData = (uint)level; - if (actor.Info.Traits.Contains()) + if (actor.Info.HasTraitInfo()) world.IssueOrder(leveluporder); } diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorActorBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorActorBrush.cs index af121d73e9..0ff3237969 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorActorBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorActorBrush.cs @@ -116,10 +116,10 @@ namespace OpenRA.Mods.Common.Widgets var initDict = newActorReference.InitDict; - if (Actor.Traits.Contains()) + if (Actor.HasTraitInfo()) initDict.Add(new FacingInit(facing)); - if (Actor.Traits.Contains()) + if (Actor.HasTraitInfo()) initDict.Add(new TurretFacingInit(facing)); editorLayer.Add(newActorReference); diff --git a/OpenRA.Mods.Common/Effects/Bullet.cs b/OpenRA.Mods.Common/Effects/Bullet.cs index 7df4ce6e68..ac65568ad7 100644 --- a/OpenRA.Mods.Common/Effects/Bullet.cs +++ b/OpenRA.Mods.Common/Effects/Bullet.cs @@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Effects contrail.Update(pos); if (ticks++ >= length || (info.Blockable && world.ActorMap - .GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.Info.Traits.Contains()))) + .GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.Info.HasTraitInfo()))) Explode(world); } diff --git a/OpenRA.Mods.Common/Effects/Missile.cs b/OpenRA.Mods.Common/Effects/Missile.cs index 7e8a3c7f8b..b4bdfd068e 100644 --- a/OpenRA.Mods.Common/Effects/Missile.cs +++ b/OpenRA.Mods.Common/Effects/Missile.cs @@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Effects var shouldExplode = (pos.Z < 0) // Hit the ground || (dist.LengthSquared < info.CloseEnough.LengthSquared) // Within range || (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel - || (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.Info.Traits.Contains())) // Hit a wall or other blocking obstacle + || (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.Info.HasTraitInfo())) // Hit a wall or other blocking obstacle || !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below. || (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain diff --git a/OpenRA.Mods.Common/Lint/CheckPlayers.cs b/OpenRA.Mods.Common/Lint/CheckPlayers.cs index 3968812ddf..9d52c86d79 100644 --- a/OpenRA.Mods.Common/Lint/CheckPlayers.cs +++ b/OpenRA.Mods.Common/Lint/CheckPlayers.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Lint if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction)) emitError("Invalid faction {0} chosen for player {1}.".F(player.Faction, player.Name)); - if (worldActor.Traits.Contains()) + if (worldActor.HasTraitInfo()) { var multiPlayers = players.Count(p => p.Value.Playable); var spawns = map.ActorDefinitions.Where(a => a.Value.Value == "mpspawn"); diff --git a/OpenRA.Mods.Common/Orders/EnterAlliedActorTargeter.cs b/OpenRA.Mods.Common/Orders/EnterAlliedActorTargeter.cs index 390e767b87..e2cb3fb561 100644 --- a/OpenRA.Mods.Common/Orders/EnterAlliedActorTargeter.cs +++ b/OpenRA.Mods.Common/Orders/EnterAlliedActorTargeter.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Orders public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!target.Info.Traits.Contains() || !canTarget(target)) + if (!target.Info.HasTraitInfo() || !canTarget(target)) return false; cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; diff --git a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs index 969468ad30..8609b0c7f7 100644 --- a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs @@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Orders yield break; } - if (world.Map.Rules.Actors[building].Traits.Contains()) + if (world.Map.Rules.Actors[building].HasTraitInfo()) orderType = "LineBuild"; } @@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Orders cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo)); } - else if (rules.Actors[building].Traits.Contains()) + else if (rules.Actors[building].HasTraitInfo()) { // Linebuild for walls. if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) diff --git a/OpenRA.Mods.Common/Orders/RepairOrderGenerator.cs b/OpenRA.Mods.Common/Orders/RepairOrderGenerator.cs index 32fbee25e7..7422ca2fad 100644 --- a/OpenRA.Mods.Common/Orders/RepairOrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/RepairOrderGenerator.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Orders yield break; // Repair a building. - if (underCursor.Info.Traits.Contains()) + if (underCursor.Info.HasTraitInfo()) yield return new Order("RepairBuilding", world.LocalPlayer.PlayerActor, false) { TargetActor = underCursor }; // Test for generic Repairable (used on units). diff --git a/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs index 863ddfdc15..f7f93a977d 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/CombatProperties.cs @@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Scripting if (!target.IsValidFor(Self) || target.Type == TargetType.FrozenActor) Log.Write("lua", "{1} is an invalid target for {0}!", Self, targetActor); - if (!targetActor.Info.Traits.Contains() && !Self.Owner.CanTargetActor(targetActor)) + if (!targetActor.Info.HasTraitInfo() && !Self.Owner.CanTargetActor(targetActor)) Log.Write("lua", "{1} is not revealed for player {0}!", Self.Owner, targetActor); attackBase.AttackTarget(target, true, allowMove); diff --git a/OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs index 5e1b59b8f7..98b493c39a 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/GuardProperties.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Scripting [Desc("Guard the target actor.")] public void Guard(Actor targetActor) { - if (targetActor.Info.Traits.Contains()) + if (targetActor.Info.HasTraitInfo()) guard.GuardTarget(Self, Target.FromActor(targetActor)); } } diff --git a/OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs index 2ac2b0a54f..987276f682 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/PlayerProperties.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Scripting public Actor[] GetGroundAttackers() { return Player.World.ActorsWithTrait().Select(a => a.Actor) - .Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.Traits.Contains()) + .Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo()) .ToArray(); } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index ca9907ef63..477cc294b9 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits firstTick = false; // TODO: Aircraft husks don't properly unreserve. - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) return; ReserveSpawnBuilding(); @@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Traits return WVec.Zero; return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation) - .Where(a => !a.IsDead && a.Info.Traits.Contains() && a.Info.Traits.Get().CruiseAltitude == info.CruiseAltitude) + .Where(a => !a.IsDead && a.Info.HasTraitInfo() && a.Info.Traits.Get().CruiseAltitude == info.CruiseAltitude) .Select(GetRepulsionForce) .Aggregate(WVec.Zero, (a, b) => a + b); } @@ -191,7 +191,7 @@ namespace OpenRA.Mods.Common.Traits return null; // not on the ground. return self.World.ActorMap.GetUnitsAt(self.Location) - .FirstOrDefault(a => a.Info.Traits.Contains()); + .FirstOrDefault(a => a.Info.HasTraitInfo()); } protected void ReserveSpawnBuilding() diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 78cf948d86..ac9e214668 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -202,7 +202,7 @@ namespace OpenRA.Mods.Common.Traits public bool IsReachableTarget(Target target, bool allowMove) { return HasAnyValidWeapons(target) - && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.Traits.Contains())); + && (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.HasTraitInfo())); } class AttackOrderTargeter : IOrderTargeter diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs index 38c44274b1..d992065111 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackFollow.cs @@ -81,8 +81,8 @@ namespace OpenRA.Mods.Common.Traits var weapon = attack.ChooseArmamentForTarget(target); if (weapon != null) { - var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.Info.Traits.Contains()) - || (target.Type == TargetType.FrozenActor && target.FrozenActor.Info.Traits.Contains()); + var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo()) + || (target.Type == TargetType.FrozenActor && target.FrozenActor.Info.HasTraitInfo()); // Try and sit at least one cell closer than the max range to give some leeway if the target starts moving. var maxRange = targetIsMobile ? new WDist(Math.Max(weapon.Weapon.MinRange.Length, weapon.Weapon.Range.Length - 1024)) diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index be1d678022..e63f549414 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -154,7 +154,7 @@ namespace OpenRA.Mods.Common.Traits return inRange .Where(a => a.AppearsHostileTo(self) && - !a.Info.Traits.Contains() && + !a.Info.HasTraitInfo() && attack.HasAnyValidWeapons(Target.FromActor(a)) && self.Owner.CanTargetActor(a)) .ClosestTo(self); diff --git a/OpenRA.Mods.Common/Traits/BodyOrientation.cs b/OpenRA.Mods.Common/Traits/BodyOrientation.cs index f25452a31d..5a9becc660 100644 --- a/OpenRA.Mods.Common/Traits/BodyOrientation.cs +++ b/OpenRA.Mods.Common/Traits/BodyOrientation.cs @@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits // If a sprite actor has neither custom QuantizedFacings nor a trait implementing IQuantizeBodyOrientationInfo, throw if (qboi == null) { - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) throw new InvalidOperationException("Actor '" + self.Info.Name + "' has a sprite body but no facing quantization." + " Either add the QuantizeFacingsFromSequence trait or set custom QuantizedFacings on BodyOrientation."); else diff --git a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs index b4bb963654..d3318755c9 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs @@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits { foreach (var c in footprint.Keys) foreach (var a in self.World.ActorMap.GetUnitsAt(c)) - if (a.Info.Traits.Contains() && !a.Trait().CanEnterCell(c)) + if (a.Info.HasTraitInfo() && !a.Trait().CanEnterCell(c)) a.Kill(self); } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index d7ac7860b2..c32883543b 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Building.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Building.cs @@ -87,12 +87,12 @@ namespace OpenRA.Mods.Common.Traits { var unitsAtPos = world.ActorMap.GetUnitsAt(pos).Where(a => a.IsInWorld && (a.Owner == p || (allyBuildRadius && a.Owner.Stances[p] == Stance.Ally)) - && a.Info.Traits.Contains()); + && a.Info.HasTraitInfo()); if (unitsAtPos.Any()) nearnessCandidates.Add(pos); } - else if (buildingAtPos.IsInWorld && buildingAtPos.Info.Traits.Contains() + else if (buildingAtPos.IsInWorld && buildingAtPos.Info.HasTraitInfo() && (buildingAtPos.Owner == p || (allyBuildRadius && buildingAtPos.Owner.Stances[p] == Stance.Ally))) nearnessCandidates.Add(pos); } @@ -164,7 +164,7 @@ namespace OpenRA.Mods.Common.Traits public void Created(Actor self) { - if (SkipMakeAnimation || !self.Info.Traits.Contains()) + if (SkipMakeAnimation || !self.Info.HasTraitInfo()) NotifyBuildingComplete(self); } diff --git a/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs b/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs index bdd7ea4c3d..9c01a4bd5f 100644 --- a/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs +++ b/OpenRA.Mods.Common/Traits/CustomBuildTimeValue.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits if (csv != null) return csv.Value; - var cost = a.Traits.Contains() ? a.Traits.Get().Cost : 0; + var cost = a.HasTraitInfo() ? a.Traits.Get().Cost : 0; var time = cost * (25 * 60) /* frames per min */ / 1000; diff --git a/OpenRA.Mods.Common/Traits/EngineerRepair.cs b/OpenRA.Mods.Common/Traits/EngineerRepair.cs index cee2c2a530..4da01c7c1a 100644 --- a/OpenRA.Mods.Common/Traits/EngineerRepair.cs +++ b/OpenRA.Mods.Common/Traits/EngineerRepair.cs @@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - if (!target.Info.Traits.Contains()) + if (!target.Info.HasTraitInfo()) return false; if (self.Owner.Stances[target.Owner] != Stance.Ally) @@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Traits public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) { - if (!target.Info.Traits.Contains()) + if (!target.Info.HasTraitInfo()) return false; if (self.Owner.Stances[target.Owner] != Stance.Ally) diff --git a/OpenRA.Mods.Common/Traits/Guard.cs b/OpenRA.Mods.Common/Traits/Guard.cs index bbbbd081a6..99cb0454b7 100644 --- a/OpenRA.Mods.Common/Traits/Guard.cs +++ b/OpenRA.Mods.Common/Traits/Guard.cs @@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits public void Tick(World world) { - if (subjects.All(s => s.IsDead || !s.Info.Traits.Contains())) + if (subjects.All(s => s.IsDead || !s.Info.HasTraitInfo())) world.CancelInputMode(); } @@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits return world.ScreenMap.ActorsAt(mi) .Where(a => !world.FogObscures(a) && !a.IsDead && a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) && - a.Info.Traits.Contains()); + a.Info.HasTraitInfo()); } } } diff --git a/OpenRA.Mods.Common/Traits/KillsSelf.cs b/OpenRA.Mods.Common/Traits/KillsSelf.cs index 9265ac1162..e045223fe8 100644 --- a/OpenRA.Mods.Common/Traits/KillsSelf.cs +++ b/OpenRA.Mods.Common/Traits/KillsSelf.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits if (self.IsDead) return; - if (Info.RemoveInstead || !self.Info.Traits.Contains()) + if (Info.RemoveInstead || !self.Info.HasTraitInfo()) self.Dispose(); else self.Kill(self); diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 8b432701df..d0cc2dfe45 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -665,7 +665,7 @@ namespace OpenRA.Mods.Common.Traits { var cellInfo = notStupidCells .SelectMany(c => self.World.ActorMap.GetUnitsAt(c) - .Where(a => a.IsIdle && a.Info.Traits.Contains()), + .Where(a => a.IsIdle && a.Info.HasTraitInfo()), (c, a) => new { Cell = c, Actor = a }) .RandomOrDefault(self.World.SharedRandom); diff --git a/OpenRA.Mods.Common/Traits/Player/AllyRepair.cs b/OpenRA.Mods.Common/Traits/Player/AllyRepair.cs index 30a2df05d2..76b089832d 100644 --- a/OpenRA.Mods.Common/Traits/Player/AllyRepair.cs +++ b/OpenRA.Mods.Common/Traits/Player/AllyRepair.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits { var building = order.TargetActor; - if (building.Info.Traits.Contains()) + if (building.Info.HasTraitInfo()) if (building.AppearsFriendlyTo(self)) building.Trait().RepairBuilding(building, self.Owner); } diff --git a/OpenRA.Mods.Common/Traits/Player/BaseAttackNotifier.cs b/OpenRA.Mods.Common/Traits/Player/BaseAttackNotifier.cs index 0494ef1aa8..19c504a831 100644 --- a/OpenRA.Mods.Common/Traits/Player/BaseAttackNotifier.cs +++ b/OpenRA.Mods.Common/Traits/Player/BaseAttackNotifier.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits public void Damaged(Actor self, AttackInfo e) { // only track last hit against our base - if (!self.Info.Traits.Contains()) + if (!self.Info.HasTraitInfo()) return; if (e.Attacker == null) diff --git a/OpenRA.Mods.Common/Traits/Player/HarvesterAttackNotifier.cs b/OpenRA.Mods.Common/Traits/Player/HarvesterAttackNotifier.cs index caa20dcb1a..5c17719c51 100644 --- a/OpenRA.Mods.Common/Traits/Player/HarvesterAttackNotifier.cs +++ b/OpenRA.Mods.Common/Traits/Player/HarvesterAttackNotifier.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits public void Damaged(Actor self, AttackInfo e) { // only track last hit against our harvesters - if (!self.Info.Traits.Contains()) + if (!self.Info.HasTraitInfo()) return; // don't track self-damage diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs index 4f96c32465..bdc75261d3 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs @@ -107,18 +107,18 @@ namespace OpenRA.Mods.Common.Traits var attackerStats = e.Attacker.Owner.PlayerActor.Trait(); var defenderStats = self.Owner.PlayerActor.Trait(); - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) { attackerStats.BuildingsKilled++; defenderStats.BuildingsDead++; } - else if (self.Info.Traits.Contains()) + else if (self.Info.HasTraitInfo()) { attackerStats.UnitsKilled++; defenderStats.UnitsDead++; } - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) { var cost = self.Info.Traits.Get().Cost; attackerStats.KillsCost += cost; diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index c903286bc4..e4ed86e53c 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs @@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Traits return self.World.Map.Rules.Actors.Values .Where(x => x.Name[0] != '^' && - x.Traits.Contains() && + x.HasTraitInfo() && x.Traits.Get().Queue.Contains(category)); } @@ -254,7 +254,7 @@ namespace OpenRA.Mods.Common.Traits if (!bi.Queue.Contains(Info.Type)) return; /* Not built by this queue */ - var cost = unit.Traits.Contains() ? unit.Traits.Get().Cost : 0; + var cost = unit.HasTraitInfo() ? unit.Traits.Get().Cost : 0; var time = GetBuildTime(order.TargetString); if (BuildableItems().All(b => b.Name != order.TargetString)) @@ -278,7 +278,7 @@ namespace OpenRA.Mods.Common.Traits var hasPlayedSound = false; BeginProduction(new ProductionItem(this, order.TargetString, cost, playerPower, () => self.World.AddFrameEndTask(_ => { - var isBuilding = unit.Traits.Contains(); + var isBuilding = unit.HasTraitInfo(); if (isBuilding && !hasPlayedSound) hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName); @@ -314,7 +314,7 @@ namespace OpenRA.Mods.Common.Traits public virtual int GetBuildTime(string unitString) { var unit = self.World.Map.Rules.Actors[unitString]; - if (unit == null || !unit.Traits.Contains()) + if (unit == null || !unit.HasTraitInfo()) return 0; if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().FastBuild) diff --git a/OpenRA.Mods.Common/Traits/Player/TechTree.cs b/OpenRA.Mods.Common/Traits/Player/TechTree.cs index cc26cbd1e7..5aabaf5021 100644 --- a/OpenRA.Mods.Common/Traits/Player/TechTree.cs +++ b/OpenRA.Mods.Common/Traits/Player/TechTree.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits public void ActorChanged(Actor a) { var bi = a.Info.Traits.GetOrDefault(); - if (a.Owner == player && (a.Info.Traits.Contains() || (bi != null && bi.BuildLimit > 0))) + if (a.Owner == player && (a.Info.HasTraitInfo() || (bi != null && bi.BuildLimit > 0))) Update(); } diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index 99b340b268..1be4fd1c8f 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits public Production(ActorInitializer init, ProductionInfo info) { Info = info; - occupiesSpace = init.Self.Info.Traits.Contains(); + occupiesSpace = init.Self.Info.HasTraitInfo(); rp = Exts.Lazy(() => init.Self.IsDead ? null : init.Self.TraitOrDefault()); Faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; } diff --git a/OpenRA.Mods.Common/Traits/Render/Hovers.cs b/OpenRA.Mods.Common/Traits/Render/Hovers.cs index 49e7e970b0..1b97a4509f 100644 --- a/OpenRA.Mods.Common/Traits/Render/Hovers.cs +++ b/OpenRA.Mods.Common/Traits/Render/Hovers.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits public Hovers(HoversInfo info, Actor self) { this.info = info; - aircraft = self.Info.Traits.Contains(); + aircraft = self.Info.HasTraitInfo(); } public IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) diff --git a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedAnimation.cs index b074d5194e..36a7fe6779 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedAnimation.cs @@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits { this.info = info; wsb = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); + buildComplete = !self.Info.HasTraitInfo(); } public void BuildingComplete(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs index 4a5085cf7c..fe322347d9 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithBuildingPlacedOverlay.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits var rs = self.Trait(); var body = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); // always render instantly for units + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); diff --git a/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs index a650248977..a6ba429239 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDockingOverlay.cs @@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits var rs = self.Trait(); var body = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); // always render instantly for units + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units var overlay = new Animation(self.World, rs.GetImage(self)); overlay.Play(info.Sequence); diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index d0fa673e3e..7551e5da45 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Traits var rs = self.Trait(); var body = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); // always render instantly for units + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); if (info.StartSequence != null) overlay.PlayThen(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.StartSequence), diff --git a/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs index 26000f049f..53a6b94b51 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithProductionOverlay.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits var rs = self.Trait(); var body = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); // always render instantly for units + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units production = self.Info.Traits.Get(); overlay = new Animation(self.World, rs.GetImage(self)); diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs index 9a5355bdf9..0276d63150 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits var rs = self.Trait(); var body = self.Trait(); - buildComplete = !self.Info.Traits.Contains(); // always render instantly for units + buildComplete = !self.Info.HasTraitInfo(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); overlay.Play(info.Sequence); diff --git a/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs b/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs index 80f1a7e52f..2fd7b4cdaf 100644 --- a/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs +++ b/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits { public AmbientSound(Actor self, AmbientSoundInfo info) { - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) Sound.PlayLooped(info.SoundFile, self.CenterPosition); else Sound.PlayLooped(info.SoundFile); diff --git a/OpenRA.Mods.Common/Traits/SupplyTruck.cs b/OpenRA.Mods.Common/Traits/SupplyTruck.cs index ae3ca5f03b..4e50156630 100644 --- a/OpenRA.Mods.Common/Traits/SupplyTruck.cs +++ b/OpenRA.Mods.Common/Traits/SupplyTruck.cs @@ -82,12 +82,12 @@ namespace OpenRA.Mods.Common.Traits public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - return target.Info.Traits.Contains(); + return target.Info.HasTraitInfo(); } public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) { - return target.Info.Traits.Contains(); + return target.Info.HasTraitInfo(); } } } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs index 1a93ecb8ff..908ae81489 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs @@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits void ActorRemoved(Actor a) { - if (a.Owner != Self.Owner || !a.Info.Traits.Contains()) + if (a.Owner != Self.Owner || !a.Info.HasTraitInfo()) return; foreach (var t in a.TraitsImplementing()) @@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable GetPowersForActor(Actor a) { - if (a.Owner != Self.Owner || !a.Info.Traits.Contains()) + if (a.Owner != Self.Owner || !a.Info.HasTraitInfo()) return NoInstances; return a.TraitsImplementing() diff --git a/OpenRA.Mods.Common/Traits/Targetable.cs b/OpenRA.Mods.Common/Traits/Targetable.cs index ff7397bcfc..ca2d0c55e3 100644 --- a/OpenRA.Mods.Common/Traits/Targetable.cs +++ b/OpenRA.Mods.Common/Traits/Targetable.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits { if (IsTraitDisabled) return false; - if (cloak == null || (!viewer.IsDead && viewer.Info.Traits.Contains())) + if (cloak == null || (!viewer.IsDead && viewer.Info.HasTraitInfo())) return true; return cloak.IsVisible(self, viewer.Owner); diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index 739cb293f7..2eefdbf77b 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -109,10 +109,10 @@ namespace OpenRA.Mods.Common.Traits if (!queued) self.CancelActivity(); - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) self.QueueActivity(new Turn(self, info.Facing)); - if (self.Info.Traits.Contains()) + if (self.Info.HasTraitInfo()) self.QueueActivity(new HeliLand(self, true)); foreach (var nt in self.TraitsImplementing()) diff --git a/OpenRA.Mods.Common/Traits/World/DomainIndex.cs b/OpenRA.Mods.Common/Traits/World/DomainIndex.cs index a998bcccfc..b348e427d0 100644 --- a/OpenRA.Mods.Common/Traits/World/DomainIndex.cs +++ b/OpenRA.Mods.Common/Traits/World/DomainIndex.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits { domainIndexes = new Dictionary(); var movementClasses = - world.Map.Rules.Actors.Where(ai => ai.Value.Traits.Contains()) + world.Map.Rules.Actors.Where(ai => ai.Value.HasTraitInfo()) .Select(ai => (uint)ai.Value.Traits.Get().GetMovementClass(world.TileSet)).Distinct(); foreach (var mc in movementClasses) diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index a508234b20..eba8970756 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -45,8 +45,8 @@ namespace OpenRA.Mods.Common.Traits public interface INotifyCharging { void Charging(Actor self, Target target); } public interface INotifyChat { bool OnChat(string from, string message); } public interface INotifyParachuteLanded { void OnLanded(); } - public interface IRenderActorPreviewInfo { IEnumerable RenderPreview(ActorPreviewInitializer init); } - public interface ICruiseAltitudeInfo { WDist GetCruiseAltitude(); } + public interface IRenderActorPreviewInfo : ITraitInfo { IEnumerable RenderPreview(ActorPreviewInitializer init); } + public interface ICruiseAltitudeInfo : ITraitInfo { WDist GetCruiseAltitude(); } public interface IUpgradable { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs index 8b2330c5ef..59b9455d6b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs @@ -92,10 +92,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic foreach (var a in actors) { var actor = a; - if (actor.Traits.Contains()) // bridge layer takes care about that automatically + if (actor.HasTraitInfo()) // bridge layer takes care about that automatically continue; - if (!actor.Traits.Contains()) + if (!actor.HasTraitInfo()) continue; var filter = actor.Traits.GetOrDefault(); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs index 1640d5df00..22738ad709 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverStatsLogic.cs @@ -245,7 +245,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic .Sum(a => a.Info.Traits.WithInterface().First().Cost); var harvesters = template.Get("HARVESTERS"); - harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.Info.Traits.Contains()).ToString(); + harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.Info.HasTraitInfo()).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.Traits.Contains() && a.Owner == player); + var playerBase = world.Actors.FirstOrDefault(a => !a.IsDead && a.Info.HasTraitInfo() && a.Owner == player); if (playerBase != null) worldRenderer.Viewport.Center(playerBase.CenterPosition); }); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index 13f05dceaa..1b0b575c2d 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -113,7 +113,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic static string ActorName(Ruleset rules, string a) { ActorInfo ai; - if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.Traits.Contains()) + if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.HasTraitInfo()) return ai.Traits.Get().Name; return a; diff --git a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs index 5fad243947..07441be01f 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionPaletteWidget.cs @@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets { var actor = World.Map.Rules.Actors[icon.Name]; - if (item != null && item.Done && actor.Traits.Contains()) + if (item != null && item.Done && actor.HasTraitInfo()) { World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name); return true; diff --git a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs index 135540d336..1ab187b29e 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs @@ -198,7 +198,7 @@ namespace OpenRA.Mods.Common.Widgets // Is added to world.ActorAdded by the SidebarLogic handler public void ActorChanged(Actor a) { - if (a.Info.Traits.Contains()) + if (a.Info.HasTraitInfo()) { var allQueues = a.World.ActorsWithTrait() .Where(p => p.Actor.Owner == p.Actor.World.LocalPlayer && p.Actor.IsInWorld && p.Trait.Enabled) diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index e3d5f31122..407d4c411b 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Widgets } var underCursor = world.ScreenMap.ActorsAt(worldRenderer.Viewport.ViewToWorldPx(Viewport.LastMousePos)) - .Where(a => !world.FogObscures(a) && a.Info.Traits.Contains()) + .Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo()) .WithHighestSelectionPriority(); if (underCursor != null) diff --git a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs index a3b48bfdb4..a91c994f8f 100644 --- a/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs +++ b/OpenRA.Mods.Common/Widgets/WorldCommandWidget.cs @@ -177,7 +177,7 @@ namespace OpenRA.Mods.Common.Widgets bool PerformGuard() { var actors = world.Selection.Actors - .Where(a => !a.Disposed && a.Owner == world.LocalPlayer && a.Info.Traits.Contains()); + .Where(a => !a.Disposed && a.Owner == world.LocalPlayer && a.Info.HasTraitInfo()); if (actors.Any()) world.OrderGenerator = new GuardOrderGenerator(actors); @@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets { var building = world.ActorsWithTrait() .Select(b => b.Actor) - .FirstOrDefault(a => a.Owner == world.LocalPlayer && a.Info.Traits.Contains()); + .FirstOrDefault(a => a.Owner == world.LocalPlayer && a.Info.HasTraitInfo()); // No buildings left if (building == null) @@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.Widgets bool CycleProductionBuildings() { var facilities = world.ActorsWithTrait() - .Where(a => a.Actor.Owner == world.LocalPlayer && !a.Actor.Info.Traits.Contains()) + .Where(a => a.Actor.Owner == world.LocalPlayer && !a.Actor.Info.HasTraitInfo()) .OrderBy(f => f.Actor.Info.Traits.Get().Produces.First()) .Select(b => b.Actor) .ToList(); diff --git a/OpenRA.Mods.D2k/Activities/SwallowActor.cs b/OpenRA.Mods.D2k/Activities/SwallowActor.cs index 389a6536bd..a6720d9745 100644 --- a/OpenRA.Mods.D2k/Activities/SwallowActor.cs +++ b/OpenRA.Mods.D2k/Activities/SwallowActor.cs @@ -79,7 +79,7 @@ namespace OpenRA.Mods.D2k.Activities actor1.Dispose(); // Harvester insurance - if (!actor1.Info.Traits.Contains()) + if (!actor1.Info.HasTraitInfo()) return; var insurance = actor1.Owner.PlayerActor.TraitOrDefault(); diff --git a/OpenRA.Mods.D2k/Traits/Carryable.cs b/OpenRA.Mods.D2k/Traits/Carryable.cs index cad10371eb..e484a3e928 100644 --- a/OpenRA.Mods.D2k/Traits/Carryable.cs +++ b/OpenRA.Mods.D2k/Traits/Carryable.cs @@ -117,7 +117,7 @@ namespace OpenRA.Mods.D2k.Traits { // HACK: Harvesters need special treatment to avoid getting stuck on resource fields, // so if a Harvester's afterLandActivity is not DeliverResources, queue a new FindResources activity - var findResources = self.Info.Traits.Contains() && !(afterLandActivity is DeliverResources); + var findResources = self.Info.HasTraitInfo() && !(afterLandActivity is DeliverResources); if (findResources) self.QueueActivity(new FindResources(self)); else diff --git a/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs b/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs index cd86d62c42..d11e2e1bad 100644 --- a/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs +++ b/OpenRA.Mods.D2k/Traits/Render/WithDeliveryOverlay.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.D2k.Traits var body = self.Trait(); // always render instantly for units - buildComplete = !self.Info.Traits.Contains(); + buildComplete = !self.Info.HasTraitInfo(); var overlay = new Animation(self.World, rs.GetImage(self)); overlay.Play(info.Sequence); diff --git a/OpenRA.Mods.D2k/Traits/Sandworm.cs b/OpenRA.Mods.D2k/Traits/Sandworm.cs index ce8c0d2e5c..56ba0fff57 100644 --- a/OpenRA.Mods.D2k/Traits/Sandworm.cs +++ b/OpenRA.Mods.D2k/Traits/Sandworm.cs @@ -99,7 +99,7 @@ namespace OpenRA.Mods.D2k.Traits targetCountdown = Info.TargetRescanInterval; // If close enough, we don't care about other actors. - var target = self.World.FindActorsInCircle(self.CenterPosition, Info.IgnoreNoiseAttackRange).FirstOrDefault(x => x.Info.Traits.Contains()); + var target = self.World.FindActorsInCircle(self.CenterPosition, Info.IgnoreNoiseAttackRange).FirstOrDefault(x => x.Info.HasTraitInfo()); if (target != null) { self.CancelActivity(); @@ -109,7 +109,7 @@ namespace OpenRA.Mods.D2k.Traits Func isValidTarget = a => { - if (!a.Info.Traits.Contains()) + if (!a.Info.HasTraitInfo()) return false; return mobile.CanEnterCell(a.Location, null, false); diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index 1f7c23fad8..8edc101ee4 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Activities self.Dispose(); - if (target.Info.Traits.Contains()) + if (target.Info.HasTraitInfo()) Sound.PlayToPlayer(self.Owner, "bldginf1.aud"); } } diff --git a/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs b/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs index f8abd6b7cf..69a27be08b 100644 --- a/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs +++ b/OpenRA.Mods.RA/Traits/Buildings/ClonesProducedUnits.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.RA.Traits public void UnitProducedByOther(Actor self, Actor producer, Actor produced) { // No recursive cloning! - if (producer.Owner != self.Owner || producer.Info.Traits.Contains()) + if (producer.Owner != self.Owner || producer.Info.HasTraitInfo()) return; var ci = produced.Info.Traits.GetOrDefault(); diff --git a/OpenRA.Mods.RA/Traits/Chronoshiftable.cs b/OpenRA.Mods.RA/Traits/Chronoshiftable.cs index f5c4a5774b..43d9318084 100644 --- a/OpenRA.Mods.RA/Traits/Chronoshiftable.cs +++ b/OpenRA.Mods.RA/Traits/Chronoshiftable.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA.Traits public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation) { // TODO: Allow enemy units to be chronoshifted into bad terrain to kill them - return self.Info.Traits.Contains() && self.Trait().CanEnterCell(targetLocation); + return self.Info.HasTraitInfo() && self.Trait().CanEnterCell(targetLocation); } public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere) diff --git a/OpenRA.Mods.RA/Traits/Mine.cs b/OpenRA.Mods.RA/Traits/Mine.cs index 068fdcc293..849e5236eb 100644 --- a/OpenRA.Mods.RA/Traits/Mine.cs +++ b/OpenRA.Mods.RA/Traits/Mine.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Traits public void OnCrush(Actor crusher) { - if (crusher.Info.Traits.Contains() || (self.Owner.Stances[crusher.Owner] == Stance.Ally && info.AvoidFriendly)) + if (crusher.Info.HasTraitInfo() || (self.Owner.Stances[crusher.Owner] == Stance.Ally && info.AvoidFriendly)) return; var mobile = crusher.TraitOrDefault(); diff --git a/OpenRA.Mods.RA/Traits/Minelayer.cs b/OpenRA.Mods.RA/Traits/Minelayer.cs index 02be6e3bef..d29d2f8cda 100644 --- a/OpenRA.Mods.RA/Traits/Minelayer.cs +++ b/OpenRA.Mods.RA/Traits/Minelayer.cs @@ -154,7 +154,7 @@ namespace OpenRA.Mods.RA.Traits var underCursor = world.ScreenMap.ActorsAt(mi) .Where(a => !world.FogObscures(a)) - .MaxByOrDefault(a => a.Info.Traits.Contains() + .MaxByOrDefault(a => a.Info.HasTraitInfo() ? a.Info.Traits.Get().Priority : int.MinValue); if (mi.Button == Game.Settings.Game.MouseButtonPreference.Action && underCursor == null) diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs index 0c7ebdf689..43f4e623b8 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/ChronoshiftPower.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA.Traits foreach (var t in tiles) units.UnionWith(Self.World.ActorMap.GetUnitsAt(t)); - return units.Where(a => a.Info.Traits.Contains() && + return units.Where(a => a.Info.HasTraitInfo() && !a.TraitsImplementing().Any(condition => condition.PreventsTeleport(a))); }