public static void Load() { Stopwatch stopwatch = Stopwatch.StartNew(); UOFilesOverrideMap.Instance.Load(); // need to load this first so that it manages can perform the file overrides if needed List <Task> tasks = new List <Task> { AnimationsLoader.Instance.Load(), AnimDataLoader.Instance.Load(), ArtLoader.Instance.Load(), MapLoader.Instance.Load(), ClilocLoader.Instance.Load(Settings.GlobalSettings.Language), GumpsLoader.Instance.Load(), FontsLoader.Instance.Load(), HuesLoader.Instance.Load(), TileDataLoader.Instance.Load(), MultiLoader.Instance.Load(), SkillsLoader.Instance.Load().ContinueWith(t => ProfessionLoader.Instance.Load()), TexmapsLoader.Instance.Load(), SpeechesLoader.Instance.Load(), LightsLoader.Instance.Load(), SoundsLoader.Instance.Load(), MultiMapLoader.Instance.Load() }; if (!Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(10))) { Log.Panic("Loading files timeout."); } Read_Art_def(); UOFileMul verdata = Verdata.File; bool useVerdata = Client.Version < ClientVersion.CV_500A || verdata != null && verdata.Length != 0 && Verdata.Patches.Length != 0; if (!Settings.GlobalSettings.UseVerdata && useVerdata) { Settings.GlobalSettings.UseVerdata = useVerdata; } Log.Trace($"Use verdata.mul: {(Settings.GlobalSettings.UseVerdata ? "Yes" : "No")}"); if (Settings.GlobalSettings.UseVerdata) { if (verdata != null && Verdata.Patches.Length != 0) { Log.Info(">> PATCHING WITH VERDATA.MUL"); for (int i = 0; i < Verdata.Patches.Length; i++) { ref UOFileIndex5D vh = ref Verdata.Patches[i]; Log.Info($">>> patching FileID: {vh.FileID} - BlockID: {vh.BlockID}"); if (vh.FileID == 0) { MapLoader.Instance.PatchMapBlock(vh.BlockID, vh.Position); } else if (vh.FileID == 2) { MapLoader.Instance.PatchStaticBlock(vh.BlockID, ((ulong)verdata.StartAddress.ToInt64() + vh.Position), vh.Length); } else if (vh.FileID == 4) { if (vh.BlockID < ArtLoader.Instance.Entries.Length) { ArtLoader.Instance.Entries[vh.BlockID] = new UOFileIndex ( verdata.StartAddress, (uint)verdata.Length, vh.Position, (int)vh.Length, 0 ); } } else if (vh.FileID == 12) { GumpsLoader.Instance.Entries[vh.BlockID] = new UOFileIndex ( verdata.StartAddress, (uint)verdata.Length, vh.Position, (int)vh.Length, 0, (short)(vh.GumpData >> 16), (short)(vh.GumpData & 0xFFFF) ); } else if (vh.FileID == 14 && vh.BlockID < MultiLoader.Instance.Count) { MultiLoader.Instance.Entries[vh.BlockID] = new UOFileIndex ( verdata.StartAddress, (uint)verdata.Length, vh.Position, (int)vh.Length, 0 ); } else if (vh.FileID == 16 && vh.BlockID < SkillsLoader.Instance.SkillsCount) { SkillEntry skill = SkillsLoader.Instance.Skills[(int)vh.BlockID]; if (skill != null) { unsafe { StackDataReader reader = new StackDataReader(new ReadOnlySpan <byte>((byte *)verdata.StartAddress, (int)verdata.Length)); skill.HasAction = reader.ReadUInt8() != 0; skill.Name = reader.ReadASCII((int)(vh.Length - 1)); reader.Release(); } } } else if (vh.FileID == 30) { verdata.Seek(0); verdata.Skip((int)vh.Position); if (vh.Length == 836) { int offset = (int)(vh.BlockID * 32); if (offset + 32 > TileDataLoader.Instance.LandData.Length) { continue; } verdata.ReadUInt(); for (int j = 0; j < 32; j++) { ulong flags; if (Client.Version < ClientVersion.CV_7090) { flags = verdata.ReadUInt(); } else { flags = verdata.ReadULong(); } TileDataLoader.Instance.LandData[offset + j] = new LandTiles(flags, verdata.ReadUShort(), verdata.ReadASCII(20)); } } else if (vh.Length == 1188) { int offset = (int)((vh.BlockID - 0x0200) * 32); if (offset + 32 > TileDataLoader.Instance.StaticData.Length) { continue; } verdata.ReadUInt(); for (int j = 0; j < 32; j++) { ulong flags; if (Client.Version < ClientVersion.CV_7090) { flags = verdata.ReadUInt(); } else { flags = verdata.ReadULong(); } TileDataLoader.Instance.StaticData[offset + j] = new StaticTiles ( flags, verdata.ReadByte(), verdata.ReadByte(), verdata.ReadInt(), verdata.ReadUShort(), verdata.ReadUShort(), verdata.ReadUShort(), verdata.ReadByte(), verdata.ReadASCII(20) ); } } } else if (vh.FileID == 32) { if (vh.BlockID < HuesLoader.Instance.HuesCount) { VerdataHuesGroup group = Marshal.PtrToStructure <VerdataHuesGroup>(verdata.StartAddress + (int)vh.Position); HuesGroup[] hues = HuesLoader.Instance.HuesRange; hues[vh.BlockID].Header = group.Header; for (int j = 0; j < 8; j++) { Array.Copy(group.Entries[j].ColorTable, hues[vh.BlockID].Entries[j].ColorTable, 32); } } } else if (vh.FileID != 5 && vh.FileID != 6) { Log.Warn($"Unused verdata block\tFileID: {vh.FileID}\tBlockID: {vh.BlockID}"); } } Log.Info("<< PATCHED."); } }