From 3c66ca709ae69e525a2c5b3f6a0a599bfe948650 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Mon, 19 Sep 2022 10:39:21 +0100 Subject: [PATCH] Fix some bugs in LongBitSet - Use LongBitSetAllocator and not BitSetAllocator. Using the wrong allocator means all string based checks and displays would provide incorrect results. - Remove LongBitSetAllocator.Mask which wasn't being calculated or Reset correctly. We can use world.AllPlayersMask to provide the same effect at use sites. --- OpenRA.Game/Primitives/LongBitSet.cs | 11 +++-------- OpenRA.Mods.Cnc/Traits/Mine.cs | 2 +- OpenRA.Mods.Common/Traits/Crushable.cs | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/Primitives/LongBitSet.cs b/OpenRA.Game/Primitives/LongBitSet.cs index e2fc002f66..5d6ee3e867 100644 --- a/OpenRA.Game/Primitives/LongBitSet.cs +++ b/OpenRA.Game/Primitives/LongBitSet.cs @@ -18,7 +18,6 @@ namespace OpenRA.Primitives static class LongBitSetAllocator where T : class { static readonly Cache Bits = new Cache(Allocate); - static long allBits = 1; static long nextBits = 1; static long Allocate(string value) @@ -26,7 +25,6 @@ namespace OpenRA.Primitives lock (Bits) { var bits = nextBits; - allBits |= bits; nextBits <<= 1; if (nextBits == 0) @@ -87,8 +85,6 @@ namespace OpenRA.Primitives nextBits = 1; } } - - public static long Mask => allBits; } // Optimized BitSet to be used only when guaranteed to be no more than 64 values. @@ -113,12 +109,11 @@ namespace OpenRA.Primitives public override string ToString() { - return BitSetAllocator.GetStrings(bits).JoinWith(","); + return LongBitSetAllocator.GetStrings(bits).JoinWith(","); } public static bool operator ==(LongBitSet me, LongBitSet other) { return me.bits == other.bits; } public static bool operator !=(LongBitSet me, LongBitSet other) { return !(me == other); } - public static LongBitSet operator ~(LongBitSet me) { return new LongBitSet(me.bits ^ LongBitSetAllocator.Mask); } public bool Equals(LongBitSet other) { return other == this; } public override bool Equals(object obj) { return obj is LongBitSet && Equals((LongBitSet)obj); } @@ -158,12 +153,12 @@ namespace OpenRA.Primitives public bool Contains(string value) { - return BitSetAllocator.BitsContainString(bits, value); + return LongBitSetAllocator.BitsContainString(bits, value); } public IEnumerator GetEnumerator() { - return BitSetAllocator.GetStrings(bits).GetEnumerator(); + return LongBitSetAllocator.GetStrings(bits).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() diff --git a/OpenRA.Mods.Cnc/Traits/Mine.cs b/OpenRA.Mods.Cnc/Traits/Mine.cs index 12e1b6c41a..b9fa7d61cb 100644 --- a/OpenRA.Mods.Cnc/Traits/Mine.cs +++ b/OpenRA.Mods.Cnc/Traits/Mine.cs @@ -65,7 +65,7 @@ namespace OpenRA.Mods.Cnc.Traits return self.World.NoPlayersMask; // Friendly units should move around! - return info.BlockFriendly ? ~self.Owner.AlliedPlayersMask : self.World.AllPlayersMask; + return info.BlockFriendly ? self.World.AllPlayersMask.Except(self.Owner.AlliedPlayersMask) : self.World.AllPlayersMask; } } diff --git a/OpenRA.Mods.Common/Traits/Crushable.cs b/OpenRA.Mods.Common/Traits/Crushable.cs index 29ef903fa6..d1cbb5bc98 100644 --- a/OpenRA.Mods.Common/Traits/Crushable.cs +++ b/OpenRA.Mods.Common/Traits/Crushable.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits if (IsTraitDisabled || !self.IsAtGroundLevel() || !Info.CrushClasses.Overlaps(crushClasses)) return self.World.NoPlayersMask; - return Info.CrushedByFriendlies ? self.World.AllPlayersMask : ~self.Owner.AlliedPlayersMask; + return Info.CrushedByFriendlies ? self.World.AllPlayersMask : self.World.AllPlayersMask.Except(self.Owner.AlliedPlayersMask); } bool CrushableInner(BitSet crushClasses, Player crushOwner)