public NpcName GetNpc(int id)
        {
            NpcName npc = CharacterNames.FirstOrDefault(c => c.Id == id);

            if (npc != null)
            {
                return(npc);
            }

            return(GetNewNpc(id));
        }
Beispiel #2
0
        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);
            }
        }