public GameObject Get(ulong id) { if (Cache.ContainsKey(id)) { return(Cache[id]); } lock (Cache) { if (!Cache.ContainsKey(id)) { GameObjectReference reference; GameObjectResource resource = null; lock (Entries) { Entries.TryGetValue(id, out reference); if (reference == null) { //Console.WriteLine("Failed to get Object ID: " + id.ToString() + " (no resource)"); return(null); } lock (ProcessedFiles) { //if a file is processed but an object in it is not in the cache, it may have changed. //check for it again! ProcessedFiles.TryGetValue(reference.FileName, out resource); } } if (resource == null) { /** Better set this up! **/ Files.Formats.IFF.IffFile sprites = null, iff = null; OTFFile tuning = null; if (reference.Source == GameObjectSource.Far) { iff = this.Iffs.Get(reference.FileName + ".iff"); iff.RuntimeInfo.Path = reference.FileName; if (WithSprites) { if (reference.EpObject) { sprites = this.Sprites.Get(reference.FileName + ".iff"); } else { sprites = this.Sprites.Get(reference.FileName + ".spf"); } } tuning = this.TuningTables.Get(reference.FileName + ".otf"); } else { iff = new Files.Formats.IFF.IffFile(reference.FileName); iff.RuntimeInfo.Path = reference.FileName; iff.RuntimeInfo.State = IffRuntimeState.Standalone; } if (iff.RuntimeInfo.State == IffRuntimeState.PIFFPatch) { //OBJDs may have changed due to patch. Remove all file references ResetFile(iff); } iff.RuntimeInfo.UseCase = IffUseCase.Object; if (sprites != null) { sprites.RuntimeInfo.UseCase = IffUseCase.ObjectSprites; } resource = new GameObjectResource(iff, sprites, tuning, reference.FileName); lock (ProcessedFiles) { ProcessedFiles.GetOrAdd(reference.FileName, resource); } var piffModified = PIFFRegistry.GetOBJDRewriteNames(); foreach (var name in piffModified) { ProcessedFiles.GetOrAdd(name, GenerateResource(new GameObjectReference(this) { FileName = name.Substring(0, name.Length - 4), Source = GameObjectSource.Far })); } } foreach (var objd in resource.MainIff.List <OBJD>()) { var item = new GameObject { GUID = objd.GUID, OBJ = objd, Resource = resource }; Cache.GetOrAdd(item.GUID, item); } //0x3BAA9787 if (!Cache.ContainsKey(id)) { // Console.WriteLine("Failed to get Object ID: " + id.ToString() + " from resource " + resource.Name); return(null); } return(Cache[id]); } return(Cache[id]); } }
/// <summary> /// Initiates loading of world objects. /// </summary> public void Init(bool withSprites) { WithSprites = withSprites; Iffs = new FAR1Provider <IffFile>(ContentManager, new IffCodec(), "objectdata/objects/objiff.far"); TuningTables = new FAR1Provider <OTFFile>(ContentManager, new OTFCodec(), new Regex(".*/objotf.*\\.far")); Iffs.Init(); TuningTables.Init(); if (withSprites) { Sprites = new FAR1Provider <IffFile>(ContentManager, new IffCodec(), new Regex(".*/objspf.*\\.far")); Sprites.Init(); } /** Load packingslip **/ Entries = new Dictionary <ulong, GameObjectReference>(); Cache = new TimedReferenceCache <ulong, GameObject>(); var packingslip = new XmlDocument(); packingslip.Load(ContentManager.GetPath("packingslips/objecttable.xml")); var objectInfos = packingslip.GetElementsByTagName("I"); foreach (XmlNode objectInfo in objectInfos) { ulong FileID = Convert.ToUInt32(objectInfo.Attributes["g"].Value, 16); Entries.Add(FileID, new GameObjectReference(this) { ID = FileID, FileName = objectInfo.Attributes["n"].Value, Source = GameObjectSource.Far, Name = objectInfo.Attributes["o"].Value, Group = Convert.ToInt16(objectInfo.Attributes["m"].Value), SubIndex = Convert.ToInt16(objectInfo.Attributes["i"].Value) }); } //init local objects, piff clones //Directory.CreateDirectory(Path.Combine(FSOEnvironment.ContentDir, "Objects")); string[] paths = Directory.GetFiles(Path.Combine(FSOEnvironment.ContentDir, "Objects"), "*.iff", SearchOption.AllDirectories); for (int i = 0; i < paths.Length; i++) { string entry = paths[i]; string filename = Path.GetFileName(entry); IffFile iffFile = new IffFile(entry); var objs = iffFile.List <OBJD>(); if (objs == null) { continue; } foreach (var obj in objs) { Entries.Add(obj.GUID, new GameObjectReference(this) { ID = obj.GUID, FileName = entry, Source = GameObjectSource.Standalone, Name = obj.ChunkLabel, Group = (short)obj.MasterID, SubIndex = obj.SubIndex }); } } var piffModified = PIFFRegistry.GetOBJDRewriteNames(); foreach (var name in piffModified) { ProcessedFiles.GetOrAdd(name, GenerateResource(new GameObjectReference(this) { FileName = name.Substring(0, name.Length - 4), Source = GameObjectSource.Far })); } }