public override void InitSigns() { ////添加寻找的词性 Signs.Add("n"); //Signs.Add("j"); ////后面不允许存在的词性 //NextBanSigns.Add("d"); //NextBanSigns.Add("v"); //NextBanSigns.Add("w"); //NextBanSigns.Add("uj"); //NextBanSigns.Add("ad"); //NextBanSigns.Add("m"); //NextBanSigns.Add("f"); //NextBanSigns.Add("c"); //NextBanSigns.Add("w"); ////前面允许出现的词性 //FrontAllowSigns.Add("v"); //FrontAllowSigns.Add("j"); ////FrontAllowSigns.Add("ng"); //FrontAllowSigns.Add("no-type"); ////后面允许的词性 //NextContinueSigns.Add("n"); //NextContinueSigns.Add("j"); //NextContinueSigns.Add("vn"); }
public void Validate() { for (int x = 0; x < TilesWide; x++) { OnProgressChanged(this, new ProgressChangedEventArgs((int)(x / (float)TilesWide * 100.0), "Validating World...")); for (int y = 0; y < TilesHigh; y++) { var curTile = Tiles[x, y]; if (curTile.Type == 127) { curTile.IsActive = false; } // TODO: Let Validate handle these //validate chest entry exists if (curTile.Type == 21) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (curTile.Type == 55 || curTile.Type == 85) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } } } }
private void ValSpecial(int x, int y) { Tile curTile = Tiles[x, y]; //validate chest entry exists if (Tile.IsChest(curTile.Type)) { if (IsAnchor(x, y) && GetChestAtTile(x, y, true) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (Tile.IsSign(curTile.Type)) { if (IsAnchor(x, y) && GetSignAtTile(x, y, true) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } //validate TileEntity else if (Tile.IsTileEntity(curTile.Type)) { if (IsAnchor(x, y) && GetTileEntityAtTile(x, y, true) == null) { var TE = TileEntity.CreateForTile(curTile, x, y, TileEntities.Count); TileEntities.Add(TE); } } }
public override void InitSigns() { //寻找的词性 Signs.Add("ns"); Signs.Add("nsf"); ////后面禁止出现的词性 //NextBanSigns.Add("p"); ////后面允许出现的词性 //NextContinueSigns.Add("n"); //NextContinueSigns.Add("ns"); ////NextContinueSigns.Add("p"); ////前面允许出现的词性 //FrontAllowSigns.Add("p"); //FrontAllowSigns.Add("w"); //FrontAllowSigns.Add("ns"); //FrontAllowSigns.Add("nsf"); //FrontAllowSigns.Add("no-type"); //FrontAllowSigns.Add("b"); //FrontAllowSigns.Add("uj"); //FrontAllowSigns.Add("v"); //FrontAllowSigns.Add("f"); }
public void SetSigns(List <string> signs) {// знаки AEElem add = new AEElem("+", "?L + ?R", "?L + ?R", default); AEElem sub = new AEElem("-", "?L - ?R", "?L - ?R", default); AEElem mul = new AEElem("*", "?L * ?R", "?L * ?R", default); AEElem div = Frac;//new AEElem("/", "?L / (?R)", "\\frac{?L}{?R}", "(fabs((?R)) > 1.0e-6)"); AEElem pow = new AEElem("^", "pow(?L, ?R)", "(?L)^{?R}", default); if (signs.Contains("+")) { Signs.Add(add); } if (signs.Contains("-")) { Signs.Add(sub); } if (signs.Contains("*")) { Signs.Add(mul); } if (signs.Contains("/")) { Signs.Add(div); } if (signs.Contains("^")) { Signs.Add(pow); } }
public void ValSpecial(int x, int y) { Tile curTile = Tiles[x, y]; //validate chest entry exists if (Tile.IsChest(curTile.Type)) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (Tile.IsSign(curTile.Type)) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } //validate TileEntity else if (Tile.IsTileEntity(curTile.Type)) { if (GetTileEntityAtTile(x, y) == null) { TileEntity TE = new TileEntity(); TE.PosX = (short)x; TE.PosY = (short)y; TE.Id = TileEntities.Count; if (curTile.Type == (int)TileType.Dummy) { TE.Type = 0; TE.Npc = -1; } else if (curTile.Type == (int)TileType.ItemFrame) { TE.Type = 1; TE.NetId = 0; TE.Prefix = 0; TE.StackSize = 0; } else { TE.Type = 2; TE.On = false; TE.LogicCheck = (byte)(curTile.V / 18 + 1); } TileEntities.Add(TE); } } }
public override void InitSigns() { //寻找的词性 Signs.Add("nt"); Signs.Add("nz"); //Signs.Add("nl"); //Signs.Add("nrj"); //Signs.Add("ng"); ////后面不允许出现的词性 //NextBanSigns.Add("n"); ////前面允许出现的词性 //FrontAllowSigns.Add("no-type"); //FrontAllowSigns.Add("v"); }
public override void InitSigns() { // HashSet<string> signs = new HashSet<string>(); Signs.Add("nr"); //Signs.Add("nr1"); //Signs.Add("nr2"); //Signs.Add("nrj"); //Signs.Add("nrf"); //Signs.Add("nz"); //Signs.Add("nt"); //NextBanSigns.Add("n"); //FrontAllowSigns.Add("no-type"); //FrontAllowSigns.Add("v"); //FrontAllowSigns.Add("w"); //FrontAllowSigns.Add("p"); //FrontAllowSigns.Add("n"); }
public override void InitSigns() { //添加寻找的词性标注 Signs.Add("t"); Signs.Add("tg"); ////后面不允许出现的词性 //NextBanSigns.Add("ns"); //NextBanSigns.Add("u"); ////后面允许继续出现的词性 //NextContinueSigns.Add("t"); //NextContinueSigns.Add("tg"); //NextContinueSigns.Add("f"); ////NextContinueSigns.Add("m"); //NextContinueSigns.Add("q"); //前面允许出现的词性 FrontAllowSigns.Add("v"); FrontAllowSigns.Add("p"); FrontAllowSigns.Add("w"); FrontAllowSigns.Add("no-type"); FrontAllowSigns.Add("m"); }
public void Validate() { for (int x = 0; x < TilesWide; x++) { OnProgressChanged(this, new ProgressChangedEventArgs((int)(x / (float)TilesWide * 100.0), "Validating World...")); for (int y = 0; y < TilesHigh; y++) { Tile curTile = Tiles[x, y]; if (curTile.Type == (int)TileType.IceByRod) { curTile.IsActive = false; } // TODO: Let Validate handle these //validate chest entry exists if (Tile.IsChest(curTile.Type)) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (Tile.IsSign(curTile.Type)) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } } } foreach (Chest chest in Chests.ToArray()) { bool removed = false; for (int x = chest.X; x < chest.X + 1; x++) { for (int y = chest.Y; y < chest.Y + 1; y++) { if (!Tiles[x, y].IsActive || !Tile.IsChest(Tiles[x, y].Type)) { Chests.Remove(chest); removed = true; break; } } if (removed) { break; } } } foreach (Sign sign in Signs.ToArray()) { if (sign.Text == null) { Signs.Remove(sign); continue; } bool removed = false; for (int x = sign.X; x < sign.X + 1; x++) { for (int y = sign.Y; y < sign.Y + 1; y++) { if (!Tiles[x, y].IsActive || !Tile.IsSign(Tiles[x, y].Type)) { Signs.Remove(sign); removed = true; break; } } if (removed) { break; } } } OnProgressChanged(this, new ProgressChangedEventArgs(0, "Validating Complete...")); if (Chests.Count > 1000) { throw new ArgumentOutOfRangeException(string.Format("Chest Count is {0} which is greater than 1000", Chests.Count)); } if (Signs.Count > 1000) { throw new ArgumentOutOfRangeException(string.Format("Sign Count is {0} which is greater than 1000", Signs.Count)); } }
public void Save(string filename, bool resetTime = false) { lock (_fileLock) { if (resetTime) { OnProgressChanged(this, new ProgressChangedEventArgs(0, "Resetting Time...")); ResetTime(); } if (filename == null) { return; } string temp = filename + ".tmp"; using (var fs = new FileStream(temp, FileMode.Create)) { using (var bw = new BinaryWriter(fs)) { bw.Write(World.CompatibleVersion); bw.Write(Title); bw.Write(WorldId); bw.Write((int)LeftWorld); bw.Write((int)RightWorld); bw.Write((int)TopWorld); bw.Write((int)BottomWorld); bw.Write(TilesHigh); bw.Write(TilesWide); bw.Write(SpawnX); bw.Write(SpawnY); bw.Write(GroundLevel); bw.Write(RockLevel); bw.Write(Time); bw.Write(DayTime); bw.Write(MoonPhase); bw.Write(BloodMoon); bw.Write(DungeonX); bw.Write(DungeonY); bw.Write(DownedBoss1); bw.Write(DownedBoss2); bw.Write(DownedBoss3); bw.Write(SavedGoblin); bw.Write(SavedWizard); bw.Write(SavedMech); bw.Write(DownedGoblins); bw.Write(DownedClown); bw.Write(DownedFrost); bw.Write(ShadowOrbSmashed); bw.Write(SpawnMeteor); bw.Write((byte)ShadowOrbCount); bw.Write(AltarCount); bw.Write(HardMode); bw.Write(InvasionDelay); bw.Write(InvasionSize); bw.Write(InvasionType); bw.Write(InvasionX); for (int x = 0; x < TilesWide; ++x) { OnProgressChanged(this, new ProgressChangedEventArgs(x.ProgressPercentage(TilesWide), "Saving Tiles...")); int rle = 0; for (int y = 0; y < TilesHigh; y = y + rle + 1) { var curTile = Tiles[x, y]; bw.Write(curTile.IsActive); if (curTile.IsActive) { bw.Write(curTile.Type); if (TileProperties[curTile.Type].IsFramed) { bw.Write(curTile.U); bw.Write(curTile.V); // TODO: Let Validate handle these //validate chest entry exists if (curTile.Type == 21) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (curTile.Type == 55 || curTile.Type == 85) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } } } if ((int)curTile.Wall > 0) { bw.Write(true); bw.Write(curTile.Wall); } else { bw.Write(false); } if ((int)curTile.Liquid > 0) { bw.Write(true); bw.Write(curTile.Liquid); bw.Write(curTile.IsLava); } else { bw.Write(false); } bw.Write(curTile.HasWire); int rleTemp = 1; while (y + rleTemp < TilesHigh && curTile.Equals(Tiles[x, (y + rleTemp)])) { ++rleTemp; } rle = rleTemp - 1; bw.Write((short)rle); } } OnProgressChanged(null, new ProgressChangedEventArgs(100, "Saving Chests...")); for (int i = 0; i < 1000; ++i) { if (i >= Chests.Count) { bw.Write(false); } else { Chest curChest = Chests[i]; bw.Write(true); bw.Write(curChest.X); bw.Write(curChest.Y); for (int j = 0; j < Chest.MaxItems; ++j) { if (curChest.Items.Count > j) { bw.Write((byte)curChest.Items[j].StackSize); if (curChest.Items[j].StackSize > 0) { bw.Write(curChest.Items[j].NetId); // TODO Verify bw.Write(curChest.Items[j].Prefix); } } else { bw.Write((byte)0); } } } } OnProgressChanged(null, new ProgressChangedEventArgs(100, "Saving Signs...")); for (int i = 0; i < 1000; ++i) { if (i >= Signs.Count || string.IsNullOrWhiteSpace(Signs[i].Text)) { bw.Write(false); } else { var curSign = Signs[i]; bw.Write(true); bw.Write(curSign.Text); bw.Write(curSign.X); bw.Write(curSign.Y); } } OnProgressChanged(null, new ProgressChangedEventArgs(100, "Saving NPC Data...")); foreach (NPC curNpc in NPCs) { bw.Write(true); bw.Write(curNpc.Name); bw.Write(curNpc.Position.X); bw.Write(curNpc.Position.Y); bw.Write(curNpc.IsHomeless); bw.Write(curNpc.Home.X); bw.Write(curNpc.Home.Y); } bw.Write(false); OnProgressChanged(null, new ProgressChangedEventArgs(100, "Saving NPC Names...")); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 17).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 18).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 19).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 20).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 22).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 54).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 38).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 107).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 108).Name); bw.Write(CharacterNames.FirstOrDefault(c => c.Id == 124).Name); OnProgressChanged(null, new ProgressChangedEventArgs(100, "Saving Validation Data...")); bw.Write(true); bw.Write(Title); bw.Write(WorldId); bw.Close(); fs.Close(); // make a backup of current file if it exists if (File.Exists(filename)) { string backup = filename + ".TEdit"; File.Copy(filename, backup, true); } // replace actual file with temp save file File.Copy(temp, filename, true); // delete temp save file File.Delete(temp); OnProgressChanged(null, new ProgressChangedEventArgs(0, "World Save Complete.")); } } _lastSave = File.GetLastWriteTimeUtc(filename); } }
public void Validate() { for (int x = 0; x < TilesWide; x++) { OnProgressChanged(this, new ProgressChangedEventArgs((int)(x / (float)TilesWide * 100.0), "Validating World...")); for (int y = 0; y < TilesHigh; y++) { Tile curTile = Tiles[x, y]; if (curTile.Type == 127) { curTile.IsActive = false; } // TODO: Let Validate handle these //validate chest entry exists if (curTile.Type == 21 || curTile.Type == 88) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(x, y)); } } //validate sign entry exists else if (curTile.Type == 55 || curTile.Type == 85) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign(x, y, string.Empty)); } } } } foreach (Chest chest in Chests.ToArray()) { bool removed = false; for (int x = chest.X; x < chest.X + 1; x++) { for (int y = chest.Y; y < chest.Y + 1; y++) { if (!Tiles[x, y].IsActive || (Tiles[x, y].Type != 21 && Tiles[x, y].Type != 88)) { Chests.Remove(chest); removed = true; break; } } if (removed) { break; } } } foreach (Sign sign in Signs.ToArray()) { if (sign.Text == null) { Signs.Remove(sign); continue; } bool removed = false; for (int x = sign.X; x < sign.X + 1; x++) { for (int y = sign.Y; y < sign.Y + 1; y++) { if (!Tiles[x, y].IsActive || (Tiles[x, y].Type != 55 && Tiles[x, y].Type != 85)) { Signs.Remove(sign); removed = true; break; } } if (removed) { break; } } } }
public void SaveFile(string filename) { Validate(); IsUsingIo = true; string backupFileName = filename + ".Tedit"; if (File.Exists(filename)) { File.Copy(filename, backupFileName, true); } using (var stream = new FileStream(filename, FileMode.Create)) { using (var writer = new BinaryWriter(stream)) { writer.Write(Header.FileVersion); writer.Write(Header.WorldName); writer.Write(Header.WorldId); writer.Write(Header.WorldBounds.Left * 16); writer.Write(Header.WorldBounds.Width * 16); writer.Write(Header.WorldBounds.Top * 16); writer.Write(Header.WorldBounds.Height * 16); writer.Write(Header.WorldBounds.Height); writer.Write(Header.WorldBounds.Width); writer.Write(Header.SpawnTile.X); writer.Write(Header.SpawnTile.Y); writer.Write(Header.WorldSurface); writer.Write(Header.WorldRockLayer); writer.Write(Header.Time); writer.Write(Header.IsDayTime); writer.Write(Header.MoonPhase); writer.Write(Header.IsBloodMoon); writer.Write(Header.DungeonEntrance.X); writer.Write(Header.DungeonEntrance.Y); writer.Write(Header.IsBossDowned1); writer.Write(Header.IsBossDowned2); writer.Write(Header.IsBossDowned3); writer.Write(Header.IsShadowOrbSmashed); writer.Write(Header.IsSpawnMeteor); writer.Write((byte)Header.ShadowOrbCount); writer.Write(Header.InvasionDelay); writer.Write(Header.InvasionSize); writer.Write(Header.InvasionType); writer.Write(Header.InvasionX); var wb = Header.WorldBounds; for (int x = wb.Left; x <= wb.Right; x++) { OnProgressChanged(this, x, wb.Right, "Saving Tiles..."); for (int y = wb.Top; y <= wb.Bottom; y++) { writer.Write(Tiles[x, y].IsActive); if (Tiles[x, y].IsActive) { writer.Write(Tiles[x, y].Type); if (WorldSettings.Tiles[Tiles[x, y].Type].IsFramed) { writer.Write(Tiles[x, y].Frame.X); writer.Write(Tiles[x, y].Frame.Y); // TODO: Let Validate handle these //validate chest entry exists if (Tiles[x, y].Type == 21) { if (GetChestAtTile(x, y) == null) { Chests.Add(new Chest(new PointInt32(x, y))); } } //validate sign entry exists else if (Tiles[x, y].Type == 55 || Tiles[x, y].Type == 85) { if (GetSignAtTile(x, y) == null) { Signs.Add(new Sign("", new PointInt32(x, y))); } } } } writer.Write(Tiles[x, y].IsLighted); if (Tiles[x, y].Wall > 0) { writer.Write(true); writer.Write(Tiles[x, y].Wall); } else { writer.Write(false); } if (Tiles[x, y].Liquid > 0) { writer.Write(true); writer.Write(Tiles[x, y].Liquid); writer.Write(Tiles[x, y].IsLava); } else { writer.Write(false); } } } for (int chestIndex = 0; chestIndex < MaxChests; chestIndex++) { OnProgressChanged(this, chestIndex, MaxChests, "Saving Chest Data..."); if (chestIndex >= Chests.Count) { writer.Write(false); } else { writer.Write(true); writer.Write(Chests[chestIndex].Location.X); writer.Write(Chests[chestIndex].Location.Y); for (int slot = 0; slot < Chest.MaxItems; slot++) { if (Chests[chestIndex].Items.Count > slot) { writer.Write((byte)Chests[chestIndex].Items[slot].StackSize); if (Chests[chestIndex].Items[slot].StackSize > 0) { writer.Write(Chests[chestIndex].Items[slot].ItemName); } } else { writer.Write((byte)0); } } } } for (int signIndex = 0; signIndex < MaxSigns; signIndex++) { OnProgressChanged(this, signIndex, MaxSigns, "Saving Sign Data..."); if (signIndex >= Signs.Count) { writer.Write(false); } else if (string.IsNullOrWhiteSpace(Signs[signIndex].Text)) { writer.Write(false); } else { writer.Write(true); writer.Write(Signs[signIndex].Text); writer.Write(Signs[signIndex].Location.X); writer.Write(Signs[signIndex].Location.Y); } } var p = 0; foreach (NPC npc in Npcs) { OnProgressChanged(this, ++p, Npcs.Count, "Saving NPCs..."); writer.Write(true); writer.Write(npc.Name); writer.Write(npc.Position.X); writer.Write(npc.Position.Y); writer.Write(npc.IsHomeless); writer.Write(npc.HomeTile.X); writer.Write(npc.HomeTile.Y); } writer.Write(false); // Write file info check version 7+ writer.Write(true); writer.Write(Header.WorldName); writer.Write(Header.WorldId); writer.Close(); } } IsUsingIo = false; IsSaved = true; OnProgressChanged(this, 100, 100, "Saving Complete."); }
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."); }
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())); }