Convert masses of HashSet<string> to BitSet<DamageType>

This commit is contained in:
Chris Forbes
2018-07-27 22:24:51 -07:00
committed by Paul Chote
parent 6d12e84bd9
commit d4ef841678
29 changed files with 86 additions and 62 deletions

View File

@@ -332,7 +332,7 @@ namespace OpenRA
health.InflictDamage(this, attacker, damage, false); health.InflictDamage(this, attacker, damage, false);
} }
public void Kill(Actor attacker, HashSet<string> damageTypes = null) public void Kill(Actor attacker, BitSet<DamageType> damageTypes = default(BitSet<DamageType>))
{ {
if (Disposed || health == null) if (Disposed || health == null)
return; return;

View File

@@ -41,6 +41,24 @@ namespace OpenRA.Primitives
return bits; return bits;
} }
public static BitSetIndex GetBitsNoAlloc(string[] values)
{
// Map strings to existing bits; do not allocate missing values new bits
BitSetIndex bits = 0;
lock (Bits)
{
foreach (var value in values)
{
BitSetIndex valueBit;
if (Bits.TryGetValue(value, out valueBit))
bits |= valueBit;
}
}
return bits;
}
public static IEnumerable<string> GetStrings(BitSetIndex bits) public static IEnumerable<string> GetStrings(BitSetIndex bits)
{ {
var values = new List<string>(); var values = new List<string>();
@@ -69,6 +87,11 @@ namespace OpenRA.Primitives
public BitSet(params string[] values) : this(BitSetAllocator<T>.GetBits(values)) { } public BitSet(params string[] values) : this(BitSetAllocator<T>.GetBits(values)) { }
BitSet(BitSetIndex bits) { this.bits = bits; } BitSet(BitSetIndex bits) { this.bits = bits; }
public static BitSet<T> FromStringsNoAlloc(string[] values)
{
return new BitSet<T>(BitSetAllocator<T>.GetBitsNoAlloc(values)) { };
}
public override string ToString() public override string ToString()
{ {
return BitSetAllocator<T>.GetStrings(bits).JoinWith(","); return BitSetAllocator<T>.GetStrings(bits).JoinWith(",");

View File

@@ -33,6 +33,11 @@ namespace OpenRA.Traits
Dead = 32 Dead = 32
} }
/// <summary>
/// Type tag for DamageTypes <see cref="Primitives.BitSet{T}"/>.
/// </summary>
public sealed class DamageType { DamageType() { } }
public interface IHealth public interface IHealth
{ {
DamageState DamageState { get; } DamageState DamageState { get; }
@@ -42,7 +47,7 @@ namespace OpenRA.Traits
bool IsDead { get; } bool IsDead { get; }
void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers); void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers);
void Kill(Actor self, Actor attacker, HashSet<string> damageTypes); void Kill(Actor self, Actor attacker, BitSet<DamageType> damageTypes);
} }
// depends on the order of pips in WorldRenderer.cs! // depends on the order of pips in WorldRenderer.cs!
@@ -77,9 +82,9 @@ namespace OpenRA.Traits
public class Damage public class Damage
{ {
public readonly int Value; public readonly int Value;
public readonly HashSet<string> DamageTypes; public readonly BitSet<DamageType> DamageTypes;
public Damage(int damage, HashSet<string> damageTypes) public Damage(int damage, BitSet<DamageType> damageTypes)
{ {
Value = damage; Value = damage;
DamageTypes = damageTypes; DamageTypes = damageTypes;
@@ -88,7 +93,7 @@ namespace OpenRA.Traits
public Damage(int damage) public Damage(int damage)
{ {
Value = damage; Value = damage;
DamageTypes = new HashSet<string>(); DamageTypes = default(BitSet<DamageType>);
} }
} }

View File

@@ -16,6 +16,7 @@ using OpenRA.Activities;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Traits.Render; using OpenRA.Mods.Common.Traits.Render;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Cnc.Activities namespace OpenRA.Mods.Cnc.Activities
@@ -30,9 +31,9 @@ namespace OpenRA.Mods.Cnc.Activities
WPos to; WPos to;
int ticks; int ticks;
WAngle angle; WAngle angle;
HashSet<string> damageTypes; BitSet<DamageType> damageTypes;
public Leap(Actor self, Actor target, Armament a, WDist speed, WAngle angle, HashSet<string> damageTypes) public Leap(Actor self, Actor target, Armament a, WDist speed, WAngle angle, BitSet<DamageType> damageTypes)
{ {
var targetMobile = target.TraitOrDefault<Mobile>(); var targetMobile = target.TraitOrDefault<Mobile>();
if (targetMobile == null) if (targetMobile == null)

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Cnc.Activities; using OpenRA.Mods.Cnc.Activities;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Cnc.Traits namespace OpenRA.Mods.Cnc.Traits
@@ -26,7 +27,7 @@ namespace OpenRA.Mods.Cnc.Traits
public readonly WAngle Angle = WAngle.FromDegrees(20); public readonly WAngle Angle = WAngle.FromDegrees(20);
[Desc("Types of damage that this trait causes. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new AttackLeap(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackLeap(init.Self, this); }
} }

View File

@@ -9,7 +9,6 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using OpenRA.Mods.Cnc.Activities; using OpenRA.Mods.Cnc.Activities;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
@@ -25,7 +24,7 @@ namespace OpenRA.Mods.Cnc.Traits
public readonly bool ExplodeInstead = false; public readonly bool ExplodeInstead = false;
[Desc("Types of damage that this trait causes to self when 'ExplodeInstead' is true. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes to self when 'ExplodeInstead' is true. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public readonly string ChronoshiftSound = "chrono2.aud"; public readonly string ChronoshiftSound = "chrono2.aud";

View File

@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Cnc.Traits
public readonly int Damage = 1000; public readonly int Damage = 1000;
[Desc("Apply the damage using these damagetypes.")] [Desc("Apply the damage using these damagetypes.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[Desc("Actor to transform into when the timer expires during (un)deploy."), ActorReference] [Desc("Actor to transform into when the timer expires during (un)deploy."), ActorReference]
public readonly string OriginalActor = "mcv"; public readonly string OriginalActor = "mcv";

View File

@@ -54,7 +54,7 @@ namespace OpenRA.Mods.Cnc.Traits
public WeaponInfo DetonationWeaponInfo { get; private set; } public WeaponInfo DetonationWeaponInfo { get; private set; }
[Desc("Types of damage that this trait causes to self while self-destructing. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes to self while self-destructing. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public object Create(ActorInitializer init) { return new MadTank(init.Self, this); } public object Create(ActorInitializer init) { return new MadTank(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)

View File

@@ -11,6 +11,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Cnc.Traits namespace OpenRA.Mods.Cnc.Traits
@@ -48,7 +49,7 @@ namespace OpenRA.Mods.Cnc.Traits
if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.LocomotorInfo.Crushes)) if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.LocomotorInfo.Crushes))
return; return;
self.Kill(crusher, mobile != null ? mobile.Info.LocomotorInfo.CrushDamageTypes : new HashSet<string>()); self.Kill(crusher, mobile != null ? mobile.Info.LocomotorInfo.CrushDamageTypes : default(BitSet<DamageType>));
} }
bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses) bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses)

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
class AttackSuicidesInfo : ConditionalTraitInfo, Requires<IMoveInfo> class AttackSuicidesInfo : ConditionalTraitInfo, Requires<IMoveInfo>
{ {
[Desc("Types of damage that this trait causes to self while suiciding. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes to self while suiciding. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[VoiceReference] public readonly string Voice = "Action"; [VoiceReference] public readonly string Voice = "Action";

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits
public WeaponInfo DemolishWeaponInfo { get; private set; } public WeaponInfo DemolishWeaponInfo { get; private set; }
[Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")] [Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public object Create(ActorInitializer init) { return new Bridge(init.Self, this); } public object Create(ActorInitializer init) { return new Bridge(init.Self, this); }

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -31,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
public WeaponInfo DemolishWeaponInfo { get; private set; } public WeaponInfo DemolishWeaponInfo { get; private set; }
[Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")] [Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{ {

View File

@@ -10,7 +10,7 @@
#endregion #endregion
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.Play(SoundType.World, Info.CrushSound, crusher.CenterPosition); Game.Sound.Play(SoundType.World, Info.CrushSound, crusher.CenterPosition);
var crusherMobile = crusher.TraitOrDefault<Mobile>(); var crusherMobile = crusher.TraitOrDefault<Mobile>();
self.Kill(crusher, crusherMobile != null ? crusherMobile.Info.LocomotorInfo.CrushDamageTypes : new HashSet<string>()); self.Kill(crusher, crusherMobile != null ? crusherMobile.Info.LocomotorInfo.CrushDamageTypes : default(BitSet<DamageType>));
} }
bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses) bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses)

View File

@@ -9,9 +9,8 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.GameRules; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -26,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int DamageInterval = 0; public readonly int DamageInterval = 0;
[Desc("Apply the damage using these damagetypes.")] [Desc("Apply the damage using these damagetypes.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[Desc("Terrain types where the actor will take damage.")] [Desc("Terrain types where the actor will take damage.")]
[FieldLoader.Require] public readonly string[] Terrain = { }; [FieldLoader.Require] public readonly string[] Terrain = { };

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Mods.Common.Warheads; using OpenRA.Mods.Common.Warheads;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -40,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int DamageThreshold = 0; public readonly int DamageThreshold = 0;
[Desc("DeathType(s) that trigger the explosion. Leave empty to always trigger an explosion.")] [Desc("DeathType(s) that trigger the explosion. Leave empty to always trigger an explosion.")]
public readonly HashSet<string> DeathTypes = new HashSet<string>(); public readonly BitSet<DamageType> DeathTypes = default(BitSet<DamageType>);
[Desc("Who is counted as source of damage for explosion.", [Desc("Who is counted as source of damage for explosion.",
"Possible values are Self and Killer.")] "Possible values are Self and Killer.")]
@@ -102,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits
if (self.World.SharedRandom.Next(100) > Info.Chance) if (self.World.SharedRandom.Next(100) > Info.Chance)
return; return;
if (Info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes)) if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
return; return;
var weapon = ChooseWeaponForExplosion(self); var weapon = ChooseWeaponForExplosion(self);
@@ -141,7 +142,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.DamageThreshold == 0) if (Info.DamageThreshold == 0)
return; return;
if (Info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes)) if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
return; return;
// Cast to long to avoid overflow when multiplying by the health // Cast to long to avoid overflow when multiplying by the health

View File

@@ -9,10 +9,9 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Warheads; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -31,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("DeathTypes for which a bounty should be granted.", [Desc("DeathTypes for which a bounty should be granted.",
"Use an empty list (the default) to allow all DeathTypes.")] "Use an empty list (the default) to allow all DeathTypes.")]
public readonly HashSet<string> DeathTypes = new HashSet<string>(); public readonly BitSet<DamageType> DeathTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new GivesBounty(this); } public override object Create(ActorInitializer init) { return new GivesBounty(this); }
} }
@@ -79,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits
if (!Info.ValidStances.HasStance(e.Attacker.Owner.Stances[self.Owner])) if (!Info.ValidStances.HasStance(e.Attacker.Owner.Stances[self.Owner]))
return; return;
if (Info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes)) if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
return; return;
var displayedBounty = GetDisplayedBountyValue(self); var displayedBounty = GetDisplayedBountyValue(self);

View File

@@ -9,8 +9,8 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -164,11 +164,8 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public void Kill(Actor self, Actor attacker, HashSet<string> damageTypes = null) public void Kill(Actor self, Actor attacker, BitSet<DamageType> damageTypes)
{ {
if (damageTypes == null)
damageTypes = new HashSet<string>();
InflictDamage(self, attacker, new Damage(MaxHP, damageTypes), true); InflictDamage(self, attacker, new Damage(MaxHP, damageTypes), true);
} }

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Warheads; using OpenRA.Mods.Common.Warheads;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -27,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
[FieldLoader.Require] [FieldLoader.Require]
[Desc("Damage types that trigger prone state. Defined on the warheads.")] [Desc("Damage types that trigger prone state. Defined on the warheads.")]
public readonly HashSet<string> DamageTriggers = new HashSet<string>(); public readonly BitSet<DamageType> DamageTriggers = default(BitSet<DamageType>);
[Desc("Damage modifiers for each damage type (defined on the warheads) while the unit is prone.")] [Desc("Damage modifiers for each damage type (defined on the warheads) while the unit is prone.")]
public readonly Dictionary<string, int> DamageModifiers = new Dictionary<string, int>(); public readonly Dictionary<string, int> DamageModifiers = new Dictionary<string, int>();
@@ -83,7 +84,7 @@ namespace OpenRA.Mods.Common.Traits
if (!IsProne) if (!IsProne)
return 100; return 100;
if (damage.DamageTypes.Count == 0) if (damage.DamageTypes.IsEmpty)
return 100; return 100;
var modifierPercentages = info.DamageModifiers.Where(x => damage.DamageTypes.Contains(x.Key)).Select(x => x.Value); var modifierPercentages = info.DamageModifiers.Where(x => damage.DamageTypes.Contains(x.Key)).Select(x => x.Value);

View File

@@ -9,7 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int[] Delay = { 0 }; public readonly int[] Delay = { 0 };
[Desc("Types of damage that this trait causes. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[GrantedConditionReference] [GrantedConditionReference]
[Desc("The condition to grant moments before suiciding.")] [Desc("The condition to grant moments before suiciding.")]

View File

@@ -9,8 +9,8 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly string Owner = "Neutral"; public readonly string Owner = "Neutral";
[Desc("The deathtypes used when 'Action' is 'Kill'.")] [Desc("The deathtypes used when 'Action' is 'Kill'.")]
public readonly HashSet<string> DeathTypes = new HashSet<string>(); public readonly BitSet<DamageType> DeathTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new OwnerLostAction(init, this); } public override object Create(ActorInitializer init) { return new OwnerLostAction(init, this); }
} }

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -23,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly bool KilledOnImpassableTerrain = true; public readonly bool KilledOnImpassableTerrain = true;
[Desc("Types of damage that this trait causes to self when 'KilledOnImpassableTerrain' is true. Leave empty for no damage types.")] [Desc("Types of damage that this trait causes to self when 'KilledOnImpassableTerrain' is true. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[Desc("Image where Ground/WaterCorpseSequence is looked up.")] [Desc("Image where Ground/WaterCorpseSequence is looked up.")]
public readonly string Image = "explosion"; public readonly string Image = "explosion";

View File

@@ -11,6 +11,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -220,13 +221,9 @@ namespace OpenRA.Mods.Common.Traits
var actor = order.Target.Actor; var actor = order.Target.Actor;
var args = order.TargetString.Split(' '); var args = order.TargetString.Split(' ');
var damageTypes = new HashSet<string>(); var damageTypes = BitSet<DamageType>.FromStringsNoAlloc(args);
foreach (var damageType in args)
damageTypes.Add(damageType);
actor.Kill(actor, damageTypes); actor.Kill(actor, damageTypes);
break; break;
} }

View File

@@ -9,9 +9,8 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Warheads; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render namespace OpenRA.Mods.Common.Traits.Render
@@ -27,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Damage types that this should be used for (defined on the warheads).", [Desc("Damage types that this should be used for (defined on the warheads).",
"Leave empty to disable all filtering.")] "Leave empty to disable all filtering.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[Desc("Trigger when Undamaged, Light, Medium, Heavy, Critical or Dead.")] [Desc("Trigger when Undamaged, Light, Medium, Heavy, Critical or Dead.")]
public readonly DamageState MinimumDamageState = DamageState.Heavy; public readonly DamageState MinimumDamageState = DamageState.Heavy;
@@ -55,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits.Render
void INotifyDamage.Damaged(Actor self, AttackInfo e) void INotifyDamage.Damaged(Actor self, AttackInfo e)
{ {
if (info.DamageTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(info.DamageTypes)) if (!info.DamageTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(info.DamageTypes))
return; return;
if (isSmoking) return; if (isSmoking) return;

View File

@@ -12,7 +12,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Warheads;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render namespace OpenRA.Mods.Common.Traits.Render
@@ -73,7 +72,7 @@ namespace OpenRA.Mods.Common.Traits.Render
palette += self.Owner.InternalName; palette += self.Owner.InternalName;
// Killed by some non-standard means // Killed by some non-standard means
if (e.Damage.DamageTypes.Count == 0) if (e.Damage.DamageTypes.IsEmpty)
{ {
if (Info.FallbackSequence != null) if (Info.FallbackSequence != null)
SpawnDeathAnimation(self, self.CenterPosition, rs.GetImage(self), Info.FallbackSequence, palette); SpawnDeathAnimation(self, self.CenterPosition, rs.GetImage(self), Info.FallbackSequence, palette);

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -33,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("DeathTypes for which shroud will be revealed.", [Desc("DeathTypes for which shroud will be revealed.",
"Use an empty list (the default) to allow all DeathTypes.")] "Use an empty list (the default) to allow all DeathTypes.")]
public readonly HashSet<string> DeathTypes = new HashSet<string>(); public readonly BitSet<DamageType> DeathTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new RevealOnDeath(init.Self, this); } public override object Create(ActorInitializer init) { return new RevealOnDeath(init.Self, this); }
} }
@@ -56,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
if (!self.IsInWorld) if (!self.IsInWorld)
return; return;
if (info.DeathTypes.Count > 0 && !attack.Damage.DamageTypes.Overlaps(info.DeathTypes)) if (!info.DeathTypes.IsEmpty && !attack.Damage.DamageTypes.Overlaps(info.DeathTypes))
return; return;
var owner = self.Owner; var owner = self.Owner;

View File

@@ -9,7 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int DamageCooldown = 0; public readonly int DamageCooldown = 0;
[Desc("Apply the selfhealing using these damagetypes.")] [Desc("Apply the selfhealing using these damagetypes.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new SelfHealing(init.Self, this); } public override object Create(ActorInitializer init) { return new SelfHealing(init.Self, this); }
} }

View File

@@ -9,8 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic; using OpenRA.Primitives;
using OpenRA.Mods.Common.Warheads;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Sound namespace OpenRA.Mods.Common.Traits.Sound
@@ -26,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
[Desc("Damage types that this should be used for (defined on the warheads).", [Desc("Damage types that this should be used for (defined on the warheads).",
"If empty, this will be used as the default sound for all death types.")] "If empty, this will be used as the default sound for all death types.")]
public readonly HashSet<string> DeathTypes = new HashSet<string>(); public readonly BitSet<DamageType> DeathTypes = default(BitSet<DamageType>);
public override object Create(ActorInitializer init) { return new DeathSounds(this); } public override object Create(ActorInitializer init) { return new DeathSounds(this); }
} }
@@ -41,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
if (IsTraitDisabled) if (IsTraitDisabled)
return; return;
if (Info.DeathTypes.Count == 0 || e.Damage.DamageTypes.Overlaps(Info.DeathTypes)) if (!Info.DeathTypes.IsEmpty || e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
self.PlayVoiceLocal(Info.Voice, Info.VolumeMultiplier); self.PlayVoiceLocal(Info.Voice, Info.VolumeMultiplier);
} }
} }

View File

@@ -12,7 +12,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Pathfinder;
using OpenRA.Primitives; using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
@@ -64,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly HashSet<string> Crushes = new HashSet<string>(); public readonly HashSet<string> Crushes = new HashSet<string>();
[Desc("Types of damage that are caused while crushing. Leave empty for no damage types.")] [Desc("Types of damage that are caused while crushing. Leave empty for no damage types.")]
public readonly HashSet<string> CrushDamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> CrushDamageTypes = default(BitSet<DamageType>);
[FieldLoader.LoadUsing("LoadSpeeds", true)] [FieldLoader.LoadUsing("LoadSpeeds", true)]
[Desc("Set Water: 0 for ground units and lower the value on rough terrain.")] [Desc("Set Water: 0 for ground units and lower the value on rough terrain.")]

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Warheads namespace OpenRA.Mods.Common.Warheads
@@ -22,7 +23,7 @@ namespace OpenRA.Mods.Common.Warheads
public readonly int Damage = 0; public readonly int Damage = 0;
[Desc("Types of damage that this warhead causes. Leave empty for no damage types.")] [Desc("Types of damage that this warhead causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly BitSet<DamageType> DamageTypes = default(BitSet<DamageType>);
[Desc("Damage percentage versus each armortype.")] [Desc("Damage percentage versus each armortype.")]
public readonly Dictionary<string, int> Versus = new Dictionary<string, int>(); public readonly Dictionary<string, int> Versus = new Dictionary<string, int>();