Пример #1
0
        static LoadError ReadFormat(ref WorldFile ret, BinBuffer bb)
        {
            positions = new int[bb.ReadShort()];
            for (int i = 0; i < positions.Length; i++)
                positions[i] = bb.ReadInt();

            importance = new bool[bb.ReadShort()];

            byte b = 0, b2 = 128;

            for (int i = 0; i < importance.Length; i++)
            {
                if (b2 == 128)
                {
                    b = bb.ReadByte();

                    b2 = 1;
                }
                else
                    b2 <<= 1;

                if ((b & b2) == b2)
                    importance[i] = true;
            }

            return LoadError.Success;
        }
Пример #2
0
        internal static WorldFile ReadWorld(string path)
        {
            WorldFile ret = new WorldFile();

            BinBuffer bb = new BinBuffer(new BinBufferByte(File.ReadAllBytes(path)));

            int ver = ret.version = bb.ReadInt();

            LoadError err;
            if ((err = (ver <= 87 ? ReadV1(ref ret, bb) : ReadV2(ref ret, bb))) != LoadError.Success)
                throw new FormatException("An error occured when reading the world file: " + ToReadableString(err));

            return ret;
        }
Пример #3
0
        unsafe static LoadError ReadV1(ref WorldFile ret, BinBuffer bb)
        {
            // please help me, I'm starting to code C/C++ in C#

            InitFrameImportant();
            InitSolid();

            int ver = ret.version;
            if (ver > 102 /* 1.2.4.1 */)
                return LoadError.InvalidVersion;

            #region global stuff
            ret.name = PlayerPorter.ReadString(bb);
            ret.ID = bb.ReadInt();
            ret.bounds = new Vector4(bb.ReadInt(), bb.ReadInt(), bb.ReadInt(), bb.ReadInt());
            ret.size = new Point(bb.ReadInt(), bb.ReadInt());
            ret.moonType = ver >= 63 ? bb.ReadByte() : backupRand.Next(Main.maxMoons);

            if (ver >= 44)
            {
                for (int i = 0; i < ret.treeX.Length; i++)
                    ret.treeX[i] = bb.ReadInt();
                for (int i = 0; i < ret.treeStyle.Length; i++)
                    ret.treeStyle[i] = bb.ReadInt();
            }
            if (ver >= 60)
            {
                for (int i = 0; i < ret.caveBackX.Length; i++)
                    ret.caveBackX[i] = bb.ReadInt();
                for (int i = 0; i < ret.caveBackStyle.Length; i++)
                    ret.caveBackStyle[i] = bb.ReadInt();

                ret.iceBackStyle = bb.ReadInt();

                if (ver >= 61)
                {
                    ret.jungleBackStyle = bb.ReadInt();
                    ret.hellBackStyle = bb.ReadInt();
                }
            }
            else
            {
                #region create random background styles
                const int maxValue = 8;

                if (ret.size.X == 4200)
                {
                    ret.caveBackX[0] = backupRand.Next(ret.size.X / 4, ret.size.X / 4 * 3);

                    ret.caveBackX[1] = ret.caveBackX[2] = ret.size.X;

                    ret.caveBackStyle[0] = backupRand.Next(maxValue);

                    do
                        ret.caveBackStyle[1] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[1] == ret.caveBackStyle[0]);
                }
                else if (ret.size.X == 6400)
                {
                    ret.caveBackX[0] = backupRand.Next(ret.size.X / 3 - ret.size.X / 5, ret.size.X / 3 + ret.size.X / 5);
                    ret.caveBackX[1] = backupRand.Next(ret.size.X / 3 * 2 - ret.size.X / 5, ret.size.X / 3 * 2 + ret.size.X / 5);

                    ret.caveBackX[2] = ret.size.X;

                    ret.caveBackStyle[0] = backupRand.Next(maxValue);

                    do
                        ret.caveBackStyle[1] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[1] == ret.caveBackStyle[0]);

                    do
                        ret.caveBackStyle[2] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[2] == ret.caveBackStyle[0] || ret.caveBackStyle[2] == ret.caveBackStyle[1]);
                }
                else
                {
                    ret.caveBackX[0] = backupRand.Next(ret.size.X / 4 - ret.size.X / 8, ret.size.X / 4 + ret.size.X / 8);
                    ret.caveBackX[1] = backupRand.Next(ret.size.X / 2 - ret.size.X / 8, ret.size.X / 2 + ret.size.X / 8);
                    ret.caveBackX[2] = backupRand.Next(ret.size.X / 4 * 3 - ret.size.X / 8, ret.size.X / 4 * 3 + ret.size.X / 8);

                    ret.caveBackStyle[0] = backupRand.Next(maxValue);

                    do
                        ret.caveBackStyle[1] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[1] == ret.caveBackStyle[0]);

                    do
                        ret.caveBackStyle[2] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[2] == ret.caveBackStyle[0] || ret.caveBackStyle[2] == ret.caveBackStyle[1]);

                    do
                        ret.caveBackStyle[3] = backupRand.Next(maxValue);
                    while (ret.caveBackStyle[3] == ret.caveBackStyle[0] || ret.caveBackStyle[3] == ret.caveBackStyle[1] || ret.caveBackStyle[3] == ret.caveBackStyle[2]);
                }

                ret.iceBackStyle = backupRand.Next(4);
                ret.hellBackStyle = backupRand.Next(3);
                ret.jungleBackStyle = backupRand.Next(2);
                #endregion
            }

            ret.spawn = new Point(bb.ReadInt(), bb.ReadInt());

            ret.surface = bb.ReadDouble();
            ret.rockLayer = bb.ReadDouble();
            ret.time = bb.ReadDouble();
            ret.day = bb.ReadBool();
            ret.moonPhase = bb.ReadInt() % 8;
            ret.bloodMoon = bb.ReadBool();

            if (ver >= 70)
                ret.eclipse = bb.ReadBool();

            ret.dungeon = new Point(bb.ReadInt(), bb.ReadInt());

            ret.crimson = ver >= 56 ? bb.ReadBool() : false;

            ret.DefeatedEoC = bb.ReadBool();
            ret.DefeatedEoW = bb.ReadBool();
            ret.DefeatedSkeletron = bb.ReadBool();

            if (ver >= 66)
                ret.DefeatedQueenBee = bb.ReadBool();
            if (ver >= 44)
            {
                ret.DefeatedDestroyer = bb.ReadBool();
                ret.DefeatedTwins = bb.ReadBool();
                ret.DefeatedSkeletronPrime = bb.ReadBool();
                bool downedAnyHM = bb.ReadBool(); // pretty redundant
            }
            if (ver >= 64)
            {
                ret.DefeatedPlantera = bb.ReadBool();
                ret.DefeatedGolem = bb.ReadBool();
            }
            if (ver >= 29)
            {
                ret.SavedGoblin = bb.ReadBool();
                ret.SavedWizard = bb.ReadBool();

                if (ver >= 34)
                {
                    ret.SavedMechanic = bb.ReadBool();

                    if (ver >= 80)
                        ret.SavedStylist = bb.ReadBool();
                }
            }
            if (ver >= 32)
                ret.DefeatedClown = bb.ReadBool();
            if (ver >= 37)
                ret.DefeatedFrostLegion = bb.ReadBool();
            if (ver >= 56)
                ret.DefeatedPirates = bb.ReadBool();

            ret.SmashedShadowOrb = bb.ReadBool();
            ret.MeteorHasLanded = bb.ReadBool();
            ret.shadowOrbsSmashed = bb.ReadByte();

            if (ver >= 23)
            {
                ret.altarsSmashed = bb.ReadInt();
                ret.Hardmode = bb.ReadBool();
            }

            ret.invasionDelay = bb.ReadInt();
            ret.invasionSize = bb.ReadInt();
            ret.invasionType = bb.ReadInt();
            ret.invasionX = bb.ReadDouble();

            if (ver >= 53)
            {
                ret.Raining = bb.ReadBool();
                ret.rainTime = bb.ReadInt();
                ret.maxRain = bb.ReadFloat();
            }
            if (ver >= 54)
            {
                ret.ore1Type = bb.ReadInt();
                ret.ore2Type = bb.ReadInt();
                ret.ore3Type = bb.ReadInt();
            }
            else if (ver >= 32 && ret.altarsSmashed == 0)
                ret.ore1Type = ret.ore2Type = ret.ore3Type = -1;
            else
            {
                ret.ore1Type = 107;
                ret.ore2Type = 108;
                ret.ore3Type = 111;
            }

            if (ver >= 55)
                for (int i = 0; i < 3; i++)
                    ret.bgStyles[i] = bb.ReadByte();
            if (ver >= 60)
            {
                for (int i = 3; i < 8; i++)
                    ret.bgStyles[i] = bb.ReadByte();

                ret.cloudBgActive = bb.ReadInt();
            }
            else
                ret.cloudBgActive = -backupRand.Next(8640, 86400);

            if (ver >= 62)
            {
                ret.cloudAmt = bb.ReadShort();
                ret.windSpeed = bb.ReadFloat();
            }
            else
            {
                ret.cloudAmt = (short)backupRand.Next(10, Main.cloudLimit);

                do
                    ret.windSpeed = WorldGen.genRand.Next(-100, 101) / 100f;
                while (ret.windSpeed == 0f);
            }
            #endregion

            for (int i = 0; i < ret.bgStyles.Length; i++)
                WorldGen.setBG(i, ret.bgStyles[i]);

            ret.InitTiles();

            #region tiles
            // warning: lunacy ahead

            fixed (Tile* basePtr = &ret.tiles[0, 0])
            {
                var t = basePtr; // don't check the bounds over and over again. much faster.

                for (int i = 0; i < ret.size.X + ret.size.Y; i++)
                {
                    long offset = t - basePtr;
                    long x = offset % ret.size.X;
                    long y = (offset - x) / ret.size.X;

                    byte* compressed = (byte*)(t + t->CompressedDataOffset);

                    if (t->Active = bb.ReadBool())
                    {
                        t->type = ver > 77 ? bb.ReadUShort() : bb.ReadByte();

                        if (t->type == 127)
                            t->Active = false;

                        if (ver <= 72 && (t->type >= 35 || t->type <= 36 || t->type >= 170 || t->type <= 172))
                        {
                            t->frameX = bb.ReadShort();
                            t->frameY = bb.ReadShort();
                        }
                        else if (TileDef.frameImportant[t->type])
                        {
                            if (ver < 28 && t->type == 4)
                                t->frameX = t->frameY = 0;
                            else if (ver < 40 && t->type == 19)
                                t->frameX = t->frameY = 0;
                            else
                            {
                                t->frameX = bb.ReadShort();
                                t->frameY = bb.ReadShort();

                                if (t->type == 144)
                                    t->frameY = 0;
                            }
                        }
                        else
                            t->frameX = t->frameY = -1;

                        if (ver >= 84 && bb.ReadBool())
                            t->Colour = bb.ReadByte();

                        if (ver <= 25)
                            bb.ReadBool();

                        if (bb.ReadBool())
                        {
                            t->wall = bb.ReadByte();

                            if (ver >= 48 && bb.ReadBool())
                                t->WallColour = bb.ReadByte();
                        }
                        if (bb.ReadBool())
                        {
                            t->liquid = bb.ReadByte();

                            t->Lava = bb.ReadBool();

                            if (ver >= 51)
                                t->Honey = bb.ReadBool();
                        }
                        if (ver >= 33)
                            t->Wire = bb.ReadBool();
                        if (ver >= 43)
                        {
                            t->Wire2 = bb.ReadBool();
                            t->Wire3 = bb.ReadBool();
                        }
                        if (ver >= 41)
                        {
                            t->HalfBrick = bb.ReadBool() && !TileDef.solid[t->type];

                            if (ver >= 49)
                            {
                                t->Slope = bb.ReadByte();

                                if (!TileDef.solid[t->type])
                                    t->Slope = 0;
                            }
                        }
                        if (ver >= 42)
                        {
                            t->Actuator = bb.ReadBool();
                            t->Inactive = bb.ReadBool();
                        }

                        if (ver >= 25)
                            bb.ReadShort();
                    }

                    t += sizeof(Tile);
                }
            }
            #endregion

            #region chests
            int chestSize = ver < 58 ? 20 : 40;

            for (int i = 0; i < ret.chests.Length; i++)
            {
                if (!bb.ReadBool())
                    continue;

                ret.chests[i] = new Chest()
                {
                    position = new Point(bb.ReadInt(), bb.ReadInt())
                };

                if (ver >= 85)
                    ret.chests[i].name = PlayerPorter.ReadString(bb);

                for (int j = 0; j < ret.chests[i].items.Length; j++)
                {
                    ret.chests[i].items[j] = new Item();

                    if (j < chestSize)
                    {
                        Item it = ret.chests[i].items[j];

                        int stack = ver >= 59 ? bb.ReadShort() : bb.ReadByte();
                        if (stack <= 0)
                            continue;

                        if (ver < 38)
                        {
                            // screw this
                            throw new FormatException("World format too old.");
                        }

                        it.netID = bb.ReadInt();
                        it.stack = stack;
                        it.prefix = bb.ReadByte();
                    }
                }
            }
            #endregion

            #region signs
            for (int i = 0; i < ret.signs.Length; i++)
            {
                if (!bb.ReadBool())
                    continue;

                ret.signs[i] = new Sign()
                {
                    text = PlayerPorter.ReadString(bb),
                    position = new Point(bb.ReadInt(), bb.ReadInt())
                };
            }
            #endregion

            #region town npcs
            while (bb.ReadBool())
            {
                TownNPC n = new TownNPC()
                {
                    occupation = PlayerPorter.ReadString(bb)
                };

                if (ver >= 83)
                    n.name = PlayerPorter.ReadString(bb);

                n.position = new Vector2(bb.ReadFloat(), bb.ReadFloat());
                n.homeless = bb.ReadBool();
                n.homeTile = new Point(bb.ReadInt(), bb.ReadInt());

                NPC npc = new NPC();
                npc.SetDefaults(n.occupation);
                n.type = npc.type;

                ret.townNPCs.Add(n);
            }

            if (ver >= 31 && ver <= 83)
            {
                string
                    merchantName = PlayerPorter.ReadString(bb),
                    nurseName = PlayerPorter.ReadString(bb),
                    armsDealerName = PlayerPorter.ReadString(bb),
                    dryadName = PlayerPorter.ReadString(bb),
                    guideName = PlayerPorter.ReadString(bb),
                    clothierName = PlayerPorter.ReadString(bb),
                    demolitionistName = PlayerPorter.ReadString(bb),
                    goblinName = PlayerPorter.ReadString(bb),
                    wizardName = PlayerPorter.ReadString(bb),

                    mechanicName = String.Empty,
                    truffleName = String.Empty,
                    steampunkerName = String.Empty,
                    dyeTraderName = String.Empty,
                    partyGirlName = String.Empty,
                    cyborgName = String.Empty,
                    painterName = String.Empty,
                    witchDoctorName = String.Empty,
                    pirateName = String.Empty,
                    anglerName = String.Empty;

                if (ver >= 35)
                {
                    mechanicName = PlayerPorter.ReadString(bb);

                    if (ver >= 65)
                    {
                        truffleName = PlayerPorter.ReadString(bb);
                        steampunkerName = PlayerPorter.ReadString(bb);
                        dyeTraderName = PlayerPorter.ReadString(bb);
                        partyGirlName = PlayerPorter.ReadString(bb);
                        cyborgName = PlayerPorter.ReadString(bb);
                        painterName = PlayerPorter.ReadString(bb);
                        witchDoctorName = PlayerPorter.ReadString(bb);
                        pirateName = PlayerPorter.ReadString(bb);

                        if (ver >= 79)
                            anglerName = PlayerPorter.ReadString(bb);
                    }
                }

                for (int i = 0; i < ret.townNPCs.Count; i++)
                {
                    TownNPC n = ret.townNPCs[i];

                    switch (n.occupation.ToLowerInvariant()) // can't remember if it's First second or First Second...
                    {
                        case "merchant":
                            n.name = merchantName;
                            break;
                        case "nurse":
                            n.name = merchantName;
                            break;
                        case "arms dealer":
                            n.name = armsDealerName;
                            break;
                        case "dryad":
                            n.name = dryadName;
                            break;
                        case "guide":
                            n.name = guideName;
                            break;
                        case "clothier":
                            n.name = clothierName;
                            break;
                        case "demolitionist":
                            n.name = demolitionistName;
                            break;
                        case "goblin tinkerer":
                            n.name = goblinName;
                            break;
                        case "wizard":
                            n.name = wizardName;
                            break;
                        case "mechanic":
                            n.name = mechanicName;
                            break;
                        case "truffle":
                            n.name = truffleName;
                            break;
                        case "steampunker":
                            n.name = steampunkerName;
                            break;
                        case "dye trader":
                            n.name = dyeTraderName;
                            break;
                        case "party girl":
                            n.name = partyGirlName;
                            break;
                        case "cyborg":
                            n.name = cyborgName;
                            break;
                        case "painter":
                            n.name = painterName;
                            break;
                        case "witch doctor":
                            n.name = witchDoctorName;
                            break;
                        case "pirate":
                            n.name = pirateName;
                            break;
                        case "angler":
                            n.name = anglerName;
                            break;
                    }
                }
            }
            #endregion

            if (ver < 7)
                return LoadError.Success;

            bool cBool = bb.ReadBool();
            string cStr = PlayerPorter.ReadString(bb);
            int bInt = bb.ReadInt();
            // this is not a checksum, red.
            return cBool && (cStr == ret.name || bInt == ret.ID)
                ? LoadError.Success
                : LoadError.InvalidChecksum;
        }
        internal static void WriteWorld(WorldFile world)
        {
            using (ZipFile zf = new ZipFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal)
                + "\\My Games\\Terraria\\tAPI\\Worlds\\" + world.name + ".wld"))
            {
                #region info.json
                JsonData info = JsonMapper.ToObject("{}");

                JsonData format = JsonMapper.ToObject("{}");
                format["release"] = API.versionAssembly;
                format["subrelease"] = API.versionSubrelease;

                info["format"] = format;

                info["id"] = world.ID;

                JsonData size = JsonMapper.ToObject("[]");

                size.Add(world.size.X);
                size.Add(world.size.Y);

                JsonData borders = JsonMapper.ToObject("{}");

                borders["left"] = (int)world.bounds.X;
                borders["right"] = (int)world.bounds.Y;
                borders["up"] = (int)world.bounds.Z;
                borders["down"] = (int)world.bounds.W;

                info["borders"] = borders;

                JsonData styles = JsonMapper.ToObject("{}");

                JsonData tree = JsonMapper.ToObject("[]");

                for (int i = 0; i < world.treeStyle.Length; i++)
                    tree.Add(world.treeStyle[i]);

                styles["tree"] = tree;

                JsonData caveBack = JsonMapper.ToObject("[]");

                for (int i = 0; i < world.caveBackStyle.Length; i++)
                    caveBack.Add(world.caveBackStyle[i]);

                styles["caveBack"] = caveBack;

                styles["iceBack"] = world.iceBackStyle;
                styles["jungleBack"] = world.jungleBackStyle;
                styles["hellBack"] = world.hellBackStyle;

                info["styles"] = styles;

                JsonData treeX = JsonMapper.ToObject("[]");

                for (int i = 0; i < world.treeX.Length; i++)
                    treeX.Add(world.treeX[i]);

                info["treeX"] = treeX;

                JsonData caveBackX = JsonMapper.ToObject("[]");

                for (int i = 0; i < world.caveBackX.Length; i++)
                    caveBackX.Add(world.caveBackX[i]);

                info["caveBackX"] = caveBackX;

                JsonData spawn = JsonMapper.ToObject("[]");

                spawn.Add(world.spawn.X);
                spawn.Add(world.spawn.Y);

                info["spawn"] = spawn;

                JsonData layers = JsonMapper.ToObject("{}");

                layers["worldSurface"] = world.surface;
                layers["rock"] = world.rockLayer;
                layers["hell"] = world.size.Y - 200d;

                info["layers"] = layers;

                JsonData time = JsonMapper.ToObject("{}");

                time["day"] = world.day;
                time["time"] = world.time;

                JsonData moon = JsonMapper.ToObject("{}");

                moon["type"] = world.moonType;
                moon["phase"] = world.moonPhase;

                time["moon"] = moon;

                time["bloodMoon"] = world.bloodMoon;
                time["eclipse"] = world.eclipse;

                info["time"] = time;

                JsonData dungeon = JsonMapper.ToObject("[]");

                dungeon.Add(world.dungeon.X);
                dungeon.Add(world.dungeon.Y);

                info["dungeon"] = dungeon;

                info["crimson"] = world.crimson;
                info["corruption"] = !world.crimson;

                JsonData progress = JsonMapper.ToObject("{}");

                JsonData bosses = JsonMapper.ToObject("{}");

                bosses["Eye of Ctulhu"] = world.DefeatedEoC;
                bosses["Eater of Worlds"] = world.DefeatedEoW;
                bosses["Skeletron"] = world.DefeatedSkeletron;
                bosses["Queen Bee"] = world.DefeatedQueenBee;

                bosses["The Destroyer"] = world.DefeatedDestroyer;
                bosses["The Twins"] = world.DefeatedTwins;
                bosses["Skeletron Prime"] = world.DefeatedSkeletronPrime;

                bosses["Plantera"] = world.DefeatedPlantera;
                bosses["Golem"] = world.DefeatedGolem;

                progress["bosses"] = bosses;

                JsonData townNPCs = JsonMapper.ToObject("{}");

                townNPCs["Goblin Tinkerer"] = world.SavedGoblin;
                townNPCs["Wizard"] = world.SavedWizard;
                townNPCs["Mechanic"] = world.SavedMechanic;

                progress["npcs"] = townNPCs;

                JsonData invasions = JsonMapper.ToObject("{}");

                JsonData currentInvasion = JsonMapper.ToObject("{}");

                currentInvasion["delay"] = world.invasionDelay;
                currentInvasion["size"] = world.invasionSize;
                currentInvasion["type"] = world.invasionType;
                currentInvasion["x"] = world.invasionX;

                invasions["current"] = currentInvasion;

                invasions["Goblin Army"] = world.DefeatedGoblins;
                invasions["Frost Legion"] = world.DefeatedFrostLegion;
                invasions["Pirates"] = world.DefeatedPirates;

                progress["invasions"] = invasions;

                JsonData shadowOrb = JsonMapper.ToObject("{}");

                shadowOrb["smashed"] = world.SmashedShadowOrb;
                shadowOrb["counter"] = world.shadowOrbsSmashed;

                progress["shadowOrb"] = shadowOrb;

                progress["spawnMeteor"] = world.MeteorHasLanded;
                progress["hardmode"] = world.Hardmode;
                progress["altarCounter"] = world.altarsSmashed;

                info["progress"] = progress;

                JsonData sky = JsonMapper.ToObject("{}");

                sky["raining"] = world.Raining;
                sky["rainTime"] = world.rainTime;
                sky["maxRain"] = world.maxRain;
                sky["cloudBGActive"] = world.cloudBgActive;
                sky["clouds"] = world.cloudAmt;
                sky["windSpeed"] = world.windSpeed;

                info["sky"] = sky;

                JsonData hmOres = JsonMapper.ToObject("[]");

                hmOres.Add(world.ore1Type);
                hmOres.Add(world.ore2Type);
                hmOres.Add(world.ore3Type);

                info["hardmodeOres"] = hmOres;

                JsonData bgs = JsonMapper.ToObject("{}");

                bgs["tree"] = WorldGen.treeBG;
                bgs["corrupt"] = WorldGen.corruptBG;
                bgs["jungle"] = WorldGen.jungleBG;
                bgs["snow"] = WorldGen.snowBG;
                bgs["hallow"] = WorldGen.hallowBG;
                bgs["crimson"] = WorldGen.crimsonBG;
                bgs["desert"] = WorldGen.desertBG;
                bgs["ocean"] = WorldGen.oceanBG;

                info["bgs"] = bgs;

                zf.AddEntry("Info.json", JsonMapper.ToJson(info));
                #endregion

                BinBuffer bb = new BinBuffer();

                #region tiles.dat
                for (int y = 0; y < world.size.Y; y++)
                    for (int x = 0; x < world.size.X; x++)
                    {
                        Tile t = world.tiles[x, y];

                        bb.Write(t.Active || t.type > Main.maxTileSets ? t.type + 1 : 0);
                        bb.Write(t.wall);
                        bb.Write(t.frameX);
                        bb.Write(t.frameY);
                        bb.Write(t.Colour);
                        bb.Write(t.WallColour);
                        bb.Write(t.LiquidType);
                        bb.Write(t.liquid);
                        bb.Write(new BitsByte(t.Wire, t.Wire2, t.Wire3, t.Actuator, t.Inactive, t.HalfBrick, (t.bb3 & 16) == 16, (t.bb3 & 32) == 32));
                    }

                bb.Pos = 0;
                zf.AddEntry("Tiles.dat", bb.ReadBytes());
                #endregion

                bb.Clear();

                #region chests.dat

                for (int i = 0; i < world.chests.Length; i++)
                {
                    Chest c = world.chests[i];

                    if (c == null || c.items.All(it => it.netID == 0 || it.stack <= 0))
                        bb.Write(false);
                    else
                    {
                        bb.Write(true);
                        bb.WriteX(c.position.X, c.position.Y);

                        for (int j = 0; j < c.items.Length; i++)
                        {
                            if (c.items[i] == null)
                                c.items[i] = new Item();

                            PlayerPorter.WriteItem(bb, c.items[i]);
                        }
                    }
                }

                bb.Pos = 0;
                zf.AddEntry("Chests.dat", bb.ReadBytes());
                #endregion

                bb.Clear();

                #region itemmappings.dat
                bb.Write(0);
                bb.Pos = 0;
                zf.AddEntry("ItemMappings.dat", bb.ReadBytes());
                #endregion

                bb.Clear();

                #region signs.dat
                for (int i = 0; i < world.signs.Length; i++)
                {
                    if (world.signs[i] == null || world.signs[i].text == null ||
                            (String.IsNullOrEmpty(world.signs[i].text) && world.signs[i].position.X == 0 && world.signs[i].position.Y == 0))
                        bb.Write(false);
                    else
                    {
                        bb.Write(true);

                        bb.WriteX(world.signs[i].position.X, world.signs[i].position.Y);

                        bb.WriteX(world.signs[i].text == null ? String.Empty : world.signs[i].text);
                    }
                }
                #endregion

                bb.Clear();

                #region npcs.dat
                bb.Write(world.townNPCs.Count);
                for (int i = 0; i < world.townNPCs.Count; i++)
                {
                    TownNPC n = world.townNPCs[i];

                    bb.Write(n.occupation);
                    bb.Write(n.position);
                    bb.Write(n.homeless);
                    bb.WriteX(n.homeTile.X, n.homeTile.Y);
                }

                bb.Write(world.townNPCs.Count);
                for (int i = 0; i < world.townNPCs.Count; i++)
                {
                    TownNPC n = world.townNPCs[i];

                    bb.Write(n.type > Main.maxNPCTypes ? 0 : n.type);
                    bb.Write(n.name);
                }
                #endregion

                //bb.Clear();

                #region tilecodes.dat
                zf.AddEntry("TileCodes.dat", new byte[0]);
                #endregion

                zf.Save();
            }
        }
Пример #5
0
        static LoadError ReadHeader(ref WorldFile ret, BinBuffer bb)
        {
            ret.name = PlayerPorter.ReadString(bb);
            ret.ID = bb.ReadInt();
            ret.bounds = new Vector4(bb.ReadInt(), bb.ReadInt(), bb.ReadInt(), bb.ReadInt());
            ret.size = new Point(bb.ReadInt(), bb.ReadInt());
            ret.moonType = bb.ReadInt();

            for (int i = 0; i < ret.treeX.Length; i++)
                ret.treeX[i] = bb.ReadInt();
            for (int i = 0; i < ret.treeStyle.Length; i++)
                ret.treeStyle[i] = bb.ReadInt();
            for (int i = 0; i < ret.caveBackX.Length; i++)
                ret.caveBackX[i] = bb.ReadInt();
            for (int i = 0; i < ret.caveBackStyle.Length; i++)
                ret.caveBackStyle[i] = bb.ReadInt();

            ret.iceBackStyle = bb.ReadInt();
            ret.jungleBackStyle = bb.ReadInt();
            ret.hellBackStyle = bb.ReadInt();

            ret.spawn = new Point(bb.ReadInt(), bb.ReadInt());

            ret.surface = bb.ReadDouble();
            ret.rockLayer = bb.ReadDouble();
            ret.time = bb.ReadDouble();
            ret.day = bb.ReadBool();
            ret.moonPhase = bb.ReadInt();
            ret.bloodMoon = bb.ReadBool();
            ret.eclipse = bb.ReadBool();
            ret.dungeon = new Point(bb.ReadInt(), bb.ReadInt());
            ret.crimson = bb.ReadBool();
            ret.DefeatedEoC = bb.ReadBool();
            ret.DefeatedEoW = bb.ReadBool();
            ret.DefeatedSkeletron = bb.ReadBool();
            ret.DefeatedQueenBee = bb.ReadBool();
            ret.DefeatedDestroyer = bb.ReadBool();
            ret.DefeatedTwins = bb.ReadBool();
            ret.DefeatedSkeletronPrime = bb.ReadBool();
            bb.ReadBool(); // downedMechBossAny. Pretty redundant.
            ret.SavedGoblin = bb.ReadBool();
            ret.SavedWizard = bb.ReadBool();
            ret.SavedMechanic = bb.ReadBool();
            ret.DefeatedGoblins = bb.ReadBool();
            ret.DefeatedFrostLegion = bb.ReadBool();
            ret.DefeatedPirates = bb.ReadBool();
            ret.SmashedShadowOrb = bb.ReadBool();
            ret.MeteorHasLanded = bb.ReadBool();
            ret.shadowOrbsSmashed = bb.ReadByte();
            ret.altarsSmashed = bb.ReadInt();
            ret.Hardmode = bb.ReadBool();
            ret.invasionDelay = bb.ReadInt();
            ret.invasionSize = bb.ReadInt();
            ret.invasionType = bb.ReadInt();
            ret.invasionX = bb.ReadDouble();
            ret.Raining = bb.ReadBool();
            ret.rainTime = bb.ReadInt();
            ret.maxRain = bb.ReadFloat();
            ret.ore1Type = bb.ReadInt();
            ret.ore2Type = bb.ReadInt();
            ret.ore3Type = bb.ReadInt();

            for (int i = 0; i < ret.bgStyles.Length; i++)
                WorldGen.setBG(i, ret.bgStyles[i]);

            ret.cloudBgActive = bb.ReadInt();
            ret.cloudAmt = bb.ReadShort();
            ret.windSpeed = bb.ReadFloat();
            
            if (ver >= 95)
            {
                int amt = bb.ReadInt();
                for (int i = 0; i < amt; i++)
                    ret.finishedAnglerToday.Add(PlayerPorter.ReadString(bb));

                if (ver >= 99)
                {
                    ret.SavedAngler = bb.ReadBool();

                    if (ver >= 101)
                        ret.anglerQuest = bb.ReadInt();
                }
            }

            return LoadError.Success;
        }
Пример #6
0
        static LoadError ReadV2(ref WorldFile ret, BinBuffer bb)
        {
            ver = ret.version;

            for (int i = 0; i < read.Length; i++)
            {
                var le = read[i](ref ret, bb);

                if (le != LoadError.Success)
                    return le;
                if (bb.Pos != positions[i])
                    return LoadError.InvalidBufferLength;
            }

            return LoadError.Success;
        }
Пример #7
0
        static LoadError ReadFooter(ref WorldFile ret, BinBuffer bb)
        {
            if (!bb.ReadBool())
                return LoadError.InvalidBufferChecksum;
            if (PlayerPorter.ReadString(bb) != ret.name)
                return LoadError.InvalidBufferChecksum;
            if (bb.ReadInt() != ret.ID)
                return LoadError.InvalidBufferChecksum;

            return LoadError.Success;
        }
Пример #8
0
        static LoadError ReadNPCs  (ref WorldFile ret, BinBuffer bb)
        {
            while (bb.ReadBool())
                ret.townNPCs.Add(new TownNPC()
                {
                    occupation = PlayerPorter.ReadString(bb),
                    name = PlayerPorter.ReadString(bb),
                    position = new Vector2(bb.ReadFloat(), bb.ReadFloat()),
                    homeless = bb.ReadBool(),
                    homeTile = new Point(bb.ReadInt(), bb.ReadInt())
                });

            for (int i = 0; i < ret.townNPCs.Count; i++)
            {
                TownNPC n = ret.townNPCs[i];

                switch (n.occupation.ToLowerInvariant()) // can't remember if it's First second or First Second...
                {
                    case "merchant":
                        n.type = 17;
                        break;
                    case "nurse":
                        n.type = 18;
                        break;
                    case "arms dealer":
                        n.type = 19;
                        break;
                    case "dryad":
                        n.type = 20;
                        break;
                    case "guide":
                        n.type = 22;
                        break;
                    case "clothier":
                        n.type = 54;
                        break;
                    case "demolitionist":
                        n.type = 38;
                        break;
                    case "goblin tinkerer":
                        n.type = 107;
                        break;
                    case "wizard":
                        n.type = 108;
                        break;
                    case "mechanic":
                        n.type = 124;
                        break;
                    case "truffle":
                        n.type = 160;
                        break;
                    case "steampunker":
                        n.type = 178;
                        break;
                    case "dye trader":
                        n.type = 207;
                        break;
                    case "party girl":
                        n.type = 208;
                        break;
                    case "cyborg":
                        n.type = 209;
                        break;
                    case "painter":
                        n.type = 227;
                        break;
                    case "witch doctor":
                        n.type = 228;
                        break;
                    case "pirate":
                        n.type = 229;
                        break;
                    case "angler":
                        n.type = 358;
                        break;
                }
            }

            return LoadError.Success;
        }
Пример #9
0
        static LoadError ReadSigns (ref WorldFile ret, BinBuffer bb)
        {
            short amt = bb.ReadShort();

            for (int i = 0; i < amt; i++)
            {
                string text = PlayerPorter.ReadString(bb);
                int
                    x = bb.ReadInt(),
                    y = bb.ReadInt();

                if (ret.tiles[x, y].Active && (ret.tiles[x, y].type == 55 || ret.tiles[x, y].type == 85))
                    ret.signs[i] = new Sign()
                    {
                        text = text,
                        position = new Point(x, y)
                    };
            }

            return LoadError.Success;
        }
Пример #10
0
        static LoadError ReadChests(ref WorldFile ret, BinBuffer bb)
        {
            int amt = bb.ReadShort();

            int rItemAmt = bb.ReadShort(), itemAmt, garbageDataAmt;

            if (rItemAmt < Terraria.Chest.maxItems)
            {
                itemAmt = rItemAmt;
                garbageDataAmt = 0;
            }
            else
                garbageDataAmt = rItemAmt - (itemAmt = Terraria.Chest.maxItems);

            for (int i = 0; i < amt; i++)
            {
                ret.chests[i] = new Chest()
                {
                    position = new Point(bb.ReadInt(), bb.ReadInt()),
                    name = PlayerPorter.ReadString(bb)
                };

                for (int j = 0; j < itemAmt; j++)
                {
                    Item it = new Item();

                    short stack = Math.Abs(bb.ReadShort());

                    if (stack <= 0)
                        continue;

                    it.netID = bb.ReadInt();
                    it.prefix = bb.ReadByte();
                    it.stack = stack;

                    ret.chests[i].items[j] = it;
                }
                for (int j = 0; i < garbageDataAmt; j++)
                    if (bb.ReadShort() > 0)
                    {
                        bb.ReadInt();
                        bb.ReadByte();
                    }
            }

            return LoadError.Success;
        }
Пример #11
0
        static LoadError ReadTiles (ref WorldFile ret, BinBuffer bb)
        {
            for (int x = 0; x < ret.size.X; x++)
                for (int y = 0; y < ret.size.Y; y++)
                {
                    int type = -1;

                    // what on earth is this?
                    byte b = 0, b2 = 0, b3 = bb.ReadByte();

                    if ((b3 & 1) != 0)
                    {
                        b2 = bb.ReadByte();
                        if ((b2 & 1) != 0)
                        {
                            b = bb.ReadByte();
                        }
                    }

                    if ((b3 & 2) != 0)
                    {
                        ret.tiles[x, y].Active = true;

                        if ((b3 & 32) != 0)
                            type = bb.ReadByte() | bb.ReadByte() << 8;
                        else
                            type = bb.ReadByte();

                        ret.tiles[x, y].type = (ushort)type;

                        if (importance[type])
                        {
                            ret.tiles[x, y].frameX = bb.ReadShort();
                            ret.tiles[x, y].frameY = bb.ReadShort();

                            if (type == 144)
                                ret.tiles[x, y].frameY = 0;
                        }
                        else
                            ret.tiles[x, y].frameX = ret.tiles[x, y].frameY = -1;

                        if ((b & 8) != 0)
                            ret.tiles[x, y].Colour = bb.ReadByte();
                    }
                    if ((b3 & 4) != 0)
                    {
                        ret.tiles[x, y].wall = bb.ReadByte();

                        if ((b & 16) != 0)
                            ret.tiles[x, y].WallColour = bb.ReadByte();
                    }

                    byte b4 = (byte)((b3 & 24) >> 3);
                    if (b4 != 0)
                    {
                        ret.tiles[x, y].liquid = bb.ReadByte();

                        if (b4 > 1)
                        {
                            if (b4 == 2)
                                ret.tiles[x, y].Lava = true;
                            else
                                ret.tiles[x, y].Honey = true;
                        }
                    }
                    if (b2 > 1)
                    {
                        ret.tiles[x, y].Wire  = (b2 & 2) != 0;
                        ret.tiles[x, y].Wire2 = (b2 & 4) != 0;
                        ret.tiles[x, y].Wire3 = (b2 & 8) != 0;

                        b4 = (byte)((b2 & 112) >> 4);
                        if (b4 != 0)
                        {
                            if (b4 == 1)
                                ret.tiles[x, y].HalfBrick = true;
                            else
                                ret.tiles[x, y].Slope = (byte)(b4 - 1);
                        }
                    }
                    if (b > 0)
                    {
                        ret.tiles[x, y].Actuator = (b & 2) != 0;
                        ret.tiles[x, y].Inactive = (b & 4) != 0;
                    }

                    b4 = (byte)((b3 & 192) >> 6);
                    if (b4 == 1)
                        bb.ReadByte();
                    else if (b4 != 0)
                        bb.ReadShort();
                }

            return LoadError.Success;
        }