Exemplo n.º 1
0
        private fCraft.Drawing.UndoState undoState; //undostate

        #endregion Fields

        #region Methods

        public void DrawImage( byte popType, Direction direct, Vector3I cpos, Player player, string url )
        {
            undoState = player.DrawBegin( null );
            Bitmap myBitmap = null;
            HttpWebRequest request = ( HttpWebRequest )WebRequest.Create( url );
            request.Timeout = 5000;
            using ( HttpWebResponse response = ( HttpWebResponse )request.GetResponse() ) {
                // Check that the remote file was found. The ContentType
                // check is performed since a request for a non-existent
                // image file might be redirected to a 404-page, which would
                // yield the StatusCode "OK", even though the image was not
                // found.
                if ( ( response.StatusCode == HttpStatusCode.OK ||
                    response.StatusCode == HttpStatusCode.Moved ||
                    response.StatusCode == HttpStatusCode.Redirect ) &&
                    response.ContentType.StartsWith( "image", StringComparison.OrdinalIgnoreCase ) ) {
                    // if the remote file was found, download it
                    using ( Stream inputStream = response.GetResponseStream() ) {
                        myBitmap = new Bitmap( inputStream );
                    }
                }
            }
            if ( myBitmap == null ) {
                throw new Exception( "&WDrawImg: Could not download given url" );
            }
            int Volume = myBitmap.Height * myBitmap.Width;
            if ( !player.CanDraw( Volume ) ) {
                player.Message( String.Format( "You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.",
                                               player.Info.Rank.DrawLimit, Volume ) );
                myBitmap.Dispose();
                return;
            }
            myBitmap.RotateFlip( RotateFlipType.RotateNoneFlipY );
            if ( myBitmap.Width > player.World.Map.Width ) {
                myBitmap = resizeImage( myBitmap, player.World.Map.Width, myBitmap.Height );
            }
            if ( myBitmap.Height > player.World.Map.Height ) {
                myBitmap = resizeImage( myBitmap, myBitmap.Width, player.World.Map.Height );
            }
            int direction = 0;
            if ( direct == Direction.one )
                direction = 0;
            if ( direct == Direction.two )
                direction = 1;
            if ( direct == Direction.three )
                direction = 2;
            if ( direct == Direction.four )
                direction = 3;

            List<ColorBlock> refCol = popRefCol( popType );
            ColorBlock colblock;
            double[] distance = new double[refCol.Count];
            try {
                Thread printThread = new Thread( new ThreadStart( delegate {
                    int position;
                    for ( int k = 0; k < myBitmap.Width; k++ ) {
                        for ( int i = 0; i < myBitmap.Height; i++ ) {
                            colblock.z = ( ushort )( cpos.Z + i );
                            if ( direction <= 1 ) {
                                if ( direction == 0 )
                                    colblock.x = ( ushort )( cpos.X + k );
                                else
                                    colblock.x = ( ushort )( cpos.X - k );
                                colblock.y = cpos.Y;
                            } else {
                                if ( direction == 2 )
                                    colblock.y = ( ushort )( cpos.Y + k );
                                else
                                    colblock.y = ( ushort )( cpos.Y - k );
                                colblock.x = cpos.X;
                            }

                            colblock.r = myBitmap.GetPixel( k, i ).R;
                            colblock.g = myBitmap.GetPixel( k, i ).G;
                            colblock.b = myBitmap.GetPixel( k, i ).B;
                            colblock.a = myBitmap.GetPixel( k, i ).A;

                            if ( popType == 6 ) {
                                if ( ( colblock.r + colblock.g + colblock.b ) / 3 < ( 256 / 4 ) ) {
                                    colblock.type = ( byte )Block.Obsidian;
                                } else if ( ( ( colblock.r + colblock.g + colblock.b ) / 3 ) >= ( 256 / 4 ) && ( ( colblock.r + colblock.g + colblock.b ) / 3 ) < ( 256 / 4 ) * 2 ) {
                                    colblock.type = ( byte )Block.Black;
                                } else if ( ( ( colblock.r + colblock.g + colblock.b ) / 3 ) >= ( 256 / 4 ) * 2 && ( ( colblock.r + colblock.g + colblock.b ) / 3 ) < ( 256 / 4 ) * 3 ) {
                                    colblock.type = ( byte )Block.Gray;
                                } else {
                                    colblock.type = ( byte )Block.White;
                                }
                            } else {
                                for ( int j = 0; j < distance.Length; j++ ) // Calculate distances between the colors in the image and the set referance colors, and store them.
                                {
                                    distance[j] = Math.Sqrt( Math.Pow( ( colblock.r - refCol[j].r ), 2 ) + Math.Pow( ( colblock.b - refCol[j].b ), 2 ) + Math.Pow( ( colblock.g - refCol[j].g ), 2 ) );
                                }

                                position = 0;
                                double minimum = distance[0];
                                for ( int h = 1; h < distance.Length; h++ ) // Find the smallest distance in the array of distances.
                                {
                                    if ( distance[h] < minimum ) {
                                        minimum = distance[h];
                                        position = h;
                                    }
                                }

                                colblock.type = refCol[position].type; // Set the block we found closest to the image to the block we are placing.

                                if ( popType == 1 ) {
                                    if ( position <= 20 ) {
                                        if ( direction == 0 ) {
                                            colblock.y = ( ushort )( colblock.y + 1 );
                                        } else if ( direction == 2 ) {
                                            colblock.x = ( ushort )( colblock.x - 1 );
                                        } else if ( direction == 1 ) {
                                            colblock.y = ( ushort )( colblock.y - 1 );
                                        } else if ( direction == 3 ) {
                                            colblock.x = ( ushort )( colblock.x + 1 );
                                        }
                                    }
                                } else if ( popType == 3 ) {
                                    if ( position <= 3 ) {
                                        if ( direction == 0 ) {
                                            colblock.y = ( ushort )( colblock.y + 1 );
                                        } else if ( direction == 2 ) {
                                            colblock.x = ( ushort )( colblock.x - 1 );
                                        } else if ( direction == 1 ) {
                                            colblock.y = ( ushort )( colblock.y - 1 );
                                        } else if ( direction == 3 ) {
                                            colblock.x = ( ushort )( colblock.x + 1 );
                                        }
                                    }
                                }
                            }
                            if ( colblock.a < 20 )
                                colblock.type = ( byte )Block.Air;
                            DrawOneBlock( player, player.World.Map, ( Block )colblock.type,
                                              new Vector3I( colblock.x, colblock.y, colblock.z ), BlockChangeContext.Drawn,
                                              ref blocks, ref blocksDenied, undoState );
                        }
                    }
                } ) );
                printThread.Start();
            } catch ( Exception e ) {
                player.Message( Color.Warning + "DrawImg: " + e.Message );
            }
        }
Exemplo n.º 2
0
        private 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++;
        }