예제 #1
0
        public Floor Get(ulong id)
        {
            if (ById.ContainsKey((ushort)id))
            {
                return(ById[(ushort)id]);
            }
            else
            {
                //get from iff
                if (!Entries.ContainsKey((ushort)id))
                {
                    return(null);
                }
                Files.Formats.IFF.IffFile iff = this.Floors.Get(Entries[(ushort)id].FileName);
                if (iff == null)
                {
                    return(null);
                }

                var far    = iff.Get <SPR2>(1);
                var medium = iff.Get <SPR2>(257);
                var near   = iff.Get <SPR2>(513);

                ById[(ushort)id] = new Floor
                {
                    ID     = (ushort)id,
                    Near   = near,
                    Medium = medium,
                    Far    = far
                };
                return(ById[(ushort)id]);
            }
        }
예제 #2
0
        public Wall Get(ulong id, bool ts1)
        {
            if (ById.ContainsKey((ushort)id))
            {
                return(ById[(ushort)id]);
            }
            else
            {
                //get from iff
                Files.Formats.IFF.IffFile iff = this.Walls.Get(Entries[(ushort)id].FileName);
                if (iff == null)
                {
                    return(null);
                }

                var far    = iff.Get <SPR>(1);
                var medium = iff.Get <SPR>(1793);
                var near   = iff.Get <SPR>(2049);

                ById[(ushort)id] = new Wall
                {
                    ID     = (ushort)id,
                    Near   = near,
                    Medium = medium,
                    Far    = far
                };
                return(ById[(ushort)id]);
            }
        }
예제 #3
0
        public void SaveChange(Files.Formats.IFF.IffFile file)
        {
            lock (this)
            {
                if (file.RuntimeInfo.State == IffRuntimeState.Standalone)
                {
                    //just save out iff
                    var filename = file.RuntimeInfo.Path;
                    Directory.CreateDirectory(Path.GetDirectoryName(filename));
                    using (var stream = new FileStream(filename, FileMode.Create))
                        file.Write(stream);

                    foreach (var chunk in file.ListAll())
                    {
                        chunk.RuntimeInfo = ChunkRuntimeState.Normal;
                    }
                }
                else
                {
                    string dest = Path.Combine(FSOEnvironment.ContentDir, ((file.RuntimeInfo.State == IffRuntimeState.PIFFClone) ? "Objects/" : "Patch/User/"));
                    Directory.CreateDirectory(dest);
                    if (file.RuntimeInfo.State == IffRuntimeState.ReadOnly)
                    {
                        file.RuntimeInfo.State = IffRuntimeState.PIFFPatch;
                    }

                    var stringResources = new HashSet <Type> {
                        typeof(STR), typeof(CTSS), typeof(TTAs)
                    };
                    var sprites = (file.RuntimeInfo.UseCase == IffUseCase.ObjectSprites);
                    file.RuntimeInfo.Patches.Clear();

                    var piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, null, stringResources);

                    string name = file.Filename.Substring(0, file.Filename.Length - 4); //get without extension

                    if (piff != null)
                    {
                        var filename = dest + name + (sprites ? ".spf" : "") + ".piff";
                        using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream);
                        file.RuntimeInfo.Patches.Add(piff);
                    }

                    if (!sprites)
                    {
                        piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, stringResources, null);
                        if (piff != null)
                        {
                            var filename = dest + name + ".str.piff";
                            using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream);
                            file.RuntimeInfo.Patches.Add(piff);
                        }
                    }
                }

                file.RuntimeInfo.Dirty = false;
                ChangedFiles.Remove(file);
            }
        }
예제 #4
0
 public void DiscardChange(Files.Formats.IFF.IffFile file)
 {
     lock (this)
     {
         UnregisterObjects(file);
         file.Revert();
         ChangedFiles.Remove(file);
         RegisterObjects(file);
     }
 }
예제 #5
0
        public void RegisterObjects(Files.Formats.IFF.IffFile file)
        {
            var objRegistry = Content.Get().WorldObjects;
            var defs        = file.List <OBJD>();

            if (defs != null)
            {
                foreach (var def in defs)
                {
                    objRegistry.AddObject(file, def);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Gets a resource.
        /// </summary>
        /// <param name="filename">The filename of the resource to get.</param>
        /// <returns>A GameGlobal instance containing the resource.</returns>
        public GameGlobal Get(string filename)
        {
            string filepath;

            Files.Formats.IFF.IffFile iff = null;

            filename = filename.ToLowerInvariant();
            lock (Cache)
            {
                if (Cache.ContainsKey(filename))
                {
                    return(Cache[filename]);
                }


                filepath = Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".iff");

                //if we can't load this let it throw an exception...
                //probably sanity check this when we add user objects.
                if (File.Exists(filepath))
                {
                    iff = new Files.Formats.IFF.IffFile(filepath);
                }


                if (GlobalIffs != null)
                {
                    iff = this.GlobalIffs.Get(filename + ".iff");
                }

                OTFFile otf = null;
                try
                {
                    otf = new OTFFile(Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".otf"));
                }
                catch (IOException)
                {
                    //if we can't load an otf, it probably doesn't exist.
                }
                var resource = new GameGlobalResource(iff, otf);

                var item = new GameGlobal
                {
                    Resource = resource
                };

                Cache.Add(filename, item);

                return(item);
            }
        }
예제 #7
0
        public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline)
        {
            if (Sprites == null)
            {
                Sprites = new Files.Formats.IFF.IffFile(Content.Content.Get().GetPath("objectdata/globals/sprites.iff"));
                WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice);
            }

            if (Headline.Operand.Group != VMSetBalloonHeadlineOperandGroup.Algorithmic)
            {
                Sprite = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)Headline.Operand.Group] + Headline.Index));
            }

            if (Headline.Operand.Type != 255 && Headline.Operand.Type != 3)
            {
                BGSprite = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon] + Headline.Operand.Type));
            }

            LastZoom = WorldZoom.Near;
            RecalculateTarget();
        }
예제 #8
0
        /// <summary>
        /// Intializes a specific neighbourhood. Also counts as a save discard, since it unloads the current neighbourhood.
        /// </summary>
        /// <param name="id"></param>
        public void InitSpecific(int id)
        {
            DirtyAvatars.Clear();
            ZoningDictionary.Clear();
            FamilyForHouse.Clear();

            var udName = "UserData" + ((id == 0) ? "" : (id + 1).ToString());
            //simitone shouldn't modify existing ts1 data, since our house saves are incompatible.
            //therefore we should copy to the simitone user data.

            var userPath = FSOEnvironment.ContentDir;


            UserPath = userPath;

            MainResource = new Files.Formats.IFF.IffFile(Path.Combine(UserPath, "Neighborhood.iff"));

            Neighbors    = MainResource.List <NBRS>().FirstOrDefault();
            Neighborhood = MainResource.List <NGBH>().FirstOrDefault();


            //todo: manage avatar iffs here
        }
예제 #9
0
 public GameGlobalResource(Files.Formats.IFF.IffFile iff, OTFFile tuning)
 {
     this.Iff    = iff;
     this.Tuning = tuning;
 }
예제 #10
0
 public void IffChanged(Files.Formats.IFF.IffFile file)
 {
     file.RuntimeInfo.Dirty = true;
     lock (this) ChangedFiles.Add(file);
 }
예제 #11
0
        public GameObjectResource(Files.Formats.IFF.IffFile iff, Files.Formats.IFF.IffFile sprites, OTFFile tuning, string iname)
        {
            this.Iff     = iff;
            this.Sprites = sprites;
            this.Tuning  = tuning;
            this.Name    = iname;

            if (iff == null)
            {
                return;
            }
            var GLOBChunks = iff.List <GLOB>();

            if (GLOBChunks != null && GLOBChunks[0].Name != "")
            {
                var sg = FSO.Content.Content.Get().WorldObjectGlobals.Get(GLOBChunks[0].Name);
                if (sg != null)
                {
                    SemiGlobal = sg.Resource;             //used for tuning constant fetching.
                }
            }

            TreeByName = new Dictionary <string, VMTreeByNameTableEntry>();
            var bhavs = List <BHAV>();

            if (bhavs != null)
            {
                foreach (var bhav in bhavs)
                {
                    string name = bhav.ChunkLabel;
                    for (var i = 0; i < name.Length; i++)
                    {
                        if (name[i] == 0)
                        {
                            name = name.Substring(0, i);
                            break;
                        }
                    }
                    if (!TreeByName.ContainsKey(name))
                    {
                        TreeByName.Add(name, new VMTreeByNameTableEntry(bhav));
                    }
                }
            }
            //also add semiglobals

            if (SemiGlobal != null)
            {
                bhavs = SemiGlobal.List <BHAV>();
                if (bhavs != null)
                {
                    foreach (var bhav in bhavs)
                    {
                        string name = bhav.ChunkLabel;
                        for (var i = 0; i < name.Length; i++)
                        {
                            if (name[i] == 0)
                            {
                                name = name.Substring(0, i);
                                break;
                            }
                        }
                        if (!TreeByName.ContainsKey(name))
                        {
                            TreeByName.Add(name, new VMTreeByNameTableEntry(bhav));
                        }
                    }
                }
            }
        }
예제 #12
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]);
            }
        }
예제 #13
0
        /// <summary>
        /// Initiates loading of floors.
        /// </summary>
        public void Init()
        {
            this.Entries            = new Dictionary <ushort, FloorReference>();
            this.ById               = new Dictionary <ushort, Floor>();
            this.DynamicFloorFromID = new Dictionary <string, ushort>();

            var floorGlobalsPath = ContentManager.GetPath("objectdata/globals/floors.iff");
            var floorGlobals     = new Files.Formats.IFF.IffFile(floorGlobalsPath);

            FloorGlobals = floorGlobals;

            var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff");
            var buildGlobals     = new Files.Formats.IFF.IffFile(buildGlobalsPath); //todo: centralize?

            /** There is a small handful of floors in a global file for some reason **/
            ushort floorID   = 1;
            var    floorStrs = buildGlobals.Get <STR>(0x83);

            for (ushort i = 1; i < (floorStrs.Length / 3); i++)
            {
                var far    = floorGlobals.Get <SPR2>(i);
                var medium = floorGlobals.Get <SPR2>((ushort)(i + 256));
                var near   = floorGlobals.Get <SPR2>((ushort)(i + 512)); //2048 is water tile

                this.AddFloor(new Floor
                {
                    ID     = floorID,
                    Far    = far,
                    Medium = medium,
                    Near   = near
                });

                Entries.Add(floorID, new FloorReference(this)
                {
                    ID       = floorID,
                    FileName = "global",

                    Name        = floorStrs.GetString((i - 1) * 3 + 1),
                    Price       = int.Parse(floorStrs.GetString((i - 1) * 3 + 0)),
                    Description = floorStrs.GetString((i - 1) * 3 + 2)
                });

                floorID++;
            }

            var waterStrs = buildGlobals.Get <STR>(0x85);

            //add pools for catalog logic
            Entries.Add(65535, new FloorReference(this)
            {
                ID       = 65535,
                FileName = "global",

                Price       = int.Parse(waterStrs.GetString(0)),
                Name        = waterStrs.GetString(1),
                Description = waterStrs.GetString(2)
            });

            floorID = 256;

            var archives = new string[]
            {
                "housedata/floors/floors.far",
                "housedata/floors2/floors2.far",
                "housedata/floors3/floors3.far",
                "housedata/floors4/floors4.far"
            };

            for (var i = 0; i < archives.Length; i++)
            {
                var archivePath = ContentManager.GetPath(archives[i]);
                var archive     = new FAR1Archive(archivePath, true);
                var entries     = archive.GetAllEntries();

                foreach (var entry in entries)
                {
                    var iff = new Files.Formats.IFF.IffFile();
                    DynamicFloorFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).ToLowerInvariant()] = floorID;
                    var bytes = archive.GetEntry(entry);
                    using (var stream = new MemoryStream(bytes))
                    {
                        iff.Read(stream);
                    }


                    var catStrings = iff.Get <STR>(0);

                    Entries.Add(floorID, new FloorReference(this)
                    {
                        ID       = floorID,
                        FileName = entry.Key,

                        Name        = catStrings.GetString(0),
                        Price       = int.Parse(catStrings.GetString(1)),
                        Description = catStrings.GetString(2)
                    });

                    floorID++;
                }
                archive.Close();
            }

            NumFloors   = floorID;
            this.Floors = new FAR1Provider <Files.Formats.IFF.IffFile>(ContentManager, new IffCodec(), new Regex(".*/floors.*\\.far"));
            Floors.Init();
        }
예제 #14
0
        public Blueprint LoadFromIff(Files.Formats.IFF.IffFile iff)
        {
            var simi = iff.Get <SIMI>(1);
            var hous = iff.Get <HOUS>(0);

            short size = simi.GlobalData[23];
            var   type = simi.GlobalData[35]; //ts1 lots are 64x64... but we convert them into dynamic size.

            //if (VM.UseWorld)
            this.Blueprint = new Blueprint(size, size);
            //VM.Entities = new List<VMEntity>();
            //VM.Context = new VMContext(VM.Context.World);
            //VM.Context.VM = VM;
            VM.Context.Blueprint    = Blueprint;
            VM.Context.Architecture = new VMArchitecture(size, size, Blueprint, VM.Context);

            FlipRoad = (hous.CameraDir & 1) > 0;

            VM.GlobalState = simi.GlobalData;

            VM.GlobalState[20] = 255; //Game Edition. Basically, what "expansion packs" are running. Let's just say all of them.
            VM.GlobalState[25] = 4;   //as seen in EA-Land edith's simulator globals, this needs to be set for people to do their idle interactions.
            VM.GlobalState[17] = 4;   //Runtime Code Version, is this in EA-Land.

            VM.SetGlobalValue(10, 1); //set house number
            VM.SetGlobalValue(32, 0); //simless build mode
            VM.Context.Clock.Hours           = VM.GlobalState[0];
            VM.Context.Clock.DayOfMonth      = VM.GlobalState[1];
            VM.Context.Clock.Minutes         = VM.GlobalState[5];
            VM.Context.Clock.MinuteFractions = (VM.GlobalState[6] * VM.Context.Clock.TicksPerMinute);
            VM.Context.Clock.Month           = VM.GlobalState[7];
            VM.Context.Clock.Year            = VM.GlobalState[8];


            var floorM = iff.Get <FLRm>(1)?.Entries ?? iff.Get <FLRm>(0)?.Entries ?? new List <WALmEntry>();
            var wallM  = iff.Get <WALm>(1)?.Entries ?? iff.Get <WALm>(0)?.Entries ?? new List <WALmEntry>();

            var floorDict = BuildFloorDict(floorM);
            var wallDict  = BuildWallDict(wallM);

            var arch = VM.Context.Architecture;
            //altitude as 0
            var advFloors = iff.Get <ARRY>(11);
            var flags     = iff.Get <ARRY>(8).TransposeData;

            if (advFloors != null)
            {
                //advanced walls and floors from modern ts1. use 16 bit wall/floor data.
                arch.Floors[0] = RemapFloors(DecodeAdvFloors(advFloors.TransposeData), floorDict, flags);
                arch.Floors[1] = RemapFloors(DecodeAdvFloors(iff.Get <ARRY>(111).TransposeData), floorDict, flags);
                //objects as 3
                arch.Walls[0] = RemapWalls(DecodeAdvWalls(iff.Get <ARRY>(12).TransposeData), wallDict, floorDict);
                arch.Walls[1] = RemapWalls(DecodeAdvWalls(iff.Get <ARRY>(112).TransposeData), wallDict, floorDict);
            }
            else
            {
                arch.Floors[0] = RemapFloors(DecodeFloors(iff.Get <ARRY>(1).TransposeData), floorDict, flags);
                arch.Floors[1] = RemapFloors(DecodeFloors(iff.Get <ARRY>(101).TransposeData), floorDict, flags);
                //objects as 3
                arch.Walls[0] = RemapWalls(DecodeWalls(iff.Get <ARRY>(2).TransposeData), wallDict, floorDict);
                arch.Walls[1] = RemapWalls(DecodeWalls(iff.Get <ARRY>(102).TransposeData), wallDict, floorDict);
            }
            //objects as 103
            //Blueprint.Terrain.GrassState = iff.Get<ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray();
            //Blueprint.Terrain.DarkType = Content.Model.TerrainType.SAND;
            //arch.Terrain.LightType = Content.Model.TerrainType.GRASS;
            arch.SignalRedraw();
            //targetgrass is 7
            //flags is 8/108
            var pools = iff.Get <ARRY>(9).TransposeData;
            var water = iff.Get <ARRY>(10).TransposeData;

            for (int i = 0; i < pools.Length; i++)
            {
                //pools in freeso are slightly different
                if (pools[i] != 0xff && pools[i] != 0x0)
                {
                    arch.Floors[0][i].Pattern = 65535;
                }
                if (water[i] != 0xff && water[i] != 0x0)
                {
                    arch.Floors[0][i].Pattern = 65534;
                }
            }

            arch.Floors[0] = ResizeFloors(arch.Floors[0], size);
            arch.Floors[1] = ResizeFloors(arch.Floors[1], size);
            arch.Walls[0]  = ResizeWalls(arch.Walls[0], size);
            arch.Walls[1]  = ResizeWalls(arch.Walls[1], size);
            //arch.FineBuildableArea = ResizeFlags(flags, size);
            //arch.Terrain.GrassState = ResizeGrass(arch.Terrain.GrassState, size);
            //arch.Terrain.Heights = Array.ConvertAll(ResizeGrass(DecodeHeights(iff.Get<ARRY>(0).TransposeData), size), x => (short)(x * 10));
            //arch.Terrain.RegenerateCenters();
            arch.RoofStyle = (uint)Content.Content.Get().WorldRoofs.NameToID(hous.RoofName.ToLowerInvariant() + ".bmp");

            if (VM.UseWorld)
            {
                World.State.WorldSize = size;
                Blueprint.Terrain     = CreateTerrain(size);
                //Blueprint.Altitude = arch.Terrain.Heights;
                //Blueprint.FineArea = arch.FineBuildableArea;
            }

            arch.RegenWallsAt();

            arch.RegenRoomMap();
            VM.Context.RegeneratePortalInfo();


            var objm = iff.Get <OBJM>(1);

            var objt = iff.Get <OBJT>(0);
            int j    = 0;

            for (int i = 0; i < objm.IDToOBJT.Length; i += 2)
            {
                if (objm.IDToOBJT[i] == 0)
                {
                    continue;
                }
                MappedObject target;
                if (!objm.ObjectData.TryGetValue(objm.IDToOBJT[i], out target))
                {
                    continue;
                }
                var entry = objt.Entries[objm.IDToOBJT[i + 1] - 1];
                target.Name = entry.Name;
                target.GUID = entry.GUID;

                //Console.WriteLine((objm.IDToOBJT[i]) + ": " + objt.Entries[objm.IDToOBJT[i + 1] - 1].Name);
            }

            var objFlrs = new ushort[][] { DecodeObjID(iff.Get <ARRY>(3)?.TransposeData), DecodeObjID(iff.Get <ARRY>(103)?.TransposeData) };

            for (int flr = 0; flr < 2; flr++)
            {
                var objs = objFlrs[flr];
                if (objs == null)
                {
                    continue;
                }
                for (int i = 0; i < objs.Length; i++)
                {
                    var obj = objs[i];
                    if (obj != 0)
                    {
                        var          x = i % 64;
                        var          y = i / 64;
                        MappedObject targ;
                        if (!objm.ObjectData.TryGetValue(obj, out targ))
                        {
                            continue;
                        }
                        targ.ArryX     = x;
                        targ.ArryY     = y;
                        targ.ArryLevel = flr + 1;
                    }
                }
            }

            var content = Content.Content.Get();

            foreach (var controller in ControllerObjects)
            {
                VM.Context.CreateObjectInstance(controller, LotTilePos.OUT_OF_WORLD, Direction.NORTH, false);
            }
            var ents = new List <Tuple <VMEntity, OBJM.MappedObject> >();

            foreach (var obj in objm.ObjectData.Values)
            {
                if (ControllerObjects.Contains(obj.GUID))
                {
                    continue;
                }
                var res = content.WorldObjects.Get(obj.GUID, false);
                if (res == null)
                {
                    continue;              //failed to load this object
                }
                var objd = res.OBJ;
                if (res.OBJ.MasterID != 0)
                {
                    var allObjs = res.Resource.List <OBJD>().Where(x => x.MasterID == res.OBJ.MasterID);
                    var hasLead = allObjs.Any(x => x.MyLeadObject != 0);
                    if ((hasLead && res.OBJ.MyLeadObject != 0) || (!hasLead && res.OBJ.SubIndex == 0))
                    {
                        //this is the object
                        //look for its master

                        //multitile object.. find master objd

                        var master = allObjs.FirstOrDefault(x => x.SubIndex < 0);
                        if (master == null)
                        {
                            continue;
                        }
                        objd     = master;
                        obj.GUID = master.GUID;
                    }
                    else
                    {
                        continue;
                    }
                }

                //if (DeleteAvatars && objd.ObjectType == OBJDType.Person) continue;

                //objm parent positioning
                //objects without positions inherit position from the objects in their "parent id".
                MappedObject src = obj;
                while (src != null && src.ParentID != 0)
                {
                    if (objm.ObjectData.TryGetValue(src.ParentID, out src))
                    {
                        if (src.ParentID == 0)
                        {
                            obj.ArryX     = src.ArryX;
                            obj.ArryY     = src.ArryY;
                            obj.ArryLevel = src.ArryLevel;
                        }
                    }
                }

                LotTilePos pos  = LotTilePos.OUT_OF_WORLD;
                var        dir  = (Direction)(1 << obj.Direction);
                var        nobj = VM.Context.CreateObjectInstance(obj.GUID, pos, dir, true);


                if (nobj.Objects.Count == 0)
                {
                    continue;
                }
                if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0)
                {
                    nobj.BaseObject.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context);
                }

                ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj.BaseObject, obj));
            }

            //place objects in slots
            foreach (var ent in ents)
            {
                var obj = ent.Item2;
                if (ent.Item1.Position == LotTilePos.OUT_OF_WORLD && obj.ContainerID != 0 && obj.ArryX != 0 && obj.ArryY != 0)
                {
                    var dir = (Direction)(1 << obj.Direction);
                    ent.Item1.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context);

                    /*
                     * var target = ents.First(x => x.Item2.ObjectID == obj.ContainerID);
                     * target.Item1.PlaceInSlot(ent.Item1, obj.ContainerSlot, true, VM.Context);
                     */
                }
            }

            var entClone = new List <VMEntity>(VM.Entities);

            foreach (var nobj in entClone)
            {
                nobj.ExecuteEntryPoint(11, VM.Context, true);
            }

            arch.SignalRedraw();
            VM.Context.World?.InitBlueprint(Blueprint);
            arch.Tick();


            return(Blueprint);
        }
예제 #15
0
        /// <summary>
        /// Initiates loading of walls.
        /// </summary>
        public void Init()
        {
            WallStyleToIndex = WallStyleIDs.ToDictionary(x => x, x => Array.IndexOf(WallStyleIDs, x));

            this.Entries           = new Dictionary <ushort, WallReference>();
            this.ById              = new Dictionary <ushort, Wall>();
            this.DynamicWallFromID = new Dictionary <string, ushort>();
            this.StyleById         = new Dictionary <ushort, WallStyle>();
            this.WallStyles        = new List <WallStyle>();

            var wallGlobalsPath = ContentManager.GetPath("objectdata/globals/walls.iff");

            WallGlobals = new Files.Formats.IFF.IffFile(wallGlobalsPath);

            var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff");
            var buildGlobals     = new Files.Formats.IFF.IffFile(buildGlobalsPath); //todo: centralize?

            /** Get wall styles from globals file **/
            var    styleStrs = buildGlobals.Get <STR>(0x81);
            ushort wallID    = 1;

            for (ushort i = 2; i < 512; i += 2)
            {
                var far    = WallGlobals.Get <SPR>((ushort)(i));
                var medium = WallGlobals.Get <SPR>((ushort)(i + 512));
                var near   = WallGlobals.Get <SPR>((ushort)(i + 1024));

                var fard    = WallGlobals.Get <SPR>((ushort)(i + 1));
                var mediumd = WallGlobals.Get <SPR>((ushort)(i + 513));
                var neard   = WallGlobals.Get <SPR>((ushort)(i + 1025));

                if (fard == null)
                { //no walls down, just render exactly the same
                    fard    = far;
                    mediumd = medium;
                    neard   = near;
                }

                string name = null, description = null;
                int    price    = -1;
                int    buyIndex = -1;
                WallStyleToIndex.TryGetValue(wallID, out buyIndex);

                if (buyIndex != -1)
                {
                    price       = int.Parse(styleStrs.GetString(buyIndex * 3));
                    name        = styleStrs.GetString(buyIndex * 3 + 1);
                    description = styleStrs.GetString(buyIndex * 3 + 2);
                }

                this.AddWallStyle(new WallStyle
                {
                    ID              = wallID,
                    WallsUpFar      = far,
                    WallsUpMedium   = medium,
                    WallsUpNear     = near,
                    WallsDownFar    = fard,
                    WallsDownMedium = mediumd,
                    WallsDownNear   = neard,

                    Price       = price,
                    Name        = name,
                    Description = description
                });

                wallID++;
            }

            DynamicStyleID = 256; //styles loaded from objects start at 256. The objd reference is dynamically altered to reference this new id,
            //so only refresh wall cache at same time as obj cache! (do this on lot unload)

            /** Get wall patterns from globals file **/
            var wallStrs = buildGlobals.Get <STR>(0x83);

            wallID = 0;
            for (ushort i = 0; i < 256; i++)
            {
                var far    = WallGlobals.Get <SPR>((ushort)(i + 1536));
                var medium = WallGlobals.Get <SPR>((ushort)(i + 1536 + 256));
                var near   = WallGlobals.Get <SPR>((ushort)(i + 1536 + 512));

                this.AddWall(new Wall
                {
                    ID     = wallID,
                    Far    = far,
                    Medium = medium,
                    Near   = near,
                });

                if (i > 0 && i < (wallStrs.Length / 3) + 1)
                {
                    Entries.Add(wallID, new WallReference(this)
                    {
                        ID       = wallID,
                        FileName = "global",

                        Name        = wallStrs.GetString((i - 1) * 3 + 1),
                        Price       = int.Parse(wallStrs.GetString((i - 1) * 3 + 0)),
                        Description = wallStrs.GetString((i - 1) * 3 + 2)
                    });
                }

                wallID++;
            }

            Junctions = new Wall
            {
                ID     = wallID,
                Far    = WallGlobals.Get <SPR>(4096),
                Medium = WallGlobals.Get <SPR>(4097),
                Near   = WallGlobals.Get <SPR>(4098),
            };

            wallID = 256;

            var archives = new string[]
            {
                "housedata/walls/walls.far",
                "housedata/walls2/walls2.far",
                "housedata/walls3/walls3.far",
                "housedata/walls4/walls4.far"
            };

            for (var i = 0; i < archives.Length; i++)
            {
                var archivePath = ContentManager.GetPath(archives[i]);
                var archive     = new FAR1Archive(archivePath, true);
                var entries     = archive.GetAllEntries();

                foreach (var entry in entries)
                {
                    var iff = new Files.Formats.IFF.IffFile();
                    DynamicWallFromID[Path.GetFileNameWithoutExtension(entry.ToString().Replace('\\', '/')).ToLowerInvariant()] = wallID;
                    var bytes = archive.GetEntry(entry);
                    using (var stream = new MemoryStream(bytes))
                    {
                        iff.Read(stream);
                    }

                    var catStrings = iff.Get <STR>(0);

                    Entries.Add(wallID, new WallReference(this)
                    {
                        ID       = wallID,
                        FileName = entry.Key,

                        Name        = catStrings.GetString(0),
                        Price       = int.Parse(catStrings.GetString(1)),
                        Description = catStrings.GetString(2)
                    });

                    wallID++;
                }
                archive.Close();
            }

            this.Walls = new FAR1Provider <Files.Formats.IFF.IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far"));
            Walls.Init();
            NumWalls = wallID;
        }
예제 #16
0
        /// <summary>
        /// Gets a resource.
        /// </summary>
        /// <param name="filename">The filename of the resource to get.</param>
        /// <returns>A GameGlobal instance containing the resource.</returns>
        public GameGlobal Get(string filename, bool ts1)
        {
            string filepath;

            Files.Formats.IFF.IffFile iff = null;

            filename = filename.ToLowerInvariant();
            lock (Cache)
            {
                if (Cache.ContainsKey(filename))
                {
                    return(Cache[filename]);
                }

                if (!ts1)
                {
                    filepath = Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".iff");

                    //if we can't load this let it throw an exception...
                    //probably sanity check this when we add user objects.
                    if (File.Exists(filepath))
                    {
                        iff = new Files.Formats.IFF.IffFile(filepath);
                    }
                }


                if (GlobalFar != null && iff == null)
                {
                    var Giff = new IffFile();

                    var bytes = GlobalFar.GetEntry(GlobalFar.GetAllEntries().FirstOrDefault(x => x.Key.ToLowerInvariant() == (filename + ".iff").ToLowerInvariant()));
                    using (var stream = new MemoryStream(bytes))
                    {
                        Giff.Read(stream);
                    }

                    if (Giff != null)
                    {
                        iff = Giff;
                    }
                }


                OTFFile otf = null;
                try
                {
                    otf = new OTFFile(Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".otf"));
                }
                catch (IOException)
                {
                    //if we can't load an otf, it probably doesn't exist.
                }
                var resource = new GameGlobalResource(iff, otf);

                var item = new GameGlobal
                {
                    Resource = resource
                };

                Cache.Add(filename, item);

                return(item);
            }
        }