using SanAndreasUnity.Importing.Archive; using SanAndreasUnity.Importing.Items.Placements; using System.Collections.Generic; using System.IO; using System.Linq; namespace SanAndreasUnity.Importing.Items { public static class Item { private static readonly List _zones = new List(); private static readonly Dictionary _definitions = new Dictionary(); private static readonly Dictionary> _placements = new Dictionary>(); public static void ReadLoadList(string path) { var ws = new[] { ' ', '\t' }; using (var reader = File.OpenText(path)) { string line; while ((line = reader.ReadLine()) != null) { line = line.Trim(); if (line.Length == 0) continue; if (line.StartsWith("#")) continue; var index = line.IndexOfAny(ws); if (index == -1) continue; var type = line.Substring(0, index); var args = line.Substring(index).TrimStart(); args = args.Replace("DATA\\MAPS\\", "data/maps/"); args = args.Replace(".IDE", ".ide"); args = args.Replace(".IPL", ".ipl"); args = args.Replace('\\', Path.DirectorySeparatorChar); switch (type.ToLower()) { case "ide": ReadIde(args); break; case "ipl": ReadIpl(args); break; } } } } public static void ReadIde(string path) { var file = new ItemFile(ArchiveManager.GetPath(path)); foreach (var obj in file.GetItems().OfType()) { _definitions.Add(obj.Id, obj); } } public static void ReadIpl(string path) { var file = new ItemFile(ArchiveManager.GetPath(path)); foreach (var zone in file.GetSection("zone")) { _zones.Add(zone); } var insts = file.GetSection("inst"); var list = new List(); list.AddRange(insts); var cars = new List(file.GetSection("cars")); var streamFormat = Path.GetFileNameWithoutExtension(path).ToLower() + "_stream{0}.ipl"; var missed = 0; for (var i = 0; ; ++i) { var streamPath = string.Format(streamFormat, i); if (!ArchiveManager.FileExists(streamPath)) { ++missed; if (missed > 10) break; continue; } file = new ItemFile(ArchiveManager.ReadFile(streamPath)); list.AddRange(file.GetSection("inst")); cars.AddRange(file.GetSection("cars")); } list.ResolveLod(); var lastCell = -1; foreach (var inst in list) { var cell = inst.CellId & 0xff; if (lastCell != cell && !_placements.ContainsKey(lastCell = cell)) { _placements.Add(cell, new List()); } _placements[cell].Add(inst); } if (!_placements.ContainsKey(0)) { _placements.Add(0, new List()); } _placements[0].AddRange(cars.Cast()); } public static TDefinition GetDefinition(int id) where TDefinition : Definition, IObjectDefinition { return !_definitions.ContainsKey(id) ? null : (TDefinition)_definitions[id]; } public static IEnumerable GetDefinitions() where TDefinition : Definition { return _definitions.Values.OfType(); } public static int GetNumDefinitions() where TDefinition : Definition { return _definitions.Count (pair => pair.Value is TDefinition); } public static IEnumerable GetPlacements(params int[] cellIds) where TPlacement : Placement { return cellIds.SelectMany(x => _placements.ContainsKey(x) ? _placements[x].OfType() : Enumerable.Empty()); } } }