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.
This commit is contained in:
RoosterDragon
2022-09-19 10:39:21 +01:00
committed by abcdefg30
parent 0080e98390
commit 3c66ca709a
3 changed files with 5 additions and 10 deletions

View File

@@ -18,7 +18,6 @@ namespace OpenRA.Primitives
static class LongBitSetAllocator<T> where T : class
{
static readonly Cache<string, long> Bits = new Cache<string, long>(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<T>.GetStrings(bits).JoinWith(",");
return LongBitSetAllocator<T>.GetStrings(bits).JoinWith(",");
}
public static bool operator ==(LongBitSet<T> me, LongBitSet<T> other) { return me.bits == other.bits; }
public static bool operator !=(LongBitSet<T> me, LongBitSet<T> other) { return !(me == other); }
public static LongBitSet<T> operator ~(LongBitSet<T> me) { return new LongBitSet<T>(me.bits ^ LongBitSetAllocator<T>.Mask); }
public bool Equals(LongBitSet<T> other) { return other == this; }
public override bool Equals(object obj) { return obj is LongBitSet<T> && Equals((LongBitSet<T>)obj); }
@@ -158,12 +153,12 @@ namespace OpenRA.Primitives
public bool Contains(string value)
{
return BitSetAllocator<T>.BitsContainString(bits, value);
return LongBitSetAllocator<T>.BitsContainString(bits, value);
}
public IEnumerator<string> GetEnumerator()
{
return BitSetAllocator<T>.GetStrings(bits).GetEnumerator();
return LongBitSetAllocator<T>.GetStrings(bits).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()

View File

@@ -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;
}
}

View File

@@ -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<CrushClass> crushClasses, Player crushOwner)