Exemple #1
0
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            int x = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            int y = BitConverter.ToInt32(readBuffer, num);

            if (Main.tile.At(x, y).Type != 21)
            {
                return;
            }

            var player = Main.players[whoAmI];

            var ctx = new HookContext
            {
                Connection = player.Connection,
                Player     = player,
                Sender     = player,
            };

            var args = new HookArgs.ChestBreakReceived
            {
                X = x, Y = y,
            };

            HookPoints.ChestBreakReceived.Invoke(ref ctx, ref args);

            if (ctx.CheckForKick())
            {
                return;
            }

            if (ctx.Result == HookResult.IGNORE)
            {
                return;
            }

            if (ctx.Result == HookResult.RECTIFY)
            {
                NetMessage.SendTileSquare(whoAmI, x, y, 3);
                return;
            }

            WorldModify.KillTile(null, null, x, y);

            if (!Main.tile.At(x, y).Active || Main.tile.At(x, y).Type != 21)
            {
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void AddWater(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, int x, int y)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            if (TileRefs(x, y).CheckingLiquid || (x >= Main.maxTilesX - 5 || y >= Main.maxTilesY - 5) || (x < 5 || y < 5) || TileRefs(x, y).Liquid == 0)
            {
                return;
            }

            if (Liquid.numLiquid >= Liquid.maxLiquid - 1)
            {
                LiquidBuffer.AddBuffer(TileRefs, x, y);
                return;
            }

            TileRefs(x, y).SetCheckingLiquid(true);
            Main.liquid[Liquid.numLiquid].kill  = 0;
            Main.liquid[Liquid.numLiquid].x     = x;
            Main.liquid[Liquid.numLiquid].y     = y;
            Main.liquid[Liquid.numLiquid].delay = 0;
            TileRefs(x, y).SetSkipLiquid(false);

            Liquid.numLiquid++;

            if (Liquid.numLiquid < Liquid.maxLiquid / 3)
            {
                NetMessage.SendWater(x, y);
            }
            if (TileRefs(x, y).Active&& (Main.tileWaterDeath[(int)TileRefs(x, y).Type] || (TileRefs(x, y).Lava&& Main.tileLavaDeath[(int)TileRefs(x, y).Type])))
            {
                if (TileRefs(x, y).Type == 4 && TileRefs(x, y).FrameY == 176)
                {
                    return;
                }

                if (WorldModify.gen)
                {
                    TileRefs(x, y).SetActive(false);
                    return;
                }
                WorldModify.KillTile(TileRefs, sandbox, x, y);
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void HitTiles(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, Vector2 Position, Vector2 Velocity, int Width, int Height)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            Vector2 nextPos = Position + Velocity;
            int     left    = (int)(Position.X / 16f) - 1;
            int     right   = (int)((Position.X + (float)Width) / 16f) + 2;
            int     top     = (int)(Position.Y / 16f) - 1;
            int     bottom  = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (TileRefs(i, j).Active&& (Main.tileSolid[(int)TileRefs(i, j).Type] || (Main.tileSolidTop[(int)TileRefs(i, j).Type] && TileRefs(i, j).FrameY == 0)))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        if (nextPos.X + (float)Width >= vector2.X && nextPos.X <= vector2.X + 16f && nextPos.Y + (float)Height >= vector2.Y && nextPos.Y <= vector2.Y + 16f)
                        {
                            WorldModify.KillTile(TileRefs, sandbox, i, j, true, true);
                        }
                    }
                }
            }
        }
        public static void AddWater(int x, int y)
        {
            if (Main.tile.At(x, y).CheckingLiquid)
            {
                return;
            }
            if (x >= Main.maxTilesX - 5 || y >= Main.maxTilesY - 5)
            {
                return;
            }
            if (x < 5 || y < 5)
            {
                return;
            }
            if (Main.tile.At(x, y).Liquid == 0)
            {
                return;
            }
            if (Liquid.numLiquid >= Liquid.maxLiquid - 1)
            {
                LiquidBuffer.AddBuffer(x, y);
                return;
            }
            Main.tile.At(x, y).SetCheckingLiquid(true);
            Main.liquid[Liquid.numLiquid].kill  = 0;
            Main.liquid[Liquid.numLiquid].x     = x;
            Main.liquid[Liquid.numLiquid].y     = y;
            Main.liquid[Liquid.numLiquid].delay = 0;
            Main.tile.At(x, y).SetSkipLiquid(false);
            Liquid.numLiquid++;

            NetMessage.SendWater(x, y);

            if (Main.tile.At(x, y).Active&& (Main.tileWaterDeath[(int)Main.tile.At(x, y).Type] || (Main.tile.At(x, y).Lava&& Main.tileLavaDeath[(int)Main.tile.At(x, y).Type])))
            {
                if (WorldModify.gen)
                {
                    Main.tile.At(x, y).SetActive(false);
                    return;
                }
                WorldModify.KillTile(x, y, false, false, false);
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void HitTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
        {
            Vector2 nextPos = Position + Velocity;
            int     left    = (int)(Position.X / 16f) - 1;
            int     right   = (int)((Position.X + (float)Width) / 16f) + 2;
            int     top     = (int)(Position.Y / 16f) - 1;
            int     bottom  = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (Main.tile.At(i, j).Active&& (Main.tileSolid[(int)Main.tile.At(i, j).Type] || (Main.tileSolidTop[(int)Main.tile.At(i, j).Type] && Main.tile.At(i, j).FrameY == 0)))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        if (nextPos.X + (float)Width >= vector2.X && nextPos.X <= vector2.X + 16f && nextPos.Y + (float)Height >= vector2.Y && nextPos.Y <= vector2.Y + 16f)
                        {
                            WorldModify.KillTile(i, j, true, true, false);
                        }
                    }
                }
            }
        }
        public static Vector2 HurtTiles(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, Vector2 Position, Vector2 Velocity, int Width, int Height, bool fireImmune = false)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            int left   = (int)(Position.X / 16f) - 1;
            int right  = (int)((Position.X + (float)Width) / 16f) + 2;
            int top    = (int)(Position.Y / 16f) - 1;
            int bottom = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (TileRefs(i, j).Active&& (TileRefs(i, j).Type == 32 || TileRefs(i, j).Type == 37 || TileRefs(i, j).Type == 48 || TileRefs(i, j).Type == 53 || TileRefs(i, j).Type == 57 || TileRefs(i, j).Type == 58 || TileRefs(i, j).Type == 59 || TileRefs(i, j).Type == 69 || TileRefs(i, j).Type == 76 || TileRefs(i, j).Type == 80))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        int Y    = 0;
                        int type = (int)TileRefs(i, j).Type;
                        if (type == 32 || type == 69 || type == 80)
                        {
                            if (Position.X + (float)Width > vector2.X && Position.X < vector2.X + 16f && Position.Y + (float)Height > vector2.Y && (double)Position.Y < (double)vector2.Y + 16.01)
                            {
                                int directionX = 1;
                                if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                                {
                                    directionX = -1;
                                }

                                Y = 10;
                                if (type == 69)
                                {
                                    Y = 17;
                                }
                                else if (type == 80)
                                {
                                    Y = 6;
                                }
                                if (type == 32 || type == 69)
                                {
                                    WorldModify.KillTile(TileRefs, sandbox, i, j);
                                }

                                return(new Vector2((float)directionX, (float)Y));
                            }
                        }
                        else if (type == 53 || type == 112 || type == 116 || type == 123)
                        {
                            if (Position.X + (float)Width - 2f >= vector2.X && Position.X + 2f <= vector2.X + 16f && Position.Y + (float)Height - 2f >= vector2.Y && Position.Y + 2f <= vector2.Y + 16f)
                            {
                                int directionX = 1;
                                if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                                {
                                    directionX = -1;
                                }

                                Y = 20;
                                return(new Vector2((float)directionX, (float)Y));
                            }
                        }
                        else if (Position.X + (float)Width >= vector2.X && Position.X <= vector2.X + 16f && Position.Y + (float)Height >= vector2.Y && (double)Position.Y <= (double)vector2.Y + 16.01)
                        {
                            int directionX = 1;
                            if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                            {
                                directionX = -1;
                            }

                            if (!fireImmune && (type == 37 || type == 58 || type == 76))
                            {
                                Y = 20;
                            }
                            if (type == 48)
                            {
                                Y = 40;
                            }

                            return(new Vector2((float)directionX, (float)Y));
                        }
                    }
                }
            }
            return(default(Vector2));
        }
        public static bool SaveWorld(string savePath, bool resetTime = false)
        {
            bool success = true;

            if (savePath == null || WorldModify.saveLock)
            {
                return(false);
            }

            try
            {
                WorldModify.saveLock = true;
                //while (WorldIO.hardLock)
                //{
                //    WorldModify.statusText = "Setting hard mode...";
                //    Thread.Sleep(100);
                //}
                lock (padlock)
                {
                    bool value = Main.dayTime;
                    tempTime      = Main.Time;
                    tempMoonPhase = Main.moonPhase;
                    tempBloodMoon = Main.bloodMoon;

                    if (resetTime)
                    {
                        value         = true;
                        tempTime      = 13500.0;
                        tempMoonPhase = 0;
                        tempBloodMoon = false;
                    }

                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    string tempPath = savePath + ".sav";
                    using (FileStream fileStream = new FileStream(tempPath, FileMode.Create))
                    {
                        using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                        {
                            binaryWriter.Write(Statics.CURRENT_TERRARIA_RELEASE);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);
                            binaryWriter.Write((int)Main.leftWorld);
                            binaryWriter.Write((int)Main.rightWorld);
                            binaryWriter.Write((int)Main.topWorld);
                            binaryWriter.Write((int)Main.bottomWorld);
                            binaryWriter.Write(Main.maxTilesY);
                            binaryWriter.Write(Main.maxTilesX);
                            binaryWriter.Write(Main.spawnTileX);
                            binaryWriter.Write(Main.spawnTileY);
                            binaryWriter.Write(Main.worldSurface);
                            binaryWriter.Write(Main.rockLayer);
                            binaryWriter.Write(tempTime);
                            binaryWriter.Write(value);
                            binaryWriter.Write(tempMoonPhase);
                            binaryWriter.Write(tempBloodMoon);
                            binaryWriter.Write(Main.dungeonX);
                            binaryWriter.Write(Main.dungeonY);
                            binaryWriter.Write(NPC.downedBoss1);
                            binaryWriter.Write(NPC.downedBoss2);
                            binaryWriter.Write(NPC.downedBoss3);
                            binaryWriter.Write(NPC.savedGoblin);
                            binaryWriter.Write(NPC.savedWizard);
                            binaryWriter.Write(NPC.savedMech);
                            binaryWriter.Write(NPC.downedGoblins);
                            binaryWriter.Write(NPC.downedClown);
                            binaryWriter.Write(NPC.downedFrost);
                            binaryWriter.Write(WorldModify.shadowOrbSmashed);
                            binaryWriter.Write(WorldModify.spawnMeteor);
                            binaryWriter.Write((byte)WorldModify.shadowOrbCount);
                            binaryWriter.Write(WorldModify.altarCount);
                            binaryWriter.Write(Main.hardMode);
                            binaryWriter.Write(Main.invasionDelay);
                            binaryWriter.Write(Main.invasionSize);
                            binaryWriter.Write((int)Main.invasionType);
                            binaryWriter.Write(Main.invasionX);

                            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Saving world data"))
                            {
                                for (int x = 0; x < Main.maxTilesX; x++)
                                {
                                    prog.Value = x;

                                    for (int y = 0; y < Main.maxTilesY; y++)
                                    {
                                        if (Main.tile.At(x, y).Type == 127 && Main.tile.At(x, y).Active)
                                        {
                                            WorldModify.KillTile(null, null, x, y);
                                            WorldModify.KillTile(null, null, x, y);
                                            if (!Main.tile.At(x, y).Active)
                                            {
                                                NetMessage.SendData(17, -1, -1, String.Empty, 0, (float)x, (float)y);
                                            }
                                        }

                                        var tile = Main.tile.At(x, y);                                         //.FieldwiseClone();
                                        binaryWriter.Write(tile.Active);
                                        if (tile.Active)
                                        {
                                            binaryWriter.Write(tile.Type);
                                            if (Main.tileFrameImportant[(int)tile.Type])
                                            {
                                                binaryWriter.Write(tile.FrameX);
                                                binaryWriter.Write(tile.FrameY);
                                            }
                                        }

                                        //binaryWriter.Write(tile.Lighted);
                                        if (Main.tile.At(x, y).Wall > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Wall);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }

                                        if (tile.Liquid > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Liquid);
                                            binaryWriter.Write(tile.Lava);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }
                                        binaryWriter.Write(tile.Wire);
                                        int num2 = 1;

                                        while (y + num2 < Main.maxTilesY && World.IsTileTheSame(tile, Main.tile.At(x, y + num2)))
                                        {
                                            num2++;
                                        }

                                        num2--;
                                        binaryWriter.Write((short)num2);
                                        y += num2;
                                    }
                                }
                            }

                            Chest chest;
                            for (int i = 0; i < Main.MAX_CHESTS; i++)
                            {
                                chest = Main.chest[i];
                                if (chest == default(Chest))
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(chest.x);
                                    binaryWriter.Write(chest.y);
                                    for (int l = 0; l < Chest.MAX_ITEMS; l++)
                                    {
                                        if (chest.contents[l].Type == 0)
                                        {
                                            chest.contents[l].Stack = 0;
                                        }
                                        binaryWriter.Write((byte)chest.contents[l].Stack);
                                        if (chest.contents[l].Stack > 0)
                                        {
                                            binaryWriter.Write(chest.contents[l].NetID);
                                            binaryWriter.Write(chest.contents[l].Prefix);
                                        }
                                    }
                                }
                            }

                            Sign sign;
                            for (int i = 0; i < Main.MAX_SIGNS; i++)
                            {
                                sign = Main.sign[i];
                                if (sign == default(Sign) || sign.text == null)
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(sign.text);
                                    binaryWriter.Write(sign.x);
                                    binaryWriter.Write(sign.y);
                                }
                            }

                            NPC npc;
                            for (int i = 0; i < NPC.MAX_NPCS; i++)
                            {
                                npc = (NPC)Main.npcs[i].Clone();
                                if (npc.Active && npc.townNPC)
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(npc.Name);
                                    binaryWriter.Write(npc.Position.X);
                                    binaryWriter.Write(npc.Position.Y);
                                    binaryWriter.Write(npc.homeless);
                                    binaryWriter.Write(npc.homeTileX);
                                    binaryWriter.Write(npc.homeTileY);
                                }
                            }

                            binaryWriter.Write(false);
                            binaryWriter.Write(Main.chrName[17]);
                            binaryWriter.Write(Main.chrName[18]);
                            binaryWriter.Write(Main.chrName[19]);
                            binaryWriter.Write(Main.chrName[20]);
                            binaryWriter.Write(Main.chrName[22]);
                            binaryWriter.Write(Main.chrName[54]);
                            binaryWriter.Write(Main.chrName[38]);
                            binaryWriter.Write(Main.chrName[107]);
                            binaryWriter.Write(Main.chrName[108]);
                            binaryWriter.Write(Main.chrName[124]);
                            binaryWriter.Write(true);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);

                            binaryWriter.Close();
                            fileStream.Close();

                            if (File.Exists(savePath))
                            {
                                ProgramLog.Log("Backing up world file...");
                                string destFileName = savePath + ".bak";
                                File.Copy(savePath, destFileName, true);
                                try
                                {
                                    File.Delete(destFileName);
                                }
                                catch (Exception e)
                                {
                                    ProgramLog.Log(e, "Exception removing " + destFileName);
                                }
                                File.Move(savePath, destFileName);
                            }
                        }

                        try
                        {
                            File.Move(tempPath, savePath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception moving " + tempPath);
                        }

                        try
                        {
                            File.Delete(tempPath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception removing " + tempPath);
                        }
                    }
                    stopwatch.Stop();
                    ProgramLog.Log("Save duration: " + stopwatch.Elapsed.Seconds + " Second(s)");
                }
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception saving the world");
                success = false;
            }
            finally
            {
                WorldModify.saveLock = false;
            }

            return(success);
        }