예제 #1
0
        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]);
            }
        }
예제 #2
0
        /// <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
                }));
            }
        }