public static void RemoveUnused <T>(this Array16 <T> arr, uint id) { ushort[] unusedItems = (ushort[])arr.GetType().GetField("m_unusedItems", AccessTools.all).GetValue(arr); FieldInfo unusedCountField = arr.GetType().GetField("m_unusedCount", AccessTools.all); uint unusedCount = (uint)unusedCountField.GetValue(arr); uint expectedPos = (uint)id - 1; // Special case, when array was modified (search for the id) if (unusedItems[expectedPos] != id) { bool found = false; for (uint num = 0; num <= unusedCount; num++) { if (unusedItems[num] == id) { expectedPos = num; found = true; break; } } if (!found) { // The arrays are no longer in sync CSM.Log("Error: Received id already in use. Please restart the multiplayer session!"); return; } } unusedItems[expectedPos] = unusedItems[--unusedCount]; unusedCountField.SetValue(arr, unusedCount); }
public static void ResizeArray16 <T>(Array16 <T> array, ushort newSize) { array.m_size = newSize; Array.Resize(ref array.m_buffer, (int)newSize); var unusedCount = (uint)array.GetType().GetField("m_unusedCount").GetValue(array); var unusedItems = (ushort[])array.GetType().GetField("m_unusedItems").GetValue(array); ushort[] newUnusedItems = new ushort[newSize]; Buffer.BlockCopy(unusedItems, 0, newUnusedItems, 0, 4 * unusedItems.Length); // Now add our own unused items for (uint i = (uint)unusedItems.Length; i < newSize + 1; i++) { newUnusedItems[i - 1] = (ushort)i; } // Update the unusedCount to be in line with the new array size // This is just adding the newly sized additions. unusedCount += newSize - unusedCount; array.GetType().GetField("m_unusedCount").SetValue(array, unusedCount); array.GetType().GetField("m_unusedItems").SetValue(array, newUnusedItems); }