public static ClipboardBuffer Load(string filename)
        {
            using (var stream = new FileStream(filename, FileMode.Open))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int maxx = reader.ReadInt32();
                    int maxy = reader.ReadInt32();

                    var buffer = new ClipboardBuffer(new PointInt32(maxx, maxy));
                    buffer.Name = Path.GetFileNameWithoutExtension(filename);

                    for (int x = 0; x < buffer.Size.W; x++)
                    {
                        for (int y = 0; y < buffer.Size.H; y++)
                        {
                            var tile = new Tile();

                            tile.IsActive = reader.ReadBoolean();

                            if (tile.IsActive)
                            {
                                tile.Type = reader.ReadByte();
                                if (WorldSettings.Tiles[tile.Type].IsFramed)
                                    tile.Frame = new PointShort(reader.ReadInt16(), reader.ReadInt16());
                                else
                                    tile.Frame = new PointShort(-1, -1);
                            }

                            tile.IsLighted = reader.ReadBoolean();

                            if (reader.ReadBoolean())
                            {
                                tile.Wall = reader.ReadByte();
                            }

                            if (reader.ReadBoolean())
                            {
                                tile.Liquid = reader.ReadByte();
                                tile.IsLava = reader.ReadBoolean();
                            }

                            buffer.Tiles[x, y] = tile;
                        }
                    }

                    for (int chestIndex = 0; chestIndex < World.MaxChests; chestIndex++)
                    {
                        if (reader.ReadBoolean())
                        {
                            var chest = new Chest();
                            chest.Location = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                            for (int slot = 0; slot < Chest.MaxItems; slot++)
                            {
                                var item = new Item();
                                byte stackSize = reader.ReadByte();
                                if (stackSize > 0)
                                {
                                    string itemName = reader.ReadString();
                                    item.ItemName = itemName;
                                    item.StackSize = stackSize;
                                }
                                chest.Items.Add(item);
                            }

                            //Chests[chestIndex] = chest;
                            buffer.Chests.Add(chest);
                        }
                    }
                    for (int signIndex = 0; signIndex < World.MaxSigns; signIndex++)
                    {
                        if (reader.ReadBoolean())
                        {
                            string signText = reader.ReadString();
                            int x = reader.ReadInt32();
                            int y = reader.ReadInt32();
                            if (buffer.Tiles[x, y].IsActive && (buffer.Tiles[x, y].Type == 55 || buffer.Tiles[x, y].Type == 85))
                            // validate tile location
                            {
                                var sign = new Sign();
                                sign.Location = new PointInt32(x, y);
                                sign.Text = signText;

                                //Signs[signIndex] = sign;
                                buffer.Signs.Add(sign);
                            }
                        }
                    }

                    int checkx = reader.ReadInt32();
                    int checky = reader.ReadInt32();

                    if (checkx == maxx && checky == maxy)
                        return buffer;

                }
            }

            return null;
        }
 public ChestEditorPopup(Chest chest)
 {
     InitializeComponent();
     DataContext = chest.Items;
 }
        public void Load(string filename)
        {
            CanUseFileIO = false;
            string ext = Path.GetExtension(filename);
            if (!string.Equals(ext, ".wld", StringComparison.CurrentCultureIgnoreCase))
                throw new ApplicationException("Invalid file");

            ClearWorld();

            using (var stream = new FileStream(filename, FileMode.Open))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int version = reader.ReadInt32();
                    if (version > CompatableVersion)
                    {
                        // handle version
                    }
                    Header.FileVersion = version;
                    Header.FileName = filename;
                    Header.WorldName = reader.ReadString();
                    Header.WorldId = reader.ReadInt32();
                    Header.WorldBounds = new RectF(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(),
                                                   reader.ReadInt32());
                    int maxy = reader.ReadInt32();
                    int maxx = reader.ReadInt32();
                    Header.MaxTiles = new PointInt32(maxx, maxy);
                    ClearWorld();
                    Header.SpawnTile = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.WorldSurface = reader.ReadDouble();
                    Header.WorldRockLayer = reader.ReadDouble();
                    Header.Time = reader.ReadDouble();
                    Header.IsDayTime = reader.ReadBoolean();
                    Header.MoonPhase = reader.ReadInt32();
                    Header.IsBloodMoon = reader.ReadBoolean();
                    Header.DungeonEntrance = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.IsBossDowned1 = reader.ReadBoolean();
                    Header.IsBossDowned2 = reader.ReadBoolean();
                    Header.IsBossDowned3 = reader.ReadBoolean();
                    Header.IsShadowOrbSmashed = reader.ReadBoolean();
                    Header.IsSpawnMeteor = reader.ReadBoolean();
                    Header.ShadowOrbCount = reader.ReadByte();
                    Header.InvasionDelay = reader.ReadInt32();
                    Header.InvasionSize = reader.ReadInt32();
                    Header.InvasionType = reader.ReadInt32();
                    Header.InvasionX = reader.ReadDouble();

                    for (int x = 0; x < Header.MaxTiles.X; x++)
                    {
                        OnProgressChanged(this,
                                          new ProgressChangedEventArgs((int) ((double) x/Header.MaxTiles.X*100.0),
                                                                       "Loading Tiles"));

                        for (int y = 0; y < Header.MaxTiles.Y; y++)
                        {
                            var tile = new Tile();

                            tile.IsActive = reader.ReadBoolean();

                            if (tile.IsActive)
                            {
                                tile.Type = reader.ReadByte();
                                if (TileProperties.TileFrameImportant[tile.Type])
                                    tile.Frame = new PointShort(reader.ReadInt16(), reader.ReadInt16());
                                else
                                    tile.Frame = new PointShort(-1, -1);
                            }

                            tile.IsLighted = reader.ReadBoolean();

                            if (reader.ReadBoolean())
                            {
                                tile.Wall = reader.ReadByte();
                            }

                            if (reader.ReadBoolean())
                            {
                                tile.Liquid = reader.ReadByte();
                                tile.IsLava = reader.ReadBoolean();
                            }

                            Tiles[x, y] = tile;
                        }
                    }

                    for (int chestIndex = 0; chestIndex < MaxChests; chestIndex++)
                    {
                        OnProgressChanged(this,
                                          new ProgressChangedEventArgs((int) ((double) chestIndex/MaxChests*100.0),
                                                                       "Loading Chest Data"));

                        if (reader.ReadBoolean())
                        {
                            var chest = new Chest();
                            chest.Location = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                            for (int slot = 0; slot < Chest.MaxItems; slot++)
                            {
                                var item = new Item();
                                byte stackSize = reader.ReadByte();
                                if (stackSize > 0)
                                {
                                    string itemName = reader.ReadString();
                                    item.Name = itemName;
                                    item.StackSize = stackSize;
                                }
                                chest.Items.Add(item);
                            }

                            //Chests[chestIndex] = chest;
                            Chests.Add(chest);
                        }
                    }
                    for (int signIndex = 0; signIndex < MaxSigns; signIndex++)
                    {
                        OnProgressChanged(this,
                                          new ProgressChangedEventArgs((int) ((double) signIndex/MaxSigns*100.0),
                                                                       "Loading Sign Data"));

                        if (reader.ReadBoolean())
                        {
                            string signText = reader.ReadString();
                            int x = reader.ReadInt32();
                            int y = reader.ReadInt32();
                            if (Tiles[x, y].IsActive && (Tiles[x, y].Type == 55 || Tiles[x, y].Type == 85))
                                // validate tile location
                            {
                                var sign = new Sign();
                                sign.Location = new PointInt32(x, y);
                                sign.Text = signText;

                                //Signs[signIndex] = sign;
                                Signs.Add(sign);
                            }
                        }
                    }

                    bool isNpcActive = reader.ReadBoolean();
                    for (int npcIndex = 0; isNpcActive; npcIndex++)
                    {
                        OnProgressChanged(this, new ProgressChangedEventArgs(100, "Loading NPCs"));
                        var npc = new NPC();

                        npc.Name = reader.ReadString();
                        npc.Position = new PointFloat(reader.ReadSingle(), reader.ReadSingle());
                        npc.IsHomeless = reader.ReadBoolean();
                        npc.HomeTile = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                        //Npcs[npcIndex] = npc;
                        Npcs.Add(npc);
                        isNpcActive = reader.ReadBoolean();
                    }

                    if (Header.FileVersion > 7)
                    {
                        OnProgressChanged(this, new ProgressChangedEventArgs(100, "Checking format"));
                        bool test = reader.ReadBoolean();
                        string worldNameCheck = reader.ReadString();
                        int worldIdCheck = reader.ReadInt32();
                        if (!(test && string.Equals(worldNameCheck, Header.WorldName) && worldIdCheck == Header.WorldId))
                        {
                            // Test FAILED!
                            throw new ApplicationException("Invalid World File");
                        }
                    }

                    reader.Close();
                }
            }
            CanUseFileIO = true;
            OnProgressChanged(this, new ProgressChangedEventArgs(0, ""));
        }
示例#4
0
        public void Load(string filename)
        {
            string ext = Path.GetExtension(filename);
            if (!(string.Equals(ext, ".wld", StringComparison.CurrentCultureIgnoreCase) ||
                  string.Equals(ext, ".bak", StringComparison.CurrentCultureIgnoreCase) ||
                  string.Equals(ext, ".Tedit", StringComparison.CurrentCultureIgnoreCase)))
                throw new ApplicationException("Invalid file");

            IsUsingIo = true;
            IsValid = false;
            ClearWorld();

            using (var stream = new FileStream(filename, FileMode.Open))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int version = reader.ReadInt32();
                    if (version > CompatableVersion)
                    {
                        // handle version
                    }
                    Header.FileVersion = version;
                    Header.FileName = filename;
                    Header.WorldName = reader.ReadString();
                    Header.WorldId = reader.ReadInt32();

                    // WorldBounds (within the file) is measured in frame units (1/2 of a pixel), while MaxTiles is measured in tiles
                    // We force everything into whole tiles, and ditch the redundant MaxTiles
                    // (Also, WorldBounds actually uses W/H, so it is really -1 for right/bottom, in an inclusive-based XY system.)
                    Header.WorldBounds = new RectI(reader.ReadInt32(), reader.ReadInt32() - 1, reader.ReadInt32(), reader.ReadInt32() - 1)
                                       / new RectI(16, 16, new SizeInt32(16, 16));
                    reader.ReadInt32();  // max Y
                    reader.ReadInt32();  // max X
                    var wb = Header.WorldBounds;

                    ClearWorld();
                    Header.SpawnTile = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.WorldSurface = reader.ReadDouble();
                    Header.WorldRockLayer = reader.ReadDouble();
                    Header.Time = reader.ReadDouble();
                    Header.IsDayTime = reader.ReadBoolean();
                    Header.MoonPhase = reader.ReadInt32();
                    Header.IsBloodMoon = reader.ReadBoolean();
                    Header.DungeonEntrance = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.IsBossDowned1 = reader.ReadBoolean();
                    Header.IsBossDowned2 = reader.ReadBoolean();
                    Header.IsBossDowned3 = reader.ReadBoolean();
                    Header.IsShadowOrbSmashed = reader.ReadBoolean();
                    Header.IsSpawnMeteor = reader.ReadBoolean();
                    Header.ShadowOrbCount = reader.ReadByte();
                    Header.InvasionDelay = reader.ReadInt32();
                    Header.InvasionSize = reader.ReadInt32();
                    Header.InvasionType = reader.ReadInt32();
                    Header.InvasionX = reader.ReadDouble();

                    for (int x = wb.Left; x <= wb.Right; x++) {
                        OnProgressChanged(this, x, wb.Right, "Loading Tiles...");

                        for (int y = wb.Top; y <= wb.Bottom; y++) {
                            var tile = new Tile();

                            tile.IsActive = reader.ReadBoolean();

                            if (tile.IsActive)
                            {
                                tile.Type = reader.ReadByte();

                                if (WorldSettings.Tiles[tile.Type].IsFramed)
                                    tile.Frame = new PointShort(reader.ReadInt16(), reader.ReadInt16());
                                else
                                    tile.Frame = new PointShort(-1, -1);
                            }
                            tile.IsLighted = reader.ReadBoolean();
                            if (reader.ReadBoolean())
                            {
                                tile.Wall = reader.ReadByte();
                            }

                            if (reader.ReadBoolean())
                            {
                                tile.Liquid = reader.ReadByte();
                                tile.IsLava = reader.ReadBoolean();
                            }

                            Tiles[x, y] = tile;
                        }
                    }

                    for (int chestIndex = 0; chestIndex < MaxChests; chestIndex++)
                    {
                        OnProgressChanged(this, chestIndex, MaxChests, "Loading Chest Data...");

                        if (reader.ReadBoolean())
                        {
                            var chest = new Chest();
                            chest.Location = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                            for (int slot = 0; slot < Chest.MaxItems; slot++)
                            {
                                var item = new Item();
                                byte stackSize = reader.ReadByte();
                                if (stackSize > 0)
                                {
                                    string itemName = reader.ReadString();
                                    item.ItemName = itemName;
                                    item.StackSize = stackSize;
                                }
                                chest.Items.Add(item);
                            }

                            Chests.Add(chest);
                        }
                    }
                    for (int signIndex = 0; signIndex < MaxSigns; signIndex++)
                    {
                        OnProgressChanged(this, signIndex, MaxSigns, "Loading Sign Data...");

                        if (reader.ReadBoolean())
                        {
                            string signText = reader.ReadString();
                            int x = reader.ReadInt32();
                            int y = reader.ReadInt32();
                            if (Tiles[x, y].IsActive && (Tiles[x, y].Type == 55 || Tiles[x, y].Type == 85))
                            // validate tile location
                            {
                                var sign = new Sign();
                                sign.Location = new PointInt32(x, y);
                                sign.Text = signText;

                                Signs.Add(sign);
                            }
                        }
                    }

                    bool isNpcActive = reader.ReadBoolean();
                    for (int npcIndex = 0; isNpcActive; npcIndex++)
                    {
                        OnProgressChanged(this, npcIndex, MaxNpcs, "Loading NPCs...");
                        var npc = new NPC();

                        npc.Name = reader.ReadString();
                        npc.Position = new PointFloat(reader.ReadSingle(), reader.ReadSingle());
                        npc.IsHomeless = reader.ReadBoolean();
                        npc.HomeTile = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                        Npcs.Add(npc);
                        isNpcActive = reader.ReadBoolean();
                    }

                    if (Header.FileVersion > 7)
                    {
                        OnProgressChanged(this, 100, 100, "Checking format...");
                        bool test = reader.ReadBoolean();
                        string worldNameCheck = reader.ReadString();
                        int worldIdCheck = reader.ReadInt32();
                        if (!(test && string.Equals(worldNameCheck, Header.WorldName) && worldIdCheck == Header.WorldId))
                        {
                            // Test FAILED!
                            IsUsingIo = false;
                            reader.Close();
                            throw new ApplicationException("Invalid World File");
                        }
                    }

                    reader.Close();
                }
            }
            IsValid = true;
            IsUsingIo = false;
            IsSaved = true;
            OnProgressChanged(this, 100, 100, "Loading Complete.");
        }
示例#5
0
        public void Validate()
        {
            List<string> log = new List<string>();
            IsUsingIo = true;

            var wb = Header.WorldBounds;
            short[,] deadSpace = new short[wb.Width, wb.Height];
            for (int y = wb.Top; y <= wb.Bottom; y++) {
                OnProgressChanged(this, y, wb.Bottom, "Validating Tiles...");

                for (int x = wb.Left; x <= wb.Right; x++) {
                    // skip anything in the dead space
                    if (deadSpace[x,y] > 0)
                    {
                        x += deadSpace[x,y] - 1;
                        continue;
                    }

                    // TODO: Need Frames support //
                    // (All tiles have the size/placement properties, but this may change in the future...) //
                    var tile  = Tiles[x, y];
                    if (!tile.IsActive) continue;  // immediate short-circuit
                    var type  = tile.Type;
                    var prop  = WorldSettings.Tiles[type];
                    var place = prop.Placement;
                    if (prop.AttachesTo.Count > 0) continue;  // can't really handle these yet...

                    if (!ValidatePlacement(new PointInt32(x,y), prop.Size, place))  // validation found a problem
                    {
                        log.Add(string.Format("Tile [{2}] at [{0},{1}] must be placed on {3} {4}", x, y, prop.Name,
                            place.Has(FP.MustHaveAll) ? "all of:" : (place.IsSingular() ? "a" : "any of:"),
                            place.Remove(FP.MustHaveAll)));
                    }

                    // validate chest/sign/NPC entries exist
                    switch (type)
                    {
                        case 21:
                            // Validate Chest
                            if (GetChestAtTile(x, y) == null)
                            {
                                var c = new Chest(new PointInt32(x, y));
                                for (int i = 0; i < 20; i++)
                                    c.Items.Add(new Item(0, "[empty]"));

                                Chests.Add(c);

                                log.Add(string.Format("added empty chest content [{0},{1}]", x, y));
                            }
                            break;
                        case 55:
                        case 85:
                            // Validate Sign/Tombstone
                            if (GetSignAtTile(x, y) == null)
                            {
                                Signs.Add(new Sign("", new PointInt32(x, y)));
                                log.Add(string.Format("added blank sign text [{0},{1}]", x, y));
                            }

                    break;
                    }

                    // TODO: validate the frame exists completely //

                    // assuming the left-right scan, it should hit the top-left corner first
                    // thus, we skip around the rest of the frame for the x-axis

                    // y-axis is a little bit more difficult... (and it requires that x stay put for a bit)
                    if (prop.Size.Y > 1) {
                        for (int s = 1; s < prop.Size.Y; s++) { deadSpace[x,y+s] = prop.Size.X; }
                    }
                    if (prop.Size.X > 1) x += prop.Size.X - 1;
                }
            }

            var p = 0;
            OnProgressChanged(this, "Validating Chests...");
            foreach (var chest in Chests.ToList())
            {
                var loc = chest.Location;
                int locType = Tiles[loc.X, loc.Y].Type;

                if (locType != 21)
                {
                    Chests.Remove(chest);
                    log.Add(string.Format("removed missing chest {0}", loc));
                }
                OnProgressChanged(this, ++p, Chests.Count);
            }

            p = 0;
            OnProgressChanged(this, "Validating Signs...");
            foreach (var sign in Signs.ToList())
            {
                var loc = sign.Location;
                int locType = Tiles[loc.X, loc.Y].Type;

                if (locType != 55 && locType != 85)
                {
                    Signs.Remove(sign);
                    log.Add(string.Format("removed missing sign {0}", loc));
                }
                OnProgressChanged(this, ++p, Signs.Count);
            }

            foreach (NPC npc in Npcs)
            {
                // no validation yet...
                // (SS: Okay, this is now in the XML; just need to port that stuff over)
            }
            IsUsingIo = false;
            OnProgressChanged(this, 100, 100, "Validation Complete.");

            log.Add("FINISHED with Validation!");
            ErrorLogging.Log(string.Join(Environment.NewLine, log.ToArray()));
        }
 public ChestsContentsPopup(Chest chest)
 {
     InitializeComponent();
     this.DataContext = chest.Items;
 }
示例#7
0
        public void Load(string filename)
        {
            string ext = Path.GetExtension(filename);

            if (!(string.Equals(ext, ".wld", StringComparison.CurrentCultureIgnoreCase) ||
                  string.Equals(ext, ".bak", StringComparison.CurrentCultureIgnoreCase) ||
                  string.Equals(ext, ".Tedit", StringComparison.CurrentCultureIgnoreCase)))
            {
                throw new ApplicationException("Invalid file");
            }

            IsUsingIo = true;
            IsValid   = false;
            ClearWorld();

            using (var stream = new FileStream(filename, FileMode.Open))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int version = reader.ReadInt32();
                    if (version > CompatableVersion)
                    {
                        // handle version
                    }
                    Header.FileVersion = version;
                    Header.FileName    = filename;
                    Header.WorldName   = reader.ReadString();
                    Header.WorldId     = reader.ReadInt32();

                    // WorldBounds (within the file) is measured in frame units (1/2 of a pixel), while MaxTiles is measured in tiles
                    // We force everything into whole tiles, and ditch the redundant MaxTiles
                    // (Also, WorldBounds actually uses W/H, so it is really -1 for right/bottom, in an inclusive-based XY system.)
                    Header.WorldBounds = new RectI(reader.ReadInt32(), reader.ReadInt32() - 1, reader.ReadInt32(), reader.ReadInt32() - 1)
                                         / new RectI(16, 16, new SizeInt32(16, 16));
                    reader.ReadInt32();  // max Y
                    reader.ReadInt32();  // max X
                    var wb = Header.WorldBounds;

                    ClearWorld();
                    Header.SpawnTile          = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.WorldSurface       = reader.ReadDouble();
                    Header.WorldRockLayer     = reader.ReadDouble();
                    Header.Time               = reader.ReadDouble();
                    Header.IsDayTime          = reader.ReadBoolean();
                    Header.MoonPhase          = reader.ReadInt32();
                    Header.IsBloodMoon        = reader.ReadBoolean();
                    Header.DungeonEntrance    = new PointInt32(reader.ReadInt32(), reader.ReadInt32());
                    Header.IsBossDowned1      = reader.ReadBoolean();
                    Header.IsBossDowned2      = reader.ReadBoolean();
                    Header.IsBossDowned3      = reader.ReadBoolean();
                    Header.IsShadowOrbSmashed = reader.ReadBoolean();
                    Header.IsSpawnMeteor      = reader.ReadBoolean();
                    Header.ShadowOrbCount     = reader.ReadByte();
                    Header.InvasionDelay      = reader.ReadInt32();
                    Header.InvasionSize       = reader.ReadInt32();
                    Header.InvasionType       = reader.ReadInt32();
                    Header.InvasionX          = reader.ReadDouble();

                    for (int x = wb.Left; x <= wb.Right; x++)
                    {
                        OnProgressChanged(this, x, wb.Right, "Loading Tiles...");

                        for (int y = wb.Top; y <= wb.Bottom; y++)
                        {
                            var tile = new Tile();

                            tile.IsActive = reader.ReadBoolean();

                            if (tile.IsActive)
                            {
                                tile.Type = reader.ReadByte();

                                if (WorldSettings.Tiles[tile.Type].IsFramed)
                                {
                                    tile.Frame = new PointShort(reader.ReadInt16(), reader.ReadInt16());
                                }
                                else
                                {
                                    tile.Frame = new PointShort(-1, -1);
                                }
                            }
                            tile.IsLighted = reader.ReadBoolean();
                            if (reader.ReadBoolean())
                            {
                                tile.Wall = reader.ReadByte();
                            }

                            if (reader.ReadBoolean())
                            {
                                tile.Liquid = reader.ReadByte();
                                tile.IsLava = reader.ReadBoolean();
                            }

                            Tiles[x, y] = tile;
                        }
                    }

                    for (int chestIndex = 0; chestIndex < MaxChests; chestIndex++)
                    {
                        OnProgressChanged(this, chestIndex, MaxChests, "Loading Chest Data...");

                        if (reader.ReadBoolean())
                        {
                            var chest = new Chest();
                            chest.Location = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                            for (int slot = 0; slot < Chest.MaxItems; slot++)
                            {
                                var  item      = new Item();
                                byte stackSize = reader.ReadByte();
                                if (stackSize > 0)
                                {
                                    string itemName = reader.ReadString();
                                    item.ItemName  = itemName;
                                    item.StackSize = stackSize;
                                }
                                chest.Items.Add(item);
                            }

                            Chests.Add(chest);
                        }
                    }
                    for (int signIndex = 0; signIndex < MaxSigns; signIndex++)
                    {
                        OnProgressChanged(this, signIndex, MaxSigns, "Loading Sign Data...");

                        if (reader.ReadBoolean())
                        {
                            string signText = reader.ReadString();
                            int    x        = reader.ReadInt32();
                            int    y        = reader.ReadInt32();
                            if (Tiles[x, y].IsActive && (Tiles[x, y].Type == 55 || Tiles[x, y].Type == 85))
                            // validate tile location
                            {
                                var sign = new Sign();
                                sign.Location = new PointInt32(x, y);
                                sign.Text     = signText;

                                Signs.Add(sign);
                            }
                        }
                    }

                    bool isNpcActive = reader.ReadBoolean();
                    for (int npcIndex = 0; isNpcActive; npcIndex++)
                    {
                        OnProgressChanged(this, npcIndex, MaxNpcs, "Loading NPCs...");
                        var npc = new NPC();

                        npc.Name       = reader.ReadString();
                        npc.Position   = new PointFloat(reader.ReadSingle(), reader.ReadSingle());
                        npc.IsHomeless = reader.ReadBoolean();
                        npc.HomeTile   = new PointInt32(reader.ReadInt32(), reader.ReadInt32());

                        Npcs.Add(npc);
                        isNpcActive = reader.ReadBoolean();
                    }

                    if (Header.FileVersion > 7)
                    {
                        OnProgressChanged(this, 100, 100, "Checking format...");
                        bool   test           = reader.ReadBoolean();
                        string worldNameCheck = reader.ReadString();
                        int    worldIdCheck   = reader.ReadInt32();
                        if (!(test && string.Equals(worldNameCheck, Header.WorldName) && worldIdCheck == Header.WorldId))
                        {
                            // Test FAILED!
                            IsUsingIo = false;
                            reader.Close();
                            throw new ApplicationException("Invalid World File");
                        }
                    }

                    reader.Close();
                }
            }
            IsValid   = true;
            IsUsingIo = false;
            IsSaved   = true;
            OnProgressChanged(this, 100, 100, "Loading Complete.");
        }
示例#8
0
        public void Validate()
        {
            List <string> log = new List <string>();

            IsUsingIo = true;

            var wb = Header.WorldBounds;

            short[,] deadSpace = new short[wb.Width, wb.Height];
            for (int y = wb.Top; y <= wb.Bottom; y++)
            {
                OnProgressChanged(this, y, wb.Bottom, "Validating Tiles...");

                for (int x = wb.Left; x <= wb.Right; x++)
                {
                    // skip anything in the dead space
                    if (deadSpace[x, y] > 0)
                    {
                        x += deadSpace[x, y] - 1;
                        continue;
                    }

                    // TODO: Need Frames support //
                    // (All tiles have the size/placement properties, but this may change in the future...) //
                    var tile = Tiles[x, y];
                    if (!tile.IsActive)
                    {
                        continue;                  // immediate short-circuit
                    }
                    var type  = tile.Type;
                    var prop  = WorldSettings.Tiles[type];
                    var place = prop.Placement;
                    if (prop.AttachesTo.Count > 0)
                    {
                        continue;                                                   // can't really handle these yet...
                    }
                    if (!ValidatePlacement(new PointInt32(x, y), prop.Size, place)) // validation found a problem
                    {
                        log.Add(string.Format("Tile [{2}] at [{0},{1}] must be placed on {3} {4}", x, y, prop.Name,
                                              place.Has(FP.MustHaveAll) ? "all of:" : (place.IsSingular() ? "a" : "any of:"),
                                              place.Remove(FP.MustHaveAll)));
                    }

                    // validate chest/sign/NPC entries exist
                    switch (type)
                    {
                    case 21:
                        // Validate Chest
                        if (GetChestAtTile(x, y) == null)
                        {
                            var c = new Chest(new PointInt32(x, y));
                            for (int i = 0; i < 20; i++)
                            {
                                c.Items.Add(new Item(0, "[empty]"));
                            }

                            Chests.Add(c);

                            log.Add(string.Format("added empty chest content [{0},{1}]", x, y));
                        }
                        break;

                    case 55:
                    case 85:
                        // Validate Sign/Tombstone
                        if (GetSignAtTile(x, y) == null)
                        {
                            Signs.Add(new Sign("", new PointInt32(x, y)));
                            log.Add(string.Format("added blank sign text [{0},{1}]", x, y));
                        }

                        break;
                    }

                    // TODO: validate the frame exists completely //

                    // assuming the left-right scan, it should hit the top-left corner first
                    // thus, we skip around the rest of the frame for the x-axis

                    // y-axis is a little bit more difficult... (and it requires that x stay put for a bit)
                    if (prop.Size.Y > 1)
                    {
                        for (int s = 1; s < prop.Size.Y; s++)
                        {
                            deadSpace[x, y + s] = prop.Size.X;
                        }
                    }
                    if (prop.Size.X > 1)
                    {
                        x += prop.Size.X - 1;
                    }
                }
            }

            var p = 0;

            OnProgressChanged(this, "Validating Chests...");
            foreach (var chest in Chests.ToList())
            {
                var loc     = chest.Location;
                int locType = Tiles[loc.X, loc.Y].Type;

                if (locType != 21)
                {
                    Chests.Remove(chest);
                    log.Add(string.Format("removed missing chest {0}", loc));
                }
                OnProgressChanged(this, ++p, Chests.Count);
            }

            p = 0;
            OnProgressChanged(this, "Validating Signs...");
            foreach (var sign in Signs.ToList())
            {
                var loc     = sign.Location;
                int locType = Tiles[loc.X, loc.Y].Type;

                if (locType != 55 && locType != 85)
                {
                    Signs.Remove(sign);
                    log.Add(string.Format("removed missing sign {0}", loc));
                }
                OnProgressChanged(this, ++p, Signs.Count);
            }

            foreach (NPC npc in Npcs)
            {
                // no validation yet...
                // (SS: Okay, this is now in the XML; just need to port that stuff over)
            }
            IsUsingIo = false;
            OnProgressChanged(this, 100, 100, "Validation Complete.");

            log.Add("FINISHED with Validation!");
            ErrorLogging.Log(string.Join(Environment.NewLine, log.ToArray()));
        }