protected bool DrawOneBlock() { BlocksProcessed++; if (!Map.InBounds(Coords)) { BlocksSkipped++; return(false); } #if DEBUG_CHECK_DUPLICATE_COORDS TestForDuplicateModification(); #endif Block newBlock = Brush.NextBlock(this); if (newBlock == Block.Undefined) { return(false); } int blockIndex = Map.Index(Coords); Block oldBlock = (Block)Map.Blocks[blockIndex]; if (oldBlock == newBlock) { BlocksSkipped++; return(false); } if (Player.CanPlace(Map, Coords, newBlock, Context) != CanPlaceResult.Allowed) { BlocksDenied++; return(false); } Map.Blocks[blockIndex] = (byte)newBlock; World world = Map.World; if (world != null && !world.IsFlushing) { world.Players.SendLowPriority(PacketWriter.MakeSetBlock(Coords, newBlock)); } Player.RaisePlayerPlacedBlockEvent(Player, Map, Coords, oldBlock, newBlock, Context); if (!UndoState.IsTooLargeToUndo) { if (!UndoState.Add(Coords, oldBlock)) { Player.LastDrawOp = null; Player.Message("{0}: Too many blocks to undo.", Description); } } BlocksUpdated++; return(true); }
protected bool DrawOneBlock() { BlocksProcessed++; if (!Map.InBounds(Coords)) { BlocksSkipped++; return false; } #if DEBUG_CHECK_DUPLICATE_COORDS TestForDuplicateModification(); #endif Block newBlock = Brush.NextBlock(this); if (newBlock == Block.None) return false; int blockIndex = Map.Index(Coords); Block oldBlock = (Block)Map.Blocks[blockIndex]; if (oldBlock == newBlock) { BlocksSkipped++; return false; } if (Player.CanPlace(Map, Coords, newBlock, Context) != CanPlaceResult.Allowed) { BlocksDenied++; return false; } Map.SetBlock(blockIndex, newBlock); World world = Map.World; if (world != null && !world.IsFlushing) { // cannot reuse packet as each player may require different modifications to block field Player[] players = world.Players; for (int i = 0; i < players.Length; i++) players[i].SendBlock(Coords, newBlock); } // Reuse instance to avoid memory allocations if (placeArgs == null) placeArgs = new PlayerPlacedBlockEventArgs(Player, Map, Vector3I.Zero, Block.Air, Block.Air, Context); placeArgs.Coords = Coords; placeArgs.OldBlock = oldBlock; placeArgs.NewBlock = newBlock; Player.RaisePlayerPlacedBlockEvent(placeArgs); if (!UndoState.IsTooLargeToUndo) { if (!UndoState.Add(Coords, Map, oldBlock)) { Player.LastDrawOp = null; Player.Message("{0}: Too many blocks to undo.", Description); } } BlocksUpdated++; return true; }
static void DrawOneBlock( [NotNull] Player player, [NotNull] Map map, Block drawBlock, Vector3I coord, BlockChangeContext context, ref int blocks, ref int blocksDenied, UndoState undoState ) { 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.MessageNow( "NOTE: This draw command is too massive to undo." ); player.LastDrawOp = null; } } blocks++; }