Пример #1
0
        public Floor Get(ulong id, bool ts1)
        {
            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)
        {
            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 Texture2D GetFloorThumb(ushort id, GraphicsDevice device)
 {
     if (id < 256)
     {
         return(TextureUtils.Copy(device, ById[id].Near.Frames[0].GetTexture(device)));
     }
     else if (id == 65535)
     {
         return(TextureUtils.Copy(device, FloorGlobals.Get <SPR2>(0x420).Frames[0].GetTexture(device)));
     }
     else
     {
         return(this.Floors.ThrowawayGet(Entries[(ushort)id].FileName).Get <SPR2>(513).Frames[0].GetTexture(device));
     }
 }
Пример #4
0
        public Tuple <string, string> GetHouseNameDesc(int houseID)
        {
            STR res;

            if (houseID < 80)
            {
                res = NeighbourhoodDesc.Get <STR>((ushort)(houseID + 2000));
            }
            else if (houseID < 90)
            {
                res = STDesc.Get <STR>((ushort)(houseID + 2000));
            }
            else
            {
                res = MTDesc.Get <STR>((ushort)(houseID + 2000));
            }

            if (res == null)
            {
                return(new Tuple <string, string>("", ""));
            }
            else
            {
                return(new Tuple <string, string>(res.GetString(0), res.GetString(1)));
            }
        }
Пример #5
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();
        }
Пример #6
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();
        }
Пример #7
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);
        }
Пример #8
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;
        }
Пример #9
0
 public BMP GetWallStyleIcon(ushort id)
 {
     return(WallGlobals.Get <BMP>(id));
 }