Example #1
0
        /// <summary> Handles manually-placed/deleted blocks.
        /// Returns true if player's action should result in a kick. </summary>
        public bool PlaceBlock(short x, short y, short h, bool buildMode, Block type)
        {
            LastUsedBlockType = type;

            // check if player is frozen or too far away to legitimately place a block
            if (Info.IsFrozen ||
                Math.Abs(x * 32 - Position.X) > MaxRange ||
                Math.Abs(y * 32 - Position.Y) > MaxRange ||
                Math.Abs(h * 32 - Position.H) > MaxRange)
            {
                RevertBlockNow(x, y, h);
                return(false);
            }

            if (World.IsLocked)
            {
                RevertBlockNow(x, y, h);
                Message("This map is currently locked (read-only).");
                return(false);
            }

            if (CheckBlockSpam())
            {
                return(true);
            }

            // bindings
            bool requiresUpdate = (type != bindings[(byte)type] || IsPainting);

            if (!buildMode && !IsPainting)
            {
                type = Block.Air;
            }
            type = bindings[(byte)type];

            // selection handling
            if (SelectionMarksExpected > 0)
            {
                RevertBlockNow(x, y, h);
                AddSelectionMark(new Position(x, y, h), true);
                return(false);
            }

            CanPlaceResult canPlaceResult;

            if (type == Block.Stair && h > 0 && World.Map.GetBlock(x, y, h - 1) == Block.Stair)
            {
                // stair stacking
                canPlaceResult = CanPlace(x, y, h - 1, Block.DoubleStair, true);
            }
            else
            {
                // normal placement
                canPlaceResult = CanPlace(x, y, h, type, true);
            }

            // if all is well, try placing it
            switch (canPlaceResult)
            {
            case CanPlaceResult.Allowed:
                BlockUpdate blockUpdate;
                if (type == Block.Stair && h > 0 && World.Map.GetBlock(x, y, h - 1) == Block.Stair)
                {
                    // handle stair stacking
                    blockUpdate = new BlockUpdate(this, x, y, h - 1, Block.DoubleStair);
                    if (!World.FireChangedBlockEvent(ref blockUpdate))
                    {
                        RevertBlockNow(x, y, h);
                        return(false);
                    }
                    Info.ProcessBlockPlaced((byte)Block.DoubleStair);
                    World.Map.QueueUpdate(blockUpdate);
                    Server.RaisePlayerPlacedBlockEvent(this, x, y, (short)(h - 1), Block.Stair, Block.DoubleStair, true);
                    Session.SendNow(PacketWriter.MakeSetBlock(x, y, h - 1, Block.DoubleStair));
                    RevertBlockNow(x, y, h);
                    break;
                }
                else
                {
                    // handle normal blocks
                    blockUpdate = new BlockUpdate(this, x, y, h, type);
                    if (!World.FireChangedBlockEvent(ref blockUpdate))
                    {
                        RevertBlockNow(x, y, h);
                        return(false);
                    }
                    Info.ProcessBlockPlaced((byte)type);
                    Block old = World.Map.GetBlock(x, y, h);
                    World.Map.QueueUpdate(blockUpdate);
                    Server.RaisePlayerPlacedBlockEvent(this, x, y, h, old, type, true);
                    if (requiresUpdate || RelayAllUpdates)
                    {
                        Session.SendNow(PacketWriter.MakeSetBlock(x, y, h, type));
                    }
                }
                break;

            case CanPlaceResult.BlocktypeDenied:
                Message("&WYou are not permitted to affect this block type.");
                RevertBlockNow(x, y, h);
                break;

            case CanPlaceResult.RankDenied:
                Message("&WYour rank is not allowed to build.");
                RevertBlockNow(x, y, h);
                break;

            case CanPlaceResult.WorldDenied:
                switch (World.BuildSecurity.CheckDetailed(Info))
                {
                case SecurityCheckResult.RankTooLow:
                case SecurityCheckResult.RankTooHigh:
                    Message("&WYour rank is not allowed to build in this world.");
                    break;

                case SecurityCheckResult.BlackListed:
                    Message("&WYou are not allowed to build in this world.");
                    break;
                }
                RevertBlockNow(x, y, h);
                break;

            case CanPlaceResult.ZoneDenied:
                Zone deniedZone = World.Map.FindDeniedZone(x, y, h, this);
                if (deniedZone != null)
                {
                    Message("&WYou are not allowed to build in zone \"{0}\".", deniedZone.Name);
                }
                else
                {
                    Message("&WYou are not allowed to build here.");
                }
                RevertBlockNow(x, y, h);
                break;

            case CanPlaceResult.PluginDenied:
                RevertBlockNow(x, y, h);
                break;

                //case CanPlaceResult.PluginDeniedNoUpdate:
                //    break;
            }
            return(false);
        }