Пример #1
0
 static ExtBlock GetFreeBlock(bool global, Level lvl)
 {
     // Start from opposite ends to avoid overlap.
     if (global)
     {
         BlockDefinition[] defs = BlockDefinition.GlobalDefs;
         for (int i = Block.CpeCount; i < Block.Invalid; i++)
         {
             if (defs[i] == null)
             {
                 return(ExtBlock.FromRaw((byte)i));
             }
         }
     }
     else
     {
         BlockDefinition[] defs = lvl.CustomBlockDefs;
         for (int i = Block.Invalid - 1; i >= Block.CpeCount; i--)
         {
             if (defs[i] == null)
             {
                 return(ExtBlock.FromRaw((byte)i));
             }
         }
     }
     return(ExtBlock.Invalid);
 }
Пример #2
0
        bool DoUndoArea(Player p, Vec3S32[] marks, object state, ExtBlock block)
        {
            UndoAreaArgs args = (UndoAreaArgs)state;

            UndoPlayer(p, args.delta, args.names, args.ids, marks);
            return(false);
        }
Пример #3
0
        internal static void C4(Player p, ExtBlock block, ushort x, ushort y, ushort z)
        {
            if (p.level.physics == 0 || p.level.physics == 5)
            {
                p.RevertBlock(x, y, z); return;
            }

            // Use red wool to detonate c4
            ExtBlock held = p.BlockBindings[p.RawHeldBlock.RawID];

            if (held.BlockID == Block.Red)
            {
                Player.Message(p, "Placed detonator block, delete it to detonate.");
                C4Det(p, (ExtBlock)Block.C4Detonator, x, y, z); return;
            }

            if (p.c4circuitNumber == -1)
            {
                sbyte num = C4Physics.NextCircuit(p.level);
                p.level.C4list.Add(new C4Data(num));
                p.c4circuitNumber = num;

                string detonatorName = p.level.BlockName((ExtBlock)Block.Red);
                Player.Message(p, "Place more blocks for more c4, then place a &c{0} %Sblock for the detonator.",
                               detonatorName);
            }

            C4Data c4 = C4Physics.Find(p.level, p.c4circuitNumber);

            if (c4 != null)
            {
                c4.list.Add(p.level.PosToInt(x, y, z));
            }
            p.ChangeBlock(x, y, z, (ExtBlock)Block.C4);
        }
Пример #4
0
        static void CheckBlockBindings(Player who)
        {
            ExtBlock block = who.ModeBlock;

            if (block != ExtBlock.Air && !CommandParser.IsBlockAllowed(who, "place", block))
            {
                who.ModeBlock = ExtBlock.Air;
                Player.Message(who, "   Hence, &b{0} %Smode was turned &cOFF",
                               who.level.BlockName(block));
            }

            for (int i = 0; i < who.BlockBindings.Length; i++)
            {
                block = who.BlockBindings[i];
                ExtBlock defaultBinding = ExtBlock.FromRaw((byte)i);
                if (block == defaultBinding)
                {
                    continue;
                }

                if (!CommandParser.IsBlockAllowed(who, "place", block))
                {
                    who.BlockBindings[i] = defaultBinding;
                    Player.Message(who, "   Hence, binding for &b{0} %Swas unbound",
                                   who.level.BlockName(defaultBinding));
                }
            }
        }
Пример #5
0
        static int FindYAbove(Level lvl, ushort x, ushort y, ushort z)
        {
            for (; y <= lvl.Height; y++)
            {
                ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
                if (above.IsInvalid)
                {
                    continue;
                }
                if (!CollideType.IsSolid(lvl.CollideType(above)))
                {
                    continue;
                }

                int             posY = (y + 1) * 32 - 6;
                BlockDefinition def  = lvl.GetBlockDef(above);
                if (def != null)
                {
                    posY += def.MinZ * 2;
                }

                return(posY);
            }
            return(-1);
        }
Пример #6
0
        public static void OutputMessageBlock(Player p, ExtBlock block,
                                              ushort x, ushort y, ushort z)
        {
            if (!p.level.Props[block.Index].IsMessageBlock)
            {
                return;
            }

            try {
                if (!Database.Backend.TableExists("Messages" + p.level.name))
                {
                    return;
                }
                DataTable messages = Database.Backend.GetRows("Messages" + p.level.name, "*",
                                                              "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
                int last = messages.Rows.Count - 1;
                if (last == -1)
                {
                    messages.Dispose(); return;
                }

                string message = messages.Rows[last]["Message"].ToString().Trim();
                message = message.Replace("\\'", "\'");
                Player.Message(p, "Message Block contents: {0}", message);
            } catch {
            }
        }
Пример #7
0
        protected override bool DoDraw(Player p, Vec3S32[] marks, object state, ExtBlock block)
        {
            DrawArgs dArgs = (DrawArgs)state;
            ushort   x = (ushort)marks[0].X, y = (ushort)marks[0].Y, z = (ushort)marks[0].Z;
            ExtBlock old = p.level.GetBlock(x, y, z);

            if (!CommandParser.IsBlockAllowed(p, "fill over", old))
            {
                return(false);
            }

            if (dArgs.Mode == DrawMode.volcano)
            {
                dArgs.Mode = Calc2DFill(p, marks);
            }
            FillDrawOp op = (FillDrawOp)dArgs.Op;

            op.Positions = FillDrawOp.FloodFill(p, p.level.PosToInt(x, y, z), old, dArgs.Mode);
            int count = op.Positions.Count;

            bool confirmed = IsConfirmed(dArgs.Message), success = true;

            if (count < p.group.DrawLimit && count > p.level.ReloadThreshold && !confirmed)
            {
                Player.Message(p, "This fill would affect {0} blocks.", count);
                Player.Message(p, "If you still want to fill, type %T/Fill {0} confirm", dArgs.Message);
            }
            else
            {
                success = base.DoDraw(p, marks, state, block);
            }

            op.Positions = null;
            return(success);
        }
Пример #8
0
        /// <summary> Loads this copy state from the given stream, using the very old format. </summary>
        public void LoadFromOld(Stream stream, Stream underlying)
        {
            byte[] raw = new byte[underlying.Length];
            underlying.Read(raw, 0, (int)underlying.Length);
            raw = raw.Decompress();
            if (raw.Length == 0)
            {
                return;
            }

            ExtBlock block = default(ExtBlock);

            CalculateBounds(raw);
            for (int i = 0; i < raw.Length; i += 7)
            {
                ushort x = BitConverter.ToUInt16(raw, i + 0);
                ushort y = BitConverter.ToUInt16(raw, i + 2);
                ushort z = BitConverter.ToUInt16(raw, i + 4);

                block.BlockID = raw[i + 6];
                Set(block, x - X, y - Y, z - Z);
            }
            UsedBlocks = Volume;
            OriginX    = X; OriginY = Y; OriginZ = Z;
        }
Пример #9
0
        public ExtBlock Get(int x, int y, int z)
        {
            int index = (y * Length + z) * Width + x;

            return(ExtBlock.FromRaw(raw[index],
                                    (isExt[index >> 3] & (1 << (index & 0x07))) != 0));
        }
Пример #10
0
        bool DoHighlightArea(Player p, Vec3S32[] marks, object state, ExtBlock block)
        {
            HighlightAreaArgs args = (HighlightAreaArgs)state;

            HighlightPlayer(p, args.delta, args.who, args.ids, marks);
            return(false);
        }
Пример #11
0
        protected override void PlacedMark(Player p, ushort x, ushort y, ushort z, ExtBlock block)
        {
            p.RevertBlock(x, y, z);
            if (!p.level.Config.Guns)
            {
                p.ClearBlockchange(); return;
            }
            if (!CommandParser.IsBlockAllowed(p, "use", block))
            {
                return;
            }

            WeaponArgs args = new WeaponArgs();

            args.player     = p;
            args.block      = block;
            args.weaponType = (WeaponType)p.blockchangeObject;

            args.start      = MakePos(p);
            args.dir        = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX);
            args.pos        = args.PosAt(3);
            args.iterations = 4;

            SchedulerTask task = new SchedulerTask(GunCallback, args, TimeSpan.Zero, true);

            p.CriticalTasks.Add(task);
        }
Пример #12
0
        protected static bool HandlesHitBlock(Player p, ExtBlock block, WeaponType ending, Vec3U16 pos, bool doExplode)
        {
            if (p.level.physics < 2 || ending == WeaponType.Teleport || ending == WeaponType.Normal)
            {
                return(true);
            }

            if (ending == WeaponType.Destroy)
            {
                bool fireKills = block.BlockID != Block.Air && p.level.Props[block.Index].LavaKills;
                if ((!fireKills && !Block.NeedRestart(block.BlockID)) && block.BlockID != Block.Glass)
                {
                    return(true);
                }
            }
            else if (p.level.physics >= 3)
            {
                if (block.BlockID != Block.Glass && doExplode)
                {
                    p.level.MakeExplosion(pos.X, pos.Y, pos.Z, 1);
                    return(true);
                }
            }
            else
            {
                return(true);
            }
            return(false);
        }
Пример #13
0
        static void RemoveBlockProps(bool global, ExtBlock block, Player p)
        {
            // Level block reverts to using global block
            if (!global)
            {
                p.level.Props[block.Index] = BlockDefinition.DefaultProps(block);
                p.level.UpdateBlockHandler(block);
                return;
            }

            BlockProps props = BlockProps.MakeDefault();

            if (!block.IsCustomType)
            {
                props = Block.Props[block.RawID];
            }

            BlockDefinition.GlobalProps[block.RawID] = props;
            Level[] loaded = LevelInfo.Loaded.Items;
            byte    raw    = block.RawID;

            foreach (Level lvl in loaded)
            {
                if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw])
                {
                    continue;
                }
                lvl.Props[block.Index] = BlockDefinition.GlobalProps[block.RawID];
                lvl.UpdateBlockHandler(block);
            }
        }
Пример #14
0
        static void MessageAlreadyBlock(Player p, ExtBlock block, bool global, string cmd)
        {
            string scope = global ? "global" : "level";

            Player.Message(p, "&cThere is already a {1} custom block with the id \"{0}\".", block.RawID, scope);
            Player.Message(p, "Type \"%T{0} list\" %Sto see a list of {1} custom blocks.", cmd, scope);
        }
Пример #15
0
        public override void Use(Player p, string message)
        {
            if (message.Length == 0)
            {
                Help(p); return;
            }
            if (!MessageCmd.CanSpeak(p, name))
            {
                return;                                // do not allow using kill to spam every 2 secs
            }
            string[] args   = message.SplitSpaces(2);
            Player   target = PlayerInfo.FindMatches(p, args[0]);
            ExtBlock rock   = (ExtBlock)Block.Stone;

            if (target == null)
            {
                if (p != null)
                {
                    p.HandleDeath(rock, "@p %Skilled themselves in their confusion");
                }
                return;
            }
            if (p != null && (target != p && target.Rank >= p.Rank))
            {
                MessageTooHighRank(p, "kill", false); return;
            }

            bool   explode  = false;
            string killer   = p == null ? "(console)" : p.ColoredName;
            string deathMsg = GetDeathMessage(args, killer, ref explode);

            target.HandleDeath(rock, deathMsg, explode);
        }
Пример #16
0
        static CopyState Rotate(CopyState state, CopyState flipped, int[] m, ExtBlock[] transform)
        {
            int volume = state.Volume;

            for (int i = 0; i < volume; i++)
            {
                ushort x, y, z;
                state.GetCoords(i, out x, out y, out z);
                ExtBlock block = transform[state.Get(i).Index];

                flipped.Set(block,
                            Rotate(m[0], x, y, z, state),
                            Rotate(m[1], x, y, z, state),
                            Rotate(m[2], x, y, z, state));
            }

            int oX = state.OriginX - state.X, oY = state.OriginY - state.Y, oZ = state.OriginZ - state.Z;

            flipped.OriginX = state.X + Rotate(m[0], oX, oY, oZ, state);
            flipped.OriginY = state.Y + Rotate(m[1], oX, oY, oZ, state);
            flipped.OriginZ = state.Z + Rotate(m[2], oX, oY, oZ, state);

            // Offset is relative to Origin
            oX += state.Offset.X; oY += state.Offset.Y; oZ += state.Offset.Z;
            flipped.Offset.X = state.X + Rotate(m[0], oX, oY, oZ, state) - flipped.OriginX;
            flipped.Offset.Y = state.Y + Rotate(m[1], oX, oY, oZ, state) - flipped.OriginY;
            flipped.Offset.Z = state.Z + Rotate(m[2], oX, oY, oZ, state) - flipped.OriginZ;
            return(flipped);
        }
Пример #17
0
        public static void Output(Player p, string name, BlockDBEntry e)
        {
            ExtBlock oldBlock = ExtBlock.FromRaw(e.OldRaw, (e.Flags & BlockDBFlags.OldCustom) != 0);
            ExtBlock newBlock = ExtBlock.FromRaw(e.NewRaw, (e.Flags & BlockDBFlags.NewCustom) != 0);

            DateTime time  = BlockDB.Epoch.AddSeconds(e.TimeDelta);
            TimeSpan delta = DateTime.UtcNow.Subtract(time);

            name = PlayerInfo.GetColoredName(p, name);

            if (newBlock.BlockID == Block.Air)
            {
                Player.Message(p, "{0} ago {1} &4deleted %S{2}{3}",
                               delta.Shorten(true, false), name,
                               p.level.BlockName(oldBlock),
                               FormatReason(e.Flags));
            }
            else
            {
                Player.Message(p, "{0} ago {1} &3placed %S{2}{3}",
                               delta.Shorten(true, false), name,
                               p.level.BlockName(newBlock),
                               FormatReason(e.Flags));
            }
        }
Пример #18
0
        public static void MirrorX(CopyState state, BlockDefinition[] defs)
        {
            // ceiling division by 2, because for odd length, we still want to
            // mirror the middle row to rotate directional blocks
            int midZ = (state.Length + 1) / 2, maxZ = state.Length - 1;

            state.OriginZ  = state.OppositeOriginZ;
            state.Offset.Z = -state.Offset.Z;
            ExtBlock[] transform = Transform(defs, mirrorX, null);

            for (int y = 0; y < state.Height; y++)
            {
                for (int z = 0; z < midZ; z++)
                {
                    int endZ  = maxZ - z;
                    int start = state.GetIndex(0, y, z);
                    int end   = state.GetIndex(0, y, endZ);

                    for (int x = 0; x < state.Width; x++)
                    {
                        ExtBlock blockA = transform[state.Get(start).Index];
                        ExtBlock blockB = transform[state.Get(end).Index];
                        state.Set(blockB, start); state.Set(blockA, end);
                        start++; end++;
                    }
                }
            }
        }
Пример #19
0
        public static void OutputPortal(Player p, ExtBlock block,
                                        ushort x, ushort y, ushort z)
        {
            if (!p.level.Props[block.Index].IsPortal)
            {
                return;
            }

            try {
                if (!Database.Backend.TableExists("Portals" + p.level.name))
                {
                    return;
                }
                DataTable portals = Database.Backend.GetRows("Portals" + p.level.name, "*",
                                                             "WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
                int last = portals.Rows.Count - 1;
                if (last == -1)
                {
                    portals.Dispose(); return;
                }

                string exitMap = portals.Rows[last]["ExitMap"].ToString().Trim();
                ushort exitX   = U16(portals.Rows[last]["ExitX"]);
                ushort exitY   = U16(portals.Rows[last]["ExitY"]);
                ushort exitZ   = U16(portals.Rows[last]["ExitZ"]);
                Player.Message(p, "Portal destination: ({0}, {1}, {2}) in {3}",
                               exitX, exitY, exitZ, exitMap);
            } catch {
            }
        }
Пример #20
0
        public static void MirrorY(CopyState state, BlockDefinition[] defs)
        {
            int midY = (state.Height + 1) / 2, maxY = state.Height - 1;

            state.OriginY  = state.OppositeOriginY;
            state.Offset.Y = -state.Offset.Y;
            ExtBlock[] transform = Transform(defs, mirrorY, null);

            for (int y = 0; y < midY; y++)
            {
                int endY  = maxY - y;
                int start = state.GetIndex(0, y, 0);
                int end   = state.GetIndex(0, endY, 0);

                for (int z = 0; z < state.Length; z++)
                {
                    for (int x = 0; x < state.Width; x++)
                    {
                        ExtBlock blockA = transform[state.Get(start).Index];
                        ExtBlock blockB = transform[state.Get(end).Index];
                        state.Set(blockB, start); state.Set(blockA, end);
                        start++; end++;
                    }
                }
            }
        }
Пример #21
0
        static void GetRaw(string[] parts, Predicate <string> filter, BrushArgs args,
                           out ExtBlock[] blocks, out int[] count)
        {
            int bCount = 0;

            for (int i = 0; i < parts.Length; i++)
            {
                if (parts[i] == "" || !filter(parts[i]))
                {
                    continue;
                }
                bCount++;
            }

            // For 0 or 1 blocks given, treat second block as 'unchanged'.
            blocks = new ExtBlock[Math.Max(2, bCount)];
            count  = new int[blocks.Length];
            for (int i = 0; i < count.Length; i++)
            {
                count[i]  = 1;
                blocks[i] = new ExtBlock(Block.Invalid, 0);
            }

            // No blocks given, assume first is held block
            if (bCount == 0)
            {
                blocks[0] = new ExtBlock(args.Block, args.ExtBlock);
            }
        }
Пример #22
0
        public static void MirrorZ(CopyState state, BlockDefinition[] defs)
        {
            int midX = (state.Width + 1) / 2, maxX = state.Width - 1;

            state.OriginX  = state.OppositeOriginX;
            state.Offset.X = -state.Offset.X;
            ExtBlock[] transform = Transform(defs, mirrorZ, null);

            for (int y = 0; y < state.Height; y++)
            {
                for (int z = 0; z < state.Length; z++)
                {
                    for (int x = 0; x < midX; x++)
                    {
                        int endX  = maxX - x;
                        int start = state.GetIndex(x, y, z);
                        int end   = state.GetIndex(endX, y, z);

                        ExtBlock blockA = transform[state.Get(start).Index];
                        ExtBlock blockB = transform[state.Get(end).Index];
                        state.Set(blockB, start); state.Set(blockA, end);
                    }
                }
            }
        }
Пример #23
0
        static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z,
                                   int dx, int dy, int dz)
        {
            ExtBlock block = lvl.GetBlock((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));

            if (block.BlockID == Block.Air)
            {
                return;
            }
            if (!lvl.Props[block.Index].LavaKills)
            {
                return;
            }

            if (dx != 0)
            {
                lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), y, z), Block.Fire);
            }
            if (dy != 0)
            {
                lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + dy), z), Block.Fire);
            }
            if (dz != 0)
            {
                lvl.AddUpdate(lvl.PosToInt(x, y, (ushort)(z + dz)), Block.Fire);
            }
        }
Пример #24
0
        internal static void HandlePlayerClick(Player p, MouseButton button, MouseAction action, ushort yaw, ushort pitch,
                                               byte entity, ushort x, ushort y, ushort z, TargetBlockFace face)
        {
            if (action != MouseAction.Pressed)
            {
                return;
            }

            if (entity != Entities.SelfID && ClickOnBot(p, entity))
            {
                return;
            }

            if (p.level.Config.Deletable || !p.level.IsValidPos(x, y, z))
            {
                return;
            }
            ExtBlock block    = p.level.GetBlock(x, y, z);
            bool     isMB     = p.level.Props[block.Index].IsMessageBlock;
            bool     isPortal = p.level.Props[block.Index].IsPortal;

            if (isMB)
            {
                MessageBlock.Handle(p, x, y, z, true);
            }
            if (isPortal)
            {
                Portal.Handle(p, x, y, z);
            }
        }
Пример #25
0
        static string Format(ExtBlock block, Level lvl, BlockProps[] props)
        {
            if (!props[block.Index].IsPortal)
            {
                return(null);
            }

            // We want to use the simple aliases if possible
            if (block.BlockID == Block.Portal_Orange)
            {
                return("orange");
            }
            if (block.BlockID == Block.Portal_Blue)
            {
                return("blue");
            }
            if (block.BlockID == Block.Portal_Air)
            {
                return("air");
            }
            if (block.BlockID == Block.Portal_Lava)
            {
                return("lava");
            }
            if (block.BlockID == Block.Portal_Water)
            {
                return("water");
            }

            return(lvl == null?Block.Name(block.BlockID) : lvl.BlockName(block));
        }
Пример #26
0
        public static void DoAir(Level lvl, ref Check C)
        {
            ushort x, y, z;

            lvl.IntToPos(C.b, out x, out y, out z);

            ActivateablePhysics.CheckNeighbours(lvl, x, y, z);
            ActivateablePhysics.CheckAt(lvl, lvl.PosToInt(x, (ushort)(y - 1), z));

            //Edge of map water
            if (lvl.Config.EdgeWater && (y < lvl.Config.EdgeLevel && y >= (lvl.Config.EdgeLevel + lvl.Config.SidesOffset)))
            {
                if (x == 0 || x == lvl.Width - 1 || z == 0 || z == lvl.Length - 1)
                {
                    ExtBlock    block = ExtBlock.FromRaw((byte)lvl.Config.HorizonBlock);
                    PhysicsArgs args  = default(PhysicsArgs);
                    args.ExtBlock = block.BlockID == Block.custom_block;
                    lvl.AddUpdate(C.b, block.RawID, false, args);
                }
            }
            if (!C.data.HasWait)
            {
                C.data.Data = PhysicsArgs.RemoveFromChecks;
            }
        }
Пример #27
0
        /// <summary> Retrieves the default walkthrough block handler for the given block. </summary>
        internal static HandleWalkthrough GetWalkthroughHandler(ExtBlock block, BlockProps[] props, bool nonSolid)
        {
            switch (block.BlockID)
            {
            case Block.Checkpoint: return(WalkthroughBehaviour.Checkpoint);

            case Block.Door_AirActivatable: return(WalkthroughBehaviour.Door);

            case Block.Door_Water: return(WalkthroughBehaviour.Door);

            case Block.Door_Lava: return(WalkthroughBehaviour.Door);

            case Block.Train: return(WalkthroughBehaviour.Train);
            }

            int i = block.Index;

            if (props[i].IsMessageBlock && nonSolid)
            {
                return(WalkthroughBehaviour.DoMessageBlock);
            }
            if (props[i].IsPortal && nonSolid)
            {
                return(WalkthroughBehaviour.DoPortal);
            }
            return(null);
        }
Пример #28
0
        internal static bool Handles(Player p, ushort x, ushort y, ushort z,
                                     bool placing, ExtBlock block, ExtBlock old, ZSGame game)
        {
            if (placing && !game.Map.Config.Pillaring && !p.Game.Referee)
            {
                if (NotPillaring(game.Map, block, old))
                {
                    p.Game.BlocksStacked = 0;
                }
                else if (CheckCoords(p, x, y, z))
                {
                    p.Game.BlocksStacked++;
                }
                else
                {
                    p.Game.BlocksStacked = 0;
                }

                if (MessagePillaring(p, x, y, z))
                {
                    return(true);
                }
            }
            p.Game.LastX = x; p.Game.LastY = y; p.Game.LastZ = z;
            return(false);
        }
Пример #29
0
        static ExtBlock[] MostFrequentBlocks(int[] countsRaw)
        {
            ExtBlock[] blocks = new ExtBlock[512];
            int[]      counts = new int[512]; // copy array as Sort works in place
            int        total  = 0;

            for (int i = 0; i < blocks.Length; i++)
            {
                blocks[i] = ExtBlock.FromIndex(i);
                counts[i] = countsRaw[i];
                if (counts[i] > 0)
                {
                    total++;
                }
            }
            Array.Sort(counts, blocks);

            if (total > 5)
            {
                total = 5;
            }
            ExtBlock[] mostFrequent = new ExtBlock[total];
            for (int i = 0; i < total; i++)
            {
                mostFrequent[i] = blocks[blocks.Length - 1 - i];
            }
            return(mostFrequent);
        }
Пример #30
0
        internal static void C4Det(Player p, ExtBlock block, ushort x, ushort y, ushort z)
        {
            int index = p.level.PosToInt(x, y, z);

            C4Physics.BlowUp(index, p.level);
            p.ChangeBlock(x, y, z, ExtBlock.Air);
        }