Replace arrays with sets.
In places where arrays were being treated as a set, just create a set directly. This reveals the intention of such collections better, and also improves performance by allowing set based methods to be used.
This commit is contained in:
@@ -27,7 +27,7 @@ namespace OpenRA.Traits
|
||||
public readonly PPos[] Footprint;
|
||||
public readonly WPos CenterPosition;
|
||||
public readonly Rectangle Bounds;
|
||||
public readonly string[] TargetTypes;
|
||||
public readonly HashSet<string> TargetTypes;
|
||||
readonly IRemoveFrozenActor[] removeFrozenActors;
|
||||
readonly Actor actor;
|
||||
readonly Shroud shroud;
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Traits
|
||||
|
||||
CenterPosition = self.CenterPosition;
|
||||
Bounds = self.Bounds;
|
||||
TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).Distinct().ToArray();
|
||||
TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).ToHashSet();
|
||||
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
@@ -310,13 +310,13 @@ namespace OpenRA.Traits
|
||||
|
||||
public interface ITargetableInfo
|
||||
{
|
||||
string[] GetTargetTypes();
|
||||
HashSet<string> GetTargetTypes();
|
||||
}
|
||||
|
||||
public interface ITargetable
|
||||
{
|
||||
// Check IsTraitEnabled or !IsTraitDisabled first
|
||||
string[] TargetTypes { get; }
|
||||
HashSet<string> TargetTypes { get; }
|
||||
bool TargetableBy(Actor self, Actor byActor);
|
||||
bool RequiresForceFire { get; }
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
public readonly Stance Against = Stance.Enemy;
|
||||
|
||||
[Desc("What types should the desired targets of this power be?")]
|
||||
public readonly string[] Types = { "Air", "Ground", "Water" };
|
||||
public readonly HashSet<string> Types = new HashSet<string> { "Air", "Ground", "Water" };
|
||||
|
||||
[Desc("How attractive are these types of targets?")]
|
||||
public readonly int Attractiveness = 100;
|
||||
@@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
if (!targetable.Any(t => t.TargetableBy(a, firedBy.PlayerActor)))
|
||||
return 0;
|
||||
|
||||
if (Types.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any())
|
||||
if (Types.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
|
||||
{
|
||||
switch (TargetMetric)
|
||||
{
|
||||
|
||||
@@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.Lint
|
||||
continue;
|
||||
|
||||
// This warhead cannot affect this actor.
|
||||
if (!warhead.ValidTargets.Intersect(targetable).Any())
|
||||
if (!warhead.ValidTargets.Overlaps(targetable))
|
||||
continue;
|
||||
|
||||
if (!warhead.DamageTypes.Intersect(deathTypes).Any())
|
||||
if (!warhead.DamageTypes.Overlaps(deathTypes))
|
||||
emitError("Actor type `{0}` does not define a death animation for weapon `{1}`!"
|
||||
.F(actorInfo.Key, weaponInfo.Key));
|
||||
}
|
||||
|
||||
@@ -77,12 +77,12 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
return target.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetTypes.Intersect(targetTypes).Any());
|
||||
return target.TraitsImplementing<ITargetable>().Any(t => t.IsTraitEnabled() && t.TargetTypes.Overlaps(targetTypes));
|
||||
}
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
return target.TargetTypes.Intersect(targetTypes).Any();
|
||||
return target.TargetTypes.Overlaps(targetTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (world.ActorsWithTrait<LineBuildNode>().Any(a =>
|
||||
(a.Actor.Location == cell &&
|
||||
a.Actor.Info.Traits.Get<LineBuildNodeInfo>()
|
||||
.Types.Intersect(lbi.NodeTypes).Any())))
|
||||
.Types.Overlaps(lbi.NodeTypes))))
|
||||
dirs[d] = i; // Cell contains actor of correct type
|
||||
else
|
||||
dirs[d] = -1; // Cell is blocked by another actor type
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -16,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class LineBuildNodeInfo : TraitInfo<LineBuildNode>
|
||||
{
|
||||
[Desc("This actor is of LineBuild 'NodeType'...")]
|
||||
public readonly string[] Types = { "wall" };
|
||||
public readonly HashSet<string> Types = new HashSet<string> { "wall" };
|
||||
}
|
||||
|
||||
public class LineBuildNode { }
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly string UncloakSound = null;
|
||||
[PaletteReference] public readonly string Palette = "cloak";
|
||||
|
||||
public readonly string[] CloakTypes = { "Cloak" };
|
||||
public readonly HashSet<string> CloakTypes = new HashSet<string> { "Cloak" };
|
||||
|
||||
[UpgradeGrantedReference]
|
||||
[Desc("The upgrades to grant to self while cloaked.")]
|
||||
@@ -150,7 +150,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return true;
|
||||
|
||||
return self.World.ActorsWithTrait<DetectCloaked>().Any(a => !a.Trait.IsTraitDisabled && a.Actor.Owner.IsAlliedWith(viewer)
|
||||
&& Info.CloakTypes.Intersect(a.Trait.Info.CloakTypes).Any()
|
||||
&& Info.CloakTypes.Overlaps(a.Trait.Info.CloakTypes)
|
||||
&& (self.CenterPosition - a.Actor.CenterPosition).Length <= WDist.FromCells(a.Trait.Info.Range).Length);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
@@ -31,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly int MaxRadius = 4;
|
||||
|
||||
[Desc("The list of unit target types we are allowed to duplicate.")]
|
||||
public readonly string[] ValidTargets = { "Ground", "Water" };
|
||||
public readonly HashSet<string> ValidTargets = new HashSet<string> { "Ground", "Water" };
|
||||
|
||||
[Desc("Which factions this crate action can occur for.")]
|
||||
public readonly string[] ValidFactions = { };
|
||||
@@ -58,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return false;
|
||||
|
||||
var targetable = collector.TraitsImplementing<ITargetable>();
|
||||
if (!info.ValidTargets.Intersect(targetable.SelectMany(t => t.TargetTypes)).Any())
|
||||
if (!info.ValidTargets.Overlaps(targetable.SelectMany(t => t.TargetTypes)))
|
||||
return false;
|
||||
|
||||
var positionable = collector.TraitOrDefault<IPositionable>();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Sound to play when being crushed.")]
|
||||
public readonly string CrushSound = null;
|
||||
[Desc("Which crush classes does this actor belong to.")]
|
||||
public readonly string[] CrushClasses = { "infantry" };
|
||||
public readonly HashSet<string> CrushClasses = new HashSet<string> { "infantry" };
|
||||
[Desc("Probability of mobile actors noticing and evading a crush attempt.")]
|
||||
public readonly int WarnProbability = 75;
|
||||
[Desc("Will friendly units just crush me instead of pathing around.")]
|
||||
@@ -72,7 +73,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!info.CrushedByFriendlies && crushOwner.IsAlliedWith(self.Owner))
|
||||
return false;
|
||||
|
||||
return info.CrushClasses.Intersect(crushClasses).Any();
|
||||
return info.CrushClasses.Overlaps(crushClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class DetectCloakedInfo : UpgradableTraitInfo
|
||||
{
|
||||
[Desc("Specific cloak classifications I can reveal.")]
|
||||
public readonly string[] CloakTypes = { "Cloak" };
|
||||
public readonly HashSet<string> CloakTypes = new HashSet<string> { "Cloak" };
|
||||
|
||||
[Desc("Measured in cells.")]
|
||||
public readonly int Range = 5;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return;
|
||||
|
||||
var warhead = e.Warhead as DamageWarhead;
|
||||
if (info.DeathType != null && warhead != null && !info.DeathType.Intersect(warhead.DamageTypes).Any())
|
||||
if (info.DeathType != null && warhead != null && !warhead.DamageTypes.Overlaps(info.DeathType))
|
||||
return;
|
||||
|
||||
var weaponName = ChooseWeaponForExplosion(self);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (Info.UseDeathTypeSuffix)
|
||||
{
|
||||
var warhead = e.Warhead as DamageWarhead;
|
||||
var damageType = warhead.DamageTypes.Intersect(Info.DeathTypes.Keys).FirstOrDefault();
|
||||
var damageType = Info.DeathTypes.Keys.FirstOrDefault(warhead.DamageTypes.Contains);
|
||||
if (damageType == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (warhead == null)
|
||||
return;
|
||||
|
||||
if (info.DeathTypes.Intersect(warhead.DamageTypes).Any())
|
||||
if (warhead.DamageTypes.Overlaps(info.DeathTypes))
|
||||
self.PlayVoiceLocal(info.Voice, info.VolumeMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class TargetableInfo : UpgradableTraitInfo, ITargetableInfo
|
||||
{
|
||||
[Desc("Target type. Used for filtering (in)valid targets.")]
|
||||
public readonly string[] TargetTypes = { };
|
||||
public string[] GetTargetTypes() { return TargetTypes; }
|
||||
public readonly HashSet<string> TargetTypes = new HashSet<string>();
|
||||
public HashSet<string> GetTargetTypes() { return TargetTypes; }
|
||||
|
||||
public bool RequiresForceFire = false;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return cloak.IsVisible(self, viewer.Owner);
|
||||
}
|
||||
|
||||
public virtual string[] TargetTypes { get { return Info.TargetTypes; } }
|
||||
public virtual HashSet<string> TargetTypes { get { return Info.TargetTypes; } }
|
||||
|
||||
public bool RequiresForceFire { get { return Info.RequiresForceFire; } }
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Warheads
|
||||
public readonly int Damage = 0;
|
||||
|
||||
[Desc("Types of damage that this warhead causes. Leave empty for no damage.")]
|
||||
public readonly string[] DamageTypes = new string[0];
|
||||
public readonly HashSet<string> DamageTypes = new HashSet<string>();
|
||||
|
||||
[FieldLoader.LoadUsing("LoadVersus")]
|
||||
[Desc("Damage percentage versus each armortype.")]
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Uses the \"Cloneable\" trait to determine whether or not we should clone a produced unit.")]
|
||||
public readonly string[] CloneableTypes = { };
|
||||
public readonly HashSet<string> CloneableTypes = new HashSet<string>();
|
||||
|
||||
public object Create(ActorInitializer init) { return new ClonesProducedUnits(init, this); }
|
||||
}
|
||||
@@ -44,7 +45,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
return;
|
||||
|
||||
var ci = produced.Info.Traits.GetOrDefault<CloneableInfo>();
|
||||
if (ci == null || !info.CloneableTypes.Intersect(ci.Types).Any())
|
||||
if (ci == null || !info.CloneableTypes.Overlaps(ci.Types))
|
||||
return;
|
||||
|
||||
production.Produce(self, produced.Info, faction);
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
class InfiltratesInfo : ITraitInfo
|
||||
{
|
||||
public readonly string[] Types = { };
|
||||
public readonly HashSet<string> Types = new HashSet<string>();
|
||||
|
||||
[VoiceReference] public readonly string Voice = "Action";
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
targetTypes = order.TargetActor.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled)
|
||||
.SelectMany(t => t.TargetTypes);
|
||||
|
||||
return targetTypes.Intersect(Info.Types).Any();
|
||||
return Info.Types.Overlaps(targetTypes);
|
||||
}
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
@@ -96,7 +96,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
var target = self.ResolveFrozenActorOrder(order, Color.Red);
|
||||
if (target.Type != TargetType.Actor
|
||||
|| target.Actor.TraitsImplementing<ITargetable>().SelectMany(t => t.TargetTypes).Intersect(Info.Types).Any())
|
||||
|| Info.Types.Overlaps(target.Actor.TraitsImplementing<ITargetable>().SelectMany(t => t.TargetTypes)))
|
||||
return;
|
||||
|
||||
if (!order.Queued)
|
||||
@@ -124,7 +124,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
if (!info.ValidStances.HasStance(stance))
|
||||
return false;
|
||||
|
||||
return target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Intersect(info.Types).Any());
|
||||
return target.TraitsImplementing<ITargetable>().Any(t => t.TargetTypes.Overlaps(info.Types));
|
||||
}
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
@@ -134,7 +134,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
if (!info.ValidStances.HasStance(stance))
|
||||
return false;
|
||||
|
||||
return target.Info.Traits.WithInterface<ITargetableInfo>().Any(t => t.GetTargetTypes().Intersect(info.Types).Any());
|
||||
return target.Info.Traits.WithInterface<ITargetableInfo>().Any(t => info.Types.Overlaps(t.GetTargetTypes()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
@@ -16,9 +17,9 @@ namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
class MineInfo : ITraitInfo
|
||||
{
|
||||
public readonly string[] CrushClasses = { };
|
||||
public readonly HashSet<string> CrushClasses = new HashSet<string>();
|
||||
public readonly bool AvoidFriendly = true;
|
||||
public readonly string[] DetonateClasses = { };
|
||||
public readonly HashSet<string> DetonateClasses = new HashSet<string>();
|
||||
|
||||
public object Create(ActorInitializer init) { return new Mine(init, this); }
|
||||
}
|
||||
@@ -42,7 +43,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
return;
|
||||
|
||||
var mobile = crusher.TraitOrDefault<Mobile>();
|
||||
if (mobile != null && !info.DetonateClasses.Intersect(mobile.Info.Crushes).Any())
|
||||
if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.Crushes))
|
||||
return;
|
||||
|
||||
self.Kill(crusher);
|
||||
@@ -50,7 +51,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
public bool CrushableBy(string[] crushClasses, Player owner)
|
||||
{
|
||||
return info.CrushClasses.Intersect(crushClasses).Any();
|
||||
return info.CrushClasses.Overlaps(crushClasses);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user