diff --git a/OpenRA.Mods.Cnc/Traits/Mine.cs b/OpenRA.Mods.Cnc/Traits/Mine.cs index 621215fb66..fe98137193 100644 --- a/OpenRA.Mods.Cnc/Traits/Mine.cs +++ b/OpenRA.Mods.Cnc/Traits/Mine.cs @@ -9,7 +9,6 @@ */ #endregion -using System.Collections.Generic; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; using OpenRA.Traits; @@ -18,10 +17,10 @@ namespace OpenRA.Mods.Cnc.Traits { class MineInfo : ITraitInfo { - public readonly HashSet CrushClasses = new HashSet(); + public readonly BitSet CrushClasses = default(BitSet); public readonly bool AvoidFriendly = true; public readonly bool BlockFriendly = true; - public readonly HashSet DetonateClasses = new HashSet(); + public readonly BitSet DetonateClasses = default(BitSet); public object Create(ActorInitializer init) { return new Mine(this); } } @@ -35,9 +34,9 @@ namespace OpenRA.Mods.Cnc.Traits this.info = info; } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) { } + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { if (!info.CrushClasses.Overlaps(crushClasses)) return; @@ -52,7 +51,7 @@ namespace OpenRA.Mods.Cnc.Traits self.Kill(crusher, mobile != null ? mobile.Info.LocomotorInfo.CrushDamageTypes : default(BitSet)); } - bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet crushClasses) + bool ICrushable.CrushableBy(Actor self, Actor crusher, BitSet crushClasses) { if (info.BlockFriendly && !crusher.Info.HasTraitInfo() && self.Owner.Stances[crusher.Owner] == Stance.Ally) return false; diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantExternalConditionToCrusher.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantExternalConditionToCrusher.cs index 8a04184789..4ff216dc5a 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantExternalConditionToCrusher.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantExternalConditionToCrusher.cs @@ -9,8 +9,8 @@ */ #endregion -using System.Collections.Generic; using System.Linq; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits this.Info = info; } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { var external = crusher.TraitsImplementing() .FirstOrDefault(t => t.Info.Condition == Info.OnCrushCondition && t.CanGrantCondition(crusher, self)); @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits external.GrantCondition(crusher, self, Info.OnCrushDuration); } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { var external = crusher.TraitsImplementing() .FirstOrDefault(t => t.Info.Condition == Info.WarnCrushCondition && t.CanGrantCondition(crusher, self)); diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index ccbbca3656..06179d593e 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -91,9 +91,9 @@ namespace OpenRA.Mods.Common.Traits SetPosition(self, init.Get()); } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) { } + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { // Crate can only be crushed if it is not in the air. if (!self.IsAtGroundLevel() || !crushClasses.Contains(info.CrushClass)) @@ -216,7 +216,7 @@ namespace OpenRA.Mods.Common.Traits return GetAvailableSubCell(a, SubCell.Any, ignoreActor, checkTransientActors) != SubCell.Invalid; } - bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet crushClasses) + bool ICrushable.CrushableBy(Actor self, Actor crusher, BitSet crushClasses) { // Crate can only be crushed if it is not in the air. return self.IsAtGroundLevel() && crushClasses.Contains(info.CrushClass); diff --git a/OpenRA.Mods.Common/Traits/Crushable.cs b/OpenRA.Mods.Common/Traits/Crushable.cs index f3efd9f5b5..56af963971 100644 --- a/OpenRA.Mods.Common/Traits/Crushable.cs +++ b/OpenRA.Mods.Common/Traits/Crushable.cs @@ -21,7 +21,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 HashSet CrushClasses = new HashSet { "infantry" }; + public readonly BitSet CrushClasses = new BitSet("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.")] @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits this.self = self; } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { if (!CrushableInner(crushClasses, crusher.Owner)) return; @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits mobile.Nudge(self, crusher, true); } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { if (!CrushableInner(crushClasses, crusher.Owner)) return; @@ -61,12 +61,12 @@ namespace OpenRA.Mods.Common.Traits self.Kill(crusher, crusherMobile != null ? crusherMobile.Info.LocomotorInfo.CrushDamageTypes : default(BitSet)); } - bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet crushClasses) + bool ICrushable.CrushableBy(Actor self, Actor crusher, BitSet crushClasses) { return CrushableInner(crushClasses, crusher.Owner); } - bool CrushableInner(HashSet crushClasses, Player crushOwner) + bool CrushableInner(BitSet crushClasses, Player crushOwner) { if (IsTraitDisabled) return false; diff --git a/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs index 7183409e66..5c6cc15459 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDeathAnimation.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common.Effects; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits.Render @@ -98,7 +99,7 @@ namespace OpenRA.Mods.Common.Traits.Render self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, w, image, sequence, palette))); } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { crushed = true; @@ -112,6 +113,6 @@ namespace OpenRA.Mods.Common.Traits.Render SpawnDeathAnimation(self, self.CenterPosition, rs.GetImage(self), Info.CrushedSequence, crushPalette); } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) { } + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { } } } diff --git a/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs b/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs index c1277fd55f..9f4064412d 100644 --- a/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs +++ b/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs @@ -9,8 +9,8 @@ */ #endregion -using System.Collections.Generic; using OpenRA.Mods.Common.Activities; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits public readonly bool SkipMakeAnims = true; - public readonly HashSet CrushClasses = new HashSet(); + public readonly BitSet CrushClasses = default(BitSet); public virtual object Create(ActorInitializer init) { return new TransformCrusherOnCrush(init, this); } } @@ -38,9 +38,9 @@ namespace OpenRA.Mods.Common.Traits faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; } - void INotifyCrushed.WarnCrush(Actor self, Actor crusher, HashSet crushClasses) { } + void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { } - void INotifyCrushed.OnCrush(Actor self, Actor crusher, HashSet crushClasses) + void INotifyCrushed.OnCrush(Actor self, Actor crusher, BitSet crushClasses) { if (!info.CrushClasses.Overlaps(crushClasses)) return; diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index 65b1a4e1fa..bfb48f68fb 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Traits public readonly bool MoveIntoShroud = true; [Desc("e.g. crate, wall, infantry")] - public readonly HashSet Crushes = new HashSet(); + public readonly BitSet Crushes = default(BitSet); [Desc("Types of damage that are caused while crushing. Leave empty for no damage types.")] public readonly BitSet CrushDamageTypes = default(BitSet); @@ -277,7 +277,7 @@ namespace OpenRA.Mods.Common.Traits } // If we cannot crush the other actor in our way, we are blocked. - if (Crushes == null || Crushes.Count == 0) + if (Crushes.IsEmpty) return true; // If the other actor in our way cannot be crushed, we are blocked. diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index 05e3250d5f..37e8ed195f 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -75,17 +75,20 @@ namespace OpenRA.Mods.Common.Traits bool IsValidTarget(Actor self, Actor saboteur); } + // Type tag for crush class bits + public class CrushClass { } + [RequireExplicitImplementation] public interface ICrushable { - bool CrushableBy(Actor self, Actor crusher, HashSet crushClasses); + bool CrushableBy(Actor self, Actor crusher, BitSet crushClasses); } [RequireExplicitImplementation] public interface INotifyCrushed { - void OnCrush(Actor self, Actor crusher, HashSet crushClasses); - void WarnCrush(Actor self, Actor crusher, HashSet crushClasses); + void OnCrush(Actor self, Actor crusher, BitSet crushClasses); + void WarnCrush(Actor self, Actor crusher, BitSet crushClasses); } [RequireExplicitImplementation]