using System.Runtime.InteropServices; using FFXIVClientStructs.FFXIV.Client.Graphics; namespace XivCommon.Functions.NamePlates; [StructLayout(LayoutKind.Explicit, Size = 0x28)] internal unsafe struct NumberArrayData { [FieldOffset(0x0)] public AtkArrayData AtkArrayData; [FieldOffset(0x20)] public int* IntArray; public void SetValue(int index, int value) { if (index >= this.AtkArrayData.Size) { return; } if (this.IntArray[index] == value) { return; } this.IntArray[index] = value; this.AtkArrayData.HasModifiedData = 1; } } [StructLayout(LayoutKind.Explicit, Size = 0x20)] internal unsafe struct AtkArrayData { [FieldOffset(0x0)] public void* vtbl; [FieldOffset(0x8)] public int Size; [FieldOffset(0x1C)] public byte Unk1C; [FieldOffset(0x1D)] public byte Unk1D; [FieldOffset(0x1E)] public byte HasModifiedData; [FieldOffset(0x1F)] public byte Unk1F; // initialized to -1 } [StructLayout(LayoutKind.Explicit, Size = 0x30)] internal unsafe struct StringArrayData { [FieldOffset(0x0)] public AtkArrayData AtkArrayData; [FieldOffset(0x20)] public byte** StringArray; // char * * [FieldOffset(0x28)] public byte* UnkString; // char * } /// /// The various different name plate types /// public enum PlateType { /// /// A normal player name plate /// Player = 0, /// /// A name plate with the icon and FC tag removed /// NoIconOrFc = 1, // 2, 5 /// /// A name plate with a level string visible, title always below the name, and FC tag removed /// LevelNoFc = 3, // 4 /// /// A name plate with only the name visible /// NameOnly = 6, /// /// A name plate with only the level string and name visible /// LevelAndName = 7, /// /// A name plate where the title always appears below the name and the FC tag is removed /// LowTitleNoFc = 8, } /// /// A colour, represented in the RGBA format. /// public class RgbaColour { /// /// The red component of the colour. /// public byte R { get; set; } /// /// The green component of the colour. /// public byte G { get; set; } /// /// The blue component of the colour. /// public byte B { get; set; } /// /// The alpha component of the colour. /// public byte A { get; set; } = byte.MaxValue; /// /// Converts an unsigned integer into an RgbaColour. /// /// 32-bit integer representing an RGBA colour /// an RgbaColour equivalent to the integer representation public static implicit operator RgbaColour(uint rgba) { var r = (byte) ((rgba >> 24) & 0xFF); var g = (byte) ((rgba >> 16) & 0xFF); var b = (byte) ((rgba >> 8) & 0xFF); var a = (byte) (rgba & 0xFF); return new RgbaColour { R = r, G = g, B = b, A = a, }; } /// /// Converts an RgbaColour into an unsigned integer representation. /// /// an RgbaColour to convert /// 32-bit integer representing an RGBA colour public static implicit operator uint(RgbaColour rgba) { return (uint) ((rgba.R << 24) | (rgba.G << 16) | (rgba.B << 8) | rgba.A); } /// /// Converts a ByteColor into an RgbaColour. /// /// ByteColor /// equivalent RgbaColour public static implicit operator RgbaColour(ByteColor rgba) { return (uint) ((rgba.R << 24) | (rgba.G << 16) | (rgba.B << 8) | rgba.A); } /// /// Converts an RgbaColour into a ByteColor. /// /// RgbaColour /// equivalent ByteColour public static implicit operator ByteColor(RgbaColour rgba) { return new() { R = rgba.R, G = rgba.G, B = rgba.B, A = rgba.A, }; } }