示例#1
0
        public Wall Get(ulong id)
        {
            if (ById.ContainsKey((ushort)id))
            {
                return(ById[(ushort)id]);
            }
            else
            {
                //get from 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]);
            }
        }
示例#2
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 if (id == 65534)
     {
         var spr = FloorGlobals.Get <SPR2>(0x800);
         if (!spr.SpritePreprocessed)
         {
             spr.ZAsAlpha           = true;
             spr.FloorCopy          = 2;
             spr.SpritePreprocessed = true;
         }
         return(TextureUtils.Copy(device, spr.Frames[0].GetTexture(device)));
     }
     else
     {
         return(this.Floors.ThrowawayGet(Entries[(ushort)id].FileName).Get <SPR2>(513).Frames[0].GetTexture(device));
     }
 }
示例#3
0
        public Wall Get(ulong id)
        {
            if (ById.ContainsKey((ushort)id))
            {
                return(ById[(ushort)id]);
            }
            else
            {
                //get from iff
                WallReference entry = null;
                if (!Entries.TryGetValue((ushort)id, out entry))
                {
                    entry = Entries.Values.First(x => x.ID > 255);
                }
                IffFile iff = this.Walls.Get(entry.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]);
            }
        }
        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);
                }
                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]);
            }
        }
 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));
     }
 }
        /// <summary>
        /// Initiates loading of walls.
        /// </summary>
        public void Init()
        {
            var wallGlobalsPath = ContentManager.GetPath("objectdata/globals/walls.iff");

            WallGlobals = new IffFile(wallGlobalsPath);

            var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff");

            BuildGlobals = new IffFile(buildGlobalsPath); //todo: centralize?

            InitGlobals();
            ushort 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 IffFile();
                    DynamicWallFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).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();
            }

            var far1 = new FAR1Provider <IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far"));

            far1.Init();
            Walls    = far1;
            NumWalls = wallID;
        }
示例#7
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)));
            }
        }
示例#8
0
        public TS1NeighborhoodProvider(Content contentManager)
        {
            ContentManager = contentManager;
            MainResource   = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/Neighborhood.iff"));
            LotLocations   = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/LotLocations.iff"));
            var lotZoning = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/LotZoning.iff"));

            var zones = lotZoning.Get <STR>(1);

            for (int i = 0; i < zones.Length; i++)
            {
                var split = zones.GetString(i).Split(',');
                ZoningDictionary[short.Parse(split[0])] = (short)((split[1] == " community") ? 1 : 0);
            }
            Neighbors    = MainResource.List <NBRS>().FirstOrDefault();
            Neighborhood = MainResource.List <NGBH>().FirstOrDefault();

            FamilyForHouse = new Dictionary <short, FAMI>();
            var families = MainResource.List <FAMI>();

            foreach (var fam in families)
            {
                FamilyForHouse[(short)fam.HouseNumber] = fam;
            }
        }
        public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline)
        {
            if (Sprites == null)
            {
                Sprites = new FSO.Files.Formats.IFF.IffFile(FSO.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();
        }
示例#10
0
        private void button6_Click(object sender, EventArgs e)
        {
            string current  = listBox3.SelectedItem.ToString();
            string userdata = comboBox1.SelectedItem.ToString();


            var iff = new IffFile(userdata + "/Houses" + current + ".iff");

            var simi = iff.Get <SIMI>(326);

            // int value = simi.ArchitectureValue();

            //int rooms = simi.Rooms();
        }
示例#11
0
        public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline)
        {
            if (Sprites == null)
            {
                var content = FSO.Content.Content.Get();
                Sprites = new FSO.Files.Formats.IFF.IffFile(
                    content.TS1?
                    Path.Combine(content.TS1BasePath, "GameData/Sprites.iff") :
                    content.GetPath("objectdata/globals/sprites.iff")
                    );
            }

            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;
        }
示例#12
0
        private void InitGlobals()
        {
            /** There is a small handful of floors in a global file for some reason **/
            ushort floorID   = 1;
            var    floorStrs = BuildGlobals.Get <STR>(0x82);

            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

                far.FloorCopy    = 1;
                medium.FloorCopy = 1;
                near.FloorCopy   = 1;

                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)
            });

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

                Price       = int.Parse(waterStrs.GetString(3)),
                Name        = waterStrs.GetString(4),
                Description = waterStrs.GetString(5)
            });


            floorID = 256;
        }
示例#13
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.StyleById  = new Dictionary <ushort, WallStyle>();
            this.WallStyles = new List <WallStyle>();

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

            WallGlobals = new IffFile(wallGlobalsPath);

            var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff");
            var buildGlobals     = new 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"
            };

            DynamicWallFromID = new Dictionary <string, ushort>();

            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 IffFile();
                    DynamicWallFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).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 <IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far"));
            Walls.Init();
            NumWalls = wallID;
        }
示例#14
0
 public FAMI GetFamily(ushort ID)
 {
     return(MainResource.Get <FAMI>(ID));
 }
示例#15
0
 public BMP GetWallStyleIcon(ushort id)
 {
     return(WallGlobals.Get <BMP>(id));
 }
示例#16
0
 public string GetVarScopeName(VMVariableScope scope)
 {
     return(Behaviour.Get <STR>(132).GetString((int)scope));
 }
示例#17
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 = Path.Combine(FSOEnvironment.UserDir, udName + "/");

            if (!Directory.Exists(userPath))
            {
                var source      = Path.Combine(ContentManager.TS1BasePath, udName + "/");
                var destination = userPath;

                //quick and dirty copy.

                foreach (string dirPath in Directory.GetDirectories(source, "*",
                                                                    SearchOption.AllDirectories))
                {
                    Directory.CreateDirectory(dirPath.Replace('\\', '/').Replace(source, destination));
                }

                foreach (string newPath in Directory.GetFiles(source, "*.*",
                                                              SearchOption.AllDirectories))
                {
                    File.Copy(newPath, newPath.Replace('\\', '/').Replace(source, destination), true);
                }
            }

            UserPath = userPath;

            MainResource = new IffFile(Path.Combine(UserPath, "Neighborhood.iff"));
            LotLocations = new IffFile(Path.Combine(UserPath, "LotLocations.iff"));
            var lotZoning = new IffFile(Path.Combine(UserPath, "LotZoning.iff"));

            StreetNames       = new IffFile(Path.Combine(UserPath, "StreetNames.iff"));
            NeighbourhoodDesc = new IffFile(Path.Combine(UserPath, "Houses/NeighborhoodDesc.iff"));
            STDesc            = new IffFile(Path.Combine(UserPath, "Houses/STDesc.iff"));
            MTDesc            = new IffFile(Path.Combine(UserPath, "Houses/MTDesc.iff"));

            var zones = lotZoning.Get <STR>(1);

            for (int i = 0; i < zones.Length; i++)
            {
                var split = zones.GetString(i).Split(',');
                ZoningDictionary[short.Parse(split[0])] = (short)((split[1] == " community") ? 1 : 0);
            }
            Neighbors      = MainResource.List <NBRS>().FirstOrDefault();
            Neighborhood   = MainResource.List <NGBH>().FirstOrDefault();
            TypeAttributes = MainResource.List <TATT>().FirstOrDefault();

            FamilyForHouse = new Dictionary <short, FAMI>();
            var families = MainResource.List <FAMI>();

            foreach (var fam in families)
            {
                FamilyForHouse[(short)fam.HouseNumber] = fam;
            }

            LoadCharacters(true);

            //todo: manage avatar iffs here
        }
        public override string GetBody(EditorScope scope)
        {
            var op     = (VMSetBalloonHeadlineOperand)Operand;
            var result = new StringBuilder();

            var content = Content.Content.Get();

            if (Sprites == null)
            {
                Sprites = new IffFile(content.TS1 ?
                                      Path.Combine(content.TS1BasePath, "GameData/Sprites.iff") :
                                      content.GetPath("objectdata/globals/sprites.iff"));
            }

            result.AppendLine((op.OfStackOBJ) ? "Set Headline of Stack Object" : "Set my Headline");
            if (op.Duration == 0)
            {
                result.Append("Clear Headline");
            }
            else
            {
                var balloon = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon] + op.Type));

                string iconName;
                if (op.Group == VMSetBalloonHeadlineOperandGroup.Algorithmic)
                {
                    if (op.Algorithmic < 2)
                    {
                        iconName = "Stack Object Icon";
                    }
                    else
                    {
                        iconName = "Object in Local[" + op.Algorithmic + "] Icon";
                    }
                }
                else
                {
                    var icon = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)op.Group] + op.Index));
                    iconName = icon?.ChunkLabel ?? op.Index.ToString();
                }

                if (op.Indexed)
                {
                    iconName += " + temp[0]";
                }
                result.AppendLine("Category " + op.Group.ToString() + ", Type " + iconName);
                result.AppendLine("Balloon Type " + balloon?.ChunkLabel ?? "none");
                result.Append("Duration " + op.Duration + ((op.DurationInLoops) ? " loops" : " ticks"));

                var    flagStr = new StringBuilder();
                string prepend = "";
                if (op.Crossed)
                {
                    flagStr.Append("Crossed"); prepend = ", ";
                }
                if (op.Backwards)
                {
                    flagStr.Append(prepend + "Backwards"); prepend = ", ";
                }
                if (op.Inactive)
                {
                    flagStr.Append(prepend + "Inactive"); prepend = ", ";
                }

                if (flagStr.Length != 0)
                {
                    result.Append("\r\n(");
                    result.Append(flagStr);
                    result.Append(")");
                }
            }

            return(result.ToString());
        }
示例#19
0
        public override Texture2D DrawFrame(World world)
        {
            if (!Inited)
            {
                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();
                Inited = true;
            }

            if (LastZoom != world.State.Zoom || Texture == null)
            {
                Invalidated = true;
                LastZoom    = world.State.Zoom;
                RecalculateTarget();
                if (Texture == null)
                {
                    return(null);
                }
            }
            var GD    = GameFacade.GraphicsDevice;
            var batch = GameFacade.Screens.SpriteBatch;

            if (DrawSkill)
            {
                ProcessSkill();
            }
            else if (Headline.Anim % 15 == 0 && Sprite != null && Sprite.Frames.Count > 3)
            {
                Invalidated = true;
            }

            if (Invalidated) //todo: logic for drawing skills less often
            {
                GD.SetRenderTarget(Texture);
                GD.Clear(Color.Transparent);
                batch.Begin();

                if (BGSprite != null)
                {
                    batch.Draw(BGSprite.Frames[ZoomFrame].GetTexture(GD), new Vector2(), Color.White);
                }

                Texture2D main   = null;
                Vector2   offset = new Vector2();
                if (Sprite != null)
                {
                    var animFrame = (Headline.Anim / 15) % (Sprite.Frames.Count / 3);
                    main   = Sprite.Frames[ZoomFrame + animFrame * 3].GetTexture(GD);
                    offset = new Vector2(0, 4);
                }
                else if (AlgTex != null)
                {
                    main   = AlgTex;
                    offset = new Vector2(0, -6);
                }
                offset /= ZoomToDiv[(int)LastZoom];

                if (main != null && Texture != null)
                {
                    batch.Draw(main, new Vector2(Texture.Width / 2 - main.Width / 2, Texture.Height / 2 - main.Height / 2) + offset, Color.White);
                }

                if (Headline.Operand.Crossed)
                {
                    Texture2D Cross = Sprites.Get <SPR>(0x67).Frames[ZoomFrame].GetTexture(GD);
                    batch.Draw(Cross, new Vector2(Texture.Width / 2 - Cross.Width / 2, Texture.Height / 2 - Cross.Height / 4), Color.White);
                }

                if (DrawSkill)
                {
                    batch.Draw(WhitePx, new Rectangle(88, 4, 71, 41), new Color(92, 92, 92));
                    var font = GameFacade.MainFont.GetNearest(14).Font;

                    Vector2 fontOrigin = font.MeasureString(SkillString) / 2;
                    batch.DrawString(font, SkillString, new Vector2(88 + 35, 15) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0);

                    fontOrigin = font.MeasureString(SpeedString) / 2;
                    batch.DrawString(font, SpeedString, new Vector2(88 + 35, 34) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0);
                }

                batch.End();
                GD.SetRenderTarget(null);
                Invalidated = false;
            }

            return(Texture);
        }
示例#20
0
        public Blueprint LoadFromIff(IffFile iff)
        {
            var size = 64; //ts1 lots are fixed size

            if (VM.UseWorld)
            {
                this.Blueprint = new Blueprint(size, size);
            }
            VM.Entities             = new List <VMEntity>();
            VM.Scheduler            = new Engine.VMScheduler(VM);
            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);

            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);

            if (advFloors != null)
            {
                //advanced walls and floors from modern ts1. use 16 bit wall/floor data.
                arch.Floors[0] = RemapFloors(DecodeAdvFloors(advFloors.TransposeData), floorDict);
                arch.Floors[1] = RemapFloors(DecodeAdvFloors(iff.Get <ARRY>(111).TransposeData), floorDict);
                //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);
                arch.Floors[1] = RemapFloors(DecodeFloors(iff.Get <ARRY>(101).TransposeData), floorDict);
                //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
            arch.Terrain.GrassState = iff.Get <ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray();
            //arch.Terrain.DarkType = Content.Model.TerrainType.SAND;
            //arch.Terrain.LightType = Content.Model.TerrainType.GRASS;
            arch.SignalTerrainRedraw();
            //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;
                }
            }

            if (VM.UseWorld)
            {
                World.State.WorldSize = size;
                Blueprint.Terrain     = CreateTerrain(size);
            }

            arch.RebuildWallsAt();

            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);
            }
            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);
                if (res == null)
                {
                    continue;              //failed to load this object
                }
                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;
                        }
                        obj.GUID = master.GUID;
                    }
                    else
                    {
                        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).BaseObject;
                if (nobj == null)
                {
                    continue;
                }
                if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0)
                {
                    nobj.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context, VMPlaceRequestFlags.AcceptSlots);
                }

                for (int i = 0; i < nobj.MultitileGroup.Objects.Count; i++)
                {
                    nobj.MultitileGroup.Objects[i].ExecuteEntryPoint(11, VM.Context, true);
                }

                ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj, 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, VMPlaceRequestFlags.AcceptSlots);

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

            arch.SignalTerrainRedraw();
            VM.Context.World?.InitBlueprint(Blueprint);
            arch.Tick();
            return(this.Blueprint);
        }
        /// <summary>
        /// Initiates loading of floors.
        /// </summary>
        public void Init()
        {
            this.Entries = new Dictionary <ushort, FloorReference>();
            this.ById    = new Dictionary <ushort, Floor>();

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

            FloorGlobals = floorGlobals;

            var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff");
            var buildGlobals     = new 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 IffFile();
                    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 <IffFile>(ContentManager, new IffCodec(), new Regex(".*/floors.*\\.far"));
            Floors.Init();
        }
示例#22
0
        private void InitGlobals()
        {
            /** 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 (far != null)
                {
                    near.WallStyle = true; medium.WallStyle = true; far.WallStyle = true;
                }

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

                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;
        }
示例#23
0
 public short GetJobData(ushort jobID, int jobLevel, int data)
 {
     return((short)(JobResource.Get <CARR>(jobID)?.GetJobData(jobLevel, data) ?? 0));
 }
示例#24
0
        public Blueprint LoadFromIff(IffFile iff)
        {
            var simi = iff.Get <SIMI>(1);
            var hous = iff.Get <HOUS>(0);

            Size = simi.GlobalData[23];
            var type = simi.GlobalData[35];
            var size = Size; //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.Scheduler = new Engine.VMScheduler(VM);
            VM.TS1State.SimulationInfo = simi;
            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, HouseNumber); //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];

            TerrainType ttype = TerrainType.GRASS;

            if (!HouseNumToType.TryGetValue(HouseNumber, out ttype))
            {
                ttype = TerrainType.GRASS;
            }
            VM.Context.Architecture.Terrain.LightType = (ttype == TerrainType.SAND) ? TerrainType.GRASS : ttype;
            VM.Context.Architecture.Terrain.DarkType  = ttype;

            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
            arch.Terrain.GrassState = iff.Get <ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray();
            //arch.Terrain.DarkType = Content.Model.TerrainType.SAND;
            //arch.Terrain.LightType = Content.Model.TerrainType.GRASS;
            arch.SignalTerrainRedraw();
            //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.GameContent.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.RebuildWallsAt();

            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;
                }
                if (!objm.ObjectData.TryGetValue(objm.IDToOBJT[i], out var 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;
                        if (!objm.ObjectData.TryGetValue(obj, out var targ))
                        {
                            continue;
                        }
                        targ.ArryX     = x;
                        targ.ArryY     = y;
                        targ.ArryLevel = flr + 1;
                    }
                }
            }

            var content = Content.GameContent.Get;

            foreach (var controller in ControllerObjects)
            {
                VM.Context.CreateObjectInstance(controller, LotTilePos.OUT_OF_WORLD, Direction.NORTH);
            }
            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);
                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).BaseObject;
                if (nobj == null)
                {
                    continue;
                }
                if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0)
                {
                    nobj.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context, VMPlaceRequestFlags.AcceptSlots);
                }

                ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj, 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, VMPlaceRequestFlags.AcceptSlots);

                    /*
                     * 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.SignalTerrainRedraw();
            VM.Context.World?.InitBlueprint(Blueprint);
            arch.Tick();
            return(this.Blueprint);
        }