Пример #1
0
        static void Place(Player player, Command cmd)
        {
            if (player.LastUsedBlockType != Block.Undefined)
            {
                Vector3I Pos = new Vector3I(player.Position.X / 32, player.Position.Y / 32, (player.Position.Z / 32) - 2);

                if (player.CanPlace(player.World.Map, Pos, player.LastUsedBlockType, BlockChangeContext.Manual) != CanPlaceResult.Allowed)
                {
                    player.Message("&WYou are not allowed to build here");
                    return;
                }

                Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), player.LastUsedBlockType, BlockChangeContext.Manual);
                BlockUpdate blockUpdate = new BlockUpdate(null, Pos, player.LastUsedBlockType);
                player.World.Map.QueueUpdate(blockUpdate);
                player.Message("Block placed below your feet");
            }
            else player.Message("&WError: No last used blocktype was found");
        }
Пример #2
0
        static void MessageBlockAdd( Player player, Vector3I[] marks, object tag )
        {
            string Message = ( string )tag;
            Vector3I mark = marks[0];
            if ( !player.Info.Rank.AllowSecurityCircumvention ) {
                SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info );
                switch ( buildCheck ) {
                    case SecurityCheckResult.BlackListed:
                        player.Message( "Cannot add a MessageBlock to world {0}&S: You are barred from building here.",
                                        player.World.ClassyName );
                        return;
                    case SecurityCheckResult.RankTooLow:
                        player.Message( "Cannot add a MessageBlock to world {0}&S: You are not allowed to build here.",
                                        player.World.ClassyName );
                        return;
                    //case SecurityCheckResult.RankTooHigh:
                }
            }
            if ( player.LastUsedBlockType != Block.Undefined ) {
                Vector3I Pos = mark;

                if ( player.CanPlace( player.World.Map, Pos, player.LastUsedBlockType, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) {
                    player.Message( "&WYou are not allowed to build here" );
                    return;
                }

                Player.RaisePlayerPlacedBlockEvent( player, player.WorldMap, Pos, player.WorldMap.GetBlock( Pos ), player.LastUsedBlockType, BlockChangeContext.Manual );
                BlockUpdate blockUpdate = new BlockUpdate( null, Pos, player.LastUsedBlockType );
                player.World.Map.QueueUpdate( blockUpdate );
            } else {
                player.Message( "&WError: No last used blocktype was found" );
                return;
            }
            MessageBlock MessageBlock = new MessageBlock( player.World.Name, mark,
                MessageBlock.GenerateName( player.World ),
                player.ClassyName, Message );
            MessageBlock.Range = new MessageBlockRange( mark.X, mark.X, mark.Y, mark.Y, mark.Z, mark.Z );

            MessageBlockHandler.CreateMessageBlock( MessageBlock, player.World );
            NormalBrush brush = new NormalBrush( Block.Air );
            Logger.Log( LogType.UserActivity, "{0} created MessageBlock {1} (on world {2})", player.Name, MessageBlock.Name, player.World.Name );
            player.Message( "MessageBlock created on world {0}&S with name {1}", player.World.ClassyName, MessageBlock.Name );
        }
Пример #3
0
        //stolen from BuildingCommands
        #region DrawOneBlock
        static void DrawOneBlock ( Player player, Map map, Block drawBlock, Vector3I coord,
                                 BlockChangeContext context, ref int blocks, ref int blocksDenied, fCraft.Drawing.UndoState undoState ) {
            if ( map == null ) return;
            if ( player == null ) throw new ArgumentNullException( "player" );

            if ( !map.InBounds( coord ) ) return;
            Block block = map.GetBlock( coord );
            if ( block == drawBlock ) return;

            if ( player.CanPlace( map, coord, drawBlock, context ) != CanPlaceResult.Allowed ) {
                blocksDenied++;
                return;
            }

            map.QueueUpdate( new BlockUpdate( null, coord, drawBlock ) );
            Player.RaisePlayerPlacedBlockEvent( player, map, coord, block, drawBlock, context );

            if ( !undoState.IsTooLargeToUndo ) {
                if ( !undoState.Add( coord, block ) ) {
                    player.Message( "NOTE: This draw command is too massive to undo." );
                    player.LastDrawOp = null;
                }
            }
            blocks++;
        }
Пример #4
0
        static void DoorAdd( Player player, Vector3I[] marks, object tag )
        {
            int sx = Math.Min( marks[0].X, marks[1].X );
            int ex = Math.Max( marks[0].X, marks[1].X );
            int sy = Math.Min( marks[0].Y, marks[1].Y );
            int ey = Math.Max( marks[0].Y, marks[1].Y );
            int sh = Math.Min( marks[0].Z, marks[1].Z );
            int eh = Math.Max( marks[0].Z, marks[1].Z );

            int volume = ( ex - sx + 1 ) * ( ey - sy + 1 ) * ( eh - sh + 1 );
            if ( volume > 30 ) {
                player.Message( "Doors are only allowed to be {0} blocks", 30 );
                return;
            }
            if ( !player.Info.Rank.AllowSecurityCircumvention ) {
                SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info );
                switch ( buildCheck ) {
                    case SecurityCheckResult.BlackListed:
                        player.Message( "Cannot add a door to world {0}&S: You are barred from building here.",
                                        player.World.ClassyName );
                        return;
                    case SecurityCheckResult.RankTooLow:
                        player.Message( "Cannot add a door to world {0}&S: You are not allowed to build here.",
                                        player.World.ClassyName );
                        return;
                    //case SecurityCheckResult.RankTooHigh:
                }
            }
            List<Vector3I> blocks = new List<Vector3I>();
            for ( int x = sx; x < ex; x++ ) {
                for ( int y = sy; y < ey; y++ ) {
                    for ( int z = sh; z < eh; z++ ) {
                        if ( player.CanPlace( player.World.Map, new Vector3I( x, y, z ), Block.Wood, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) {
                            player.Message( "Cannot add a door to world {0}&S: Build permissions in this area replied with 'denied'.",
                                        player.World.ClassyName );
                            return;
                        }
                        blocks.Add( new Vector3I( x, y, z ) );
                    }
                }
            }

            Door door = new Door( player.World.Name,
                blocks.ToArray(),
                fCraft.Doors.Door.GenerateName( player.World ),
                player.ClassyName );
            door.Range = new DoorRange( sx, ex, sy, ey, sh, eh );

            DoorHandler.CreateDoor( door, player.World );
            Logger.Log( LogType.UserActivity, "{0} created door {1} (on world {2})", player.Name, door.Name, player.World.Name );
            player.Message( "Door created on world {0}&S with name {1}", player.World.ClassyName, door.Name );
        }
Пример #5
0
        private static void DisPlace(Player player, CommandReader cmd) {
            Block block;
            if (cmd.Count <= 2) {
                player.Message(CdDisPlace.Usage);
                return;
            }
            string tryBlock = cmd.Next();
            if (!Map.GetBlockByName(tryBlock, false, out block)) {
                player.Message("Invalid block name/id: {0}", tryBlock);
                return;
            }
            int dis;
            string tryInt = cmd.Next();
            if (!int.TryParse(tryInt, out dis)) {
                player.Message("Invalid distance: {0}", tryInt);
                return;
            }
            dis = dis*32;
            byte rot = player.Position.R;
            byte ud = player.Position.L;
            if (225 < ud || ud < 32) {
                if (225 <= rot || rot <= 32) {
                    Vector3I Pos = new Vector3I(player.Position.X/32, (player.Position.Y - dis)/32,
                        (player.Position.Z - 32)/32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32);
                } else if (33 <= rot && rot <= 96) {
                    Vector3I Pos = new Vector3I((player.Position.X + dis)/32, player.Position.Y/32,
                        (player.Position.Z - 32) / 32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32);
                } else if (97 <= rot && rot <= 160) {
                    Vector3I Pos = new Vector3I(player.Position.X/32, (player.Position.Y + dis)/32,
                        (player.Position.Z - 32) / 32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32);
                } else if (161 <= rot && rot <= 224) {
                    Vector3I Pos = new Vector3I((player.Position.X - dis)/32, player.Position.Y/32,
                        (player.Position.Z - 32) / 32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32);
                } else {
                    player.Message("Error occurred, please try again.");
                    return;
                }
            } else {
                if (192 <= ud && ud <= 224) {
                    Vector3I Pos = new Vector3I(player.Position.X/32, player.Position.Y/32,
                        (player.Position.Z - 32 + dis) / 32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis / 32);
                } else if (33 <= ud && ud <= 65) {
                    Vector3I Pos = new Vector3I(player.Position.X/32, player.Position.Y/32,
                        (player.Position.Z - 32 - dis) / 32);
                    Pos.X = Math.Min(player.WorldMap.Width - 1, Math.Max(0, Pos.X));
                    Pos.Y = Math.Min(player.WorldMap.Length - 1, Math.Max(0, Pos.Y));
                    Pos.Z = Math.Min(player.WorldMap.Height - 1, Math.Max(0, Pos.Z));

                    if (player.CanPlace(player.World.Map, Pos, block, BlockChangeContext.Drawn) !=
                        CanPlaceResult.Allowed) {
                        player.Message("&WYou are not allowed to build here");
                        return;
                    }

                    Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos),
                        block, BlockChangeContext.Drawn);
                    BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
                    player.World.Map.QueueUpdate(blockUpdate);
                    player.Message("Block placed at {0} ({1} blocks away from you)", Pos, dis/32);
                } else {
                    player.Message("Error occurred, please try again.");
                    return;
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Particle"/> class.
        /// </summary>
        /// <param name="world">The world.</param>
        /// <param name="pos">The initial position.</param>
        /// <param name="direction">The direction in which the particle is flying.</param>
        /// <param name="owner">The owner of the particle.</param>
        /// <param name="block">The block type of the particle.</param>
        /// <param name="behavior">The partcle behavior. Includes how fare and fast it moves, what happens if it hits a player an obstacle etc.</param>
        public Particle(World world, Vector3I pos, Vector3F direction, Player owner,
            Block block, IParticleBehavior behavior)
            : base(world)
        {
            _direction = direction.Normalize();
            if (_direction == Vector3F.Zero)
                throw new ArgumentException("direction vector cannot be zero");

            _stepDelay = behavior.ProcessingStepsPerSecond <= 0 || behavior.ProcessingStepsPerSecond > 20
                            ? 50
                            : 1000 / behavior.ProcessingStepsPerSecond;

            _pos = pos;
            _startingPos = pos;
            _currentStep = 0;
            _owner = owner;
            _block = block;
            _restDistance = behavior.MaxDistance;
            _behavior = behavior;
            lock (_world.SyncRoot)
            {
                //draw it once right now
                if (null != _map && ReferenceEquals(_map, _world.Map))
                {
                    _prevBlock = _map.GetBlock(pos);
                    if (Block.Undefined != _prevBlock) //out of bounds!
                        if (owner.CanPlace(_map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed)
                        UpdateMap(new BlockUpdate(null, pos, block));
                }
            }
        }
Пример #7
0
 //true if not stopped
 public bool VisitBlock(World world, Vector3I pos, Block block, Player owner, ref int restDistance, IList<BlockUpdate> updates, Block sending)
 {
     if (Block.TNT == block) //explode it
     {
         world.AddPhysicsTask(new TNTTask(world, pos, owner, false, true), _r.Next(150, 300));
     }
     if (Block.Air != block && Block.Water != block && Block.Lava != block)
         if (owner.CanPlace(world.Map, pos, Block.Wood, BlockChangeContext.Manual) == CanPlaceResult.Allowed)
         updates.Add(new BlockUpdate(null, pos, Block.Air));
     return true;
 }
Пример #8
0
        static void Place(Player player, Command cmd)
        {
            Block block;
            if (player.LastUsedBlockType == Block.Undefined)
            {
                block = Block.Stone;
            }
            else
            {
                block = player.LastUsedBlockType;
            }
            Vector3I Pos = new Vector3I(player.Position.X / 32, player.Position.Y / 32, (player.Position.Z / 32) - 2);

            if (player.CanPlace(player.World.Map, Pos, player.GetBind(block), BlockChangeContext.Manual) != CanPlaceResult.Allowed)
            {
                player.Message("&WYou are not allowed to build here");
                return;
            }

            Player.RaisePlayerPlacedBlockEvent(player, player.WorldMap, Pos, player.WorldMap.GetBlock(Pos), block, BlockChangeContext.Manual);
            BlockUpdate blockUpdate = new BlockUpdate(null, Pos, block);
            player.World.Map.QueueUpdate(blockUpdate);
            player.Message("Block placed below your feet");
        }
Пример #9
0
        unsafe internal static void ReplaceCallback( Player player, Position[] marks, object drawArgs ) {
            ReplaceArgs args = (ReplaceArgs)drawArgs;

            byte* specialTypes = stackalloc byte[args.Types.Length];
            int specialTypeCount = args.Types.Length;
            for( int i = 0; i < args.Types.Length; i++ ) {
                specialTypes[i] = (byte)args.Types[i];
            }

            bool doExclude = args.DoExclude;

            // find start/end coordinates
            int sx = Math.Min( marks[0].X, marks[1].X );
            int ex = Math.Max( marks[0].X, marks[1].X );
            int sy = Math.Min( marks[0].Y, marks[1].Y );
            int ey = Math.Max( marks[0].Y, marks[1].Y );
            int sh = Math.Min( marks[0].H, marks[1].H );
            int eh = Math.Max( marks[0].H, marks[1].H );

            int volume = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1);
            if( !player.CanDraw( volume ) ) {
                player.MessageNow( "You are only allowed to run draw commands that affect up to {0} blocks. This one would affect {1} blocks.",
                                    player.Info.Rank.DrawLimit,
                                    volume );
                return;
            }

            player.UndoBuffer.Clear();

            bool cannotUndo = false;
            int blocks = 0, blocksDenied = 0;
            for( int x = sx; x <= ex; x += DrawStride ) {
                for( int y = sy; y <= ey; y += DrawStride ) {
                    for( int h = sh; h <= eh; h++ ) {
                        for( int y3 = 0; y3 < DrawStride && y + y3 <= ey; y3++ ) {
                            for( int x3 = 0; x3 < DrawStride && x + x3 <= ex; x3++ ) {

                                byte block = player.World.Map.GetBlockByte( x + x3, y + y3, h );

                                bool skip = !args.DoExclude;
                                for( int i = 0; i < specialTypeCount; i++ ) {
                                    if( block == specialTypes[i] ) {
                                        skip = args.DoExclude;
                                        break;
                                    }
                                }
                                if( skip ) continue;

                                if( player.CanPlace( x + x3, y + y3, h, args.ReplacementBlock, false ) != CanPlaceResult.Allowed ) {
                                    blocksDenied++;
                                    continue;
                                }
                                player.World.Map.QueueUpdate( new BlockUpdate( null, x + x3, y + y3, h, args.ReplacementBlock ) );
                                Server.RaisePlayerPlacedBlockEvent( player, (short)x, (short)y, (short)h, (Block)block, args.ReplacementBlock, false );
                                if( blocks < MaxUndoCount ) {
                                    player.UndoBuffer.Enqueue( new BlockUpdate( null, x + x3, y + y3, h, block ) );
                                } else if( !cannotUndo ) {
                                    player.UndoBuffer.Clear();
                                    player.UndoBuffer.TrimExcess();
                                    player.MessageNow( "NOTE: This draw command is too massive to undo." );
                                    cannotUndo = true;
                                    if( player.Can( Permission.ManageWorlds ) ) {
                                        player.MessageNow( "Reminder: You can use &H/wflush&S to accelerate draw commands." );
                                    }
                                }
                                blocks++;

                            }
                        }
                    }
                }
            }


            Logger.Log( "{0} replaced {1} blocks {2} ({3}) with {4} (on world {5})", LogType.UserActivity,
                        player.Name,
                        blocks,
                        (doExclude ? "except" : "of"),
                        args.Types.JoinToString(),
                        args.ReplacementBlock,
                        player.World.Name );

            DrawingFinished( player, "replaced", blocks, blocksDenied );
        }
Пример #10
0
        static void DrawOneBlock( Player player, byte drawBlock, int x, int y, int h, ref int blocks, ref int blocksDenied, ref bool cannotUndo ) {
            if( !player.World.Map.InBounds( x, y, h ) ) return;
            byte block = player.World.Map.GetBlockByte( x, y, h );
            if( block == drawBlock ) return;

            if( player.CanPlace( x, y, h, (Block)drawBlock, false ) != CanPlaceResult.Allowed ) {
                blocksDenied++;
                return;
            }

            // this would've been an easy way to do block tracking for draw commands BUT
            // if i set "origin" to player, he will not receive the block update. I tried.
            player.World.Map.QueueUpdate( new BlockUpdate( null, x, y, h, drawBlock ) );
            Server.RaisePlayerPlacedBlockEvent( player, (short)x, (short)y, (short)h, (Block)block, (Block)drawBlock, false );
            //player.SendDelayed( PacketWriter.MakeSetBlock( x, y, h, drawBlock ) );

            if( blocks < MaxUndoCount ) {
                player.UndoBuffer.Enqueue( new BlockUpdate( null, x, y, h, block ) );
            } else if( !cannotUndo ) {
                player.UndoBuffer.Clear();
                player.UndoBuffer.TrimExcess();
                player.MessageNow( "NOTE: This draw command is too massive to undo." );
                if( player.Can( Permission.ManageWorlds ) ) {
                    player.MessageNow( "Reminder: You can use &H/wflush&S to accelerate draw commands." );
                }
                cannotUndo = true;
            }
            blocks++;
        }
Пример #11
0
        protected override int PerformInternal()
        {
            //lock is done already
            if (Block.Undefined == _prevBlock) //created out of bounds, dont continue
            {
                return(0);
            }
            //fix for portal gun
            if (_owner.orangePortal.Count > 0)
            {
                if (_pos == _owner.orangePortal[0] || _pos == _owner.orangePortal[1])
                {
                    return(0);
                }
            }
            if (_owner.bluePortal.Count > 0)
            {
                if (_pos == _owner.bluePortal[0] || _pos == _owner.bluePortal[1])
                {
                    return(0);
                }
            }

            //delete at the previous position, restore water unconditionally, lava only when bullet is still there to prevent restoration of explosion lava
            if (_prevBlock != Block.Water)
            {
                _prevBlock = Block.Air;
            }
            //edit: lazyfix, dont restore lava coz tnt.

            if (Block.Undefined != _prevBlock)
            {
                if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed)
                {
                    UpdateMap(new BlockUpdate(null, _pos, _prevBlock));
                }
            }

            List <BlockUpdate> updates = new List <BlockUpdate>();

            for (int i = 0; i < _behavior.MovesPerProcessingStep && _restDistance > 0; ++i)
            {
                _pos       = Move();
                _prevBlock = _map.GetBlock(_pos);

                if (Block.Undefined == _prevBlock)
                {
                    _restDistance = 0;
                    break;
                }

                _behavior.ModifyDirection(ref _direction, _prevBlock);
                //e.g. if you want it to be dependent on gravity or change direction depending on current block etc

                if (_behavior.VisitBlock(_world, _pos, _prevBlock, _owner, ref _restDistance, updates, _block) &&
                    _behavior.CanKillPlayer)
                {
                    CheckHitPlayers(updates);
                }
            }

            bool cont = _restDistance > 0;

            if (cont) //check if the last update was for the current position and replace it with the particle
            {
                int idx = updates.Count - 1;
                if (idx >= 0 && updates[idx].X == _pos.X &&
                    updates[idx].Y == _pos.Y &&
                    updates[idx].Z == _pos.Z)
                {
                    if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed)
                    {
                        updates[idx] = new BlockUpdate(null, _pos, _block);
                    }
                }
                else
                {
                    if (_owner.CanPlace(_map, _pos, Block.Plank, BlockChangeContext.Manual) == CanPlaceResult.Allowed)
                    {
                        updates.Add(new BlockUpdate(null, _pos, _block));
                    }
                }
            }

            for (int i = 0; i < updates.Count; ++i)
            {
                UpdateMap(updates[i]);
            }

            return(cont ? _stepDelay : 0);
        }
Пример #12
0
        static void DoorAdd( Player player, Vector3I[] marks, object tag )
        {
            int sx = Math.Min( marks[0].X, marks[1].X );
            int ex = Math.Max( marks[0].X, marks[1].X );
            int sy = Math.Min( marks[0].Y, marks[1].Y );
            int ey = Math.Max( marks[0].Y, marks[1].Y );
            int sh = Math.Min( marks[0].Z, marks[1].Z );
            int eh = Math.Max( marks[0].Z, marks[1].Z );

            int volume = ( ex - sx + 1 ) * ( ey - sy + 1 ) * ( eh - sh + 1 );
            if ( volume > maxDoorBlocks ) {
                player.Message( "Doors are only allowed to be {0} blocks", maxDoorBlocks );
                return;
            }
            if ( !player.Info.Rank.AllowSecurityCircumvention ) {
                SecurityCheckResult buildCheck = player.World.BuildSecurity.CheckDetailed( player.Info );
                switch ( buildCheck ) {
                    case SecurityCheckResult.BlackListed:
                        player.Message( "Cannot add a door to world {0}&S: You are barred from building here.",
                                        player.World.ClassyName );
                        return;
                    case SecurityCheckResult.RankTooLow:
                        player.Message( "Cannot add a door to world {0}&S: You are not allowed to build here.",
                                        player.World.ClassyName );
                        return;
                    //case SecurityCheckResult.RankTooHigh:
                }
            }
            for ( int x = sx; x < ex; x++ ) {
                for ( int y = sy; y < ey; y++ ) {
                    for ( int z = sh; z < eh; z++ ) {
                        if ( player.CanPlace( player.World.Map, new Vector3I( x, y, z ), Block.Wood, BlockChangeContext.Manual ) != CanPlaceResult.Allowed ) {
                            player.Message( "Cannot add a door to world {0}&S: Build permissions in this area replied with 'denied'.",
                                        player.World.ClassyName );
                            return;
                        }
                    }
                }
            }
            Zone door = ( Zone )tag;
            door.Create( new BoundingBox( marks[0], marks[1] ), player.Info );
            player.WorldMap.Zones.Add( door );
            Logger.Log( LogType.UserActivity, "{0} created door {1} (on world {2})", player.Name, door.Name, player.World.Name );
            player.Message( "Door created: {0}x{1}x{2}", door.Bounds.Dimensions.X,
                                                        door.Bounds.Dimensions.Y,
                                                        door.Bounds.Dimensions.Z );
        }