From 1ba4405421b732e51c762cabaa274a1dc3699b63 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 11 Oct 2022 17:09:46 -0400 Subject: [PATCH] Core/Objects: Fix flags overflow for InvisibilityType because TOTAL_INVISIBILITY_TYPES (38) can't fit in 32 bits flag Port From (https://github.com/TrinityCore/TrinityCore/commit/423f81fbdaad9bedf936b313a97afe0be53b6ae0) --- Source/Framework/Dynamic/FlagArray.cs | 30 ++++++++++++++++++---- Source/Game/Entities/Object/WorldObject.cs | 16 ++++++------ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Source/Framework/Dynamic/FlagArray.cs b/Source/Framework/Dynamic/FlagArray.cs index a6906b44c..828c793b3 100644 --- a/Source/Framework/Dynamic/FlagArray.cs +++ b/Source/Framework/Dynamic/FlagArray.cs @@ -173,20 +173,40 @@ namespace Framework.Dynamic } } - public class FlaggedArray where T : struct + public class FlaggedArray32 where T : struct { int[] m_values; uint m_flags; - public FlaggedArray(byte arraysize) + public FlaggedArray32(byte arraysize) { m_values = new int[4 * arraysize]; } public uint GetFlags() { return m_flags; } - public bool HasFlag(T flag) { return Convert.ToBoolean(Convert.ToInt32(m_flags) & 1 << Convert.ToInt32(flag)); } - public void AddFlag(T flag) { m_flags |= (uint)(1 << Convert.ToInt32(flag)); } - public void DelFlag(T flag) { m_flags &= ~(uint)(1 << Convert.ToInt32(flag)); } + public bool HasFlag(T flag) { return (m_flags & 1 << Convert.ToInt32(flag)) != 0; } + public void AddFlag(T flag) { m_flags |= (dynamic)(1 << Convert.ToInt32(flag)); } + public void DelFlag(T flag) { m_flags &= ~(dynamic)(1 << Convert.ToInt32(flag)); } + + public int GetValue(T flag) { return m_values[Convert.ToInt32(flag)]; } + public void SetValue(T flag, object value) { m_values[Convert.ToInt32(flag)] = Convert.ToInt32(value); } + public void AddValue(T flag, object value) { m_values[Convert.ToInt32(flag)] += Convert.ToInt32(value); } + } + + public class FlaggedArray64 where T : struct + { + int[] m_values; + ulong m_flags; + + public FlaggedArray64(byte arraysize) + { + m_values = new int[4 * arraysize]; + } + + public ulong GetFlags() { return m_flags; } + public bool HasFlag(T flag) { return (m_flags & 1ul << Convert.ToInt32(flag)) != 0; } + public void AddFlag(T flag) { m_flags |= (dynamic)(1ul << Convert.ToInt32(flag)); } + public void DelFlag(T flag) { m_flags &= ~(dynamic)(1ul << Convert.ToInt32(flag)); } public int GetValue(T flag) { return m_values[Convert.ToInt32(flag)]; } public void SetValue(T flag, object value) { m_values[Convert.ToInt32(flag)] = Convert.ToInt32(value); } diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 0012319fa..ec6afe4d2 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -1271,7 +1271,7 @@ namespace Game.Entities bool CanDetectInvisibilityOf(WorldObject obj) { - uint mask = obj.m_invisibility.GetFlags() & m_invisibilityDetect.GetFlags(); + ulong mask = obj.m_invisibility.GetFlags() & m_invisibilityDetect.GetFlags(); // Check for not detected types if (mask != obj.m_invisibility.GetFlags()) @@ -1279,7 +1279,7 @@ namespace Game.Entities for (int i = 0; i < (int)InvisibilityType.Max; ++i) { - if (!Convert.ToBoolean(mask & (1 << i))) + if (!Convert.ToBoolean(mask & (1ul << i))) continue; int objInvisibilityValue = obj.m_invisibility.GetValue((InvisibilityType)i); @@ -3708,14 +3708,14 @@ namespace Game.Entities SmoothPhasing _smoothPhasing; - public FlaggedArray m_stealth = new(2); - public FlaggedArray m_stealthDetect = new(2); + public FlaggedArray32 m_stealth = new(2); + public FlaggedArray32 m_stealthDetect = new(2); - public FlaggedArray m_invisibility = new((int)InvisibilityType.Max); - public FlaggedArray m_invisibilityDetect = new((int)InvisibilityType.Max); + public FlaggedArray64 m_invisibility = new((int)InvisibilityType.Max); + public FlaggedArray64 m_invisibilityDetect = new((int)InvisibilityType.Max); - public FlaggedArray m_serverSideVisibility = new(2); - public FlaggedArray m_serverSideVisibilityDetect = new(2); + public FlaggedArray32 m_serverSideVisibility = new(2); + public FlaggedArray32 m_serverSideVisibilityDetect = new(2); #endregion public static implicit operator bool(WorldObject obj)