/// <summary>
        /// Shows a dialog to add a new terrain patch to the world map.
        /// </summary>
        /// <param name="sender">The object that raised the event.</param>
        /// <param name="e">The event arguments.</param>
        private void AddNewPatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Helper.EnsureDirectories();

            AddNewPatchDialog addPatchForm = new AddNewPatchDialog(this.editorRenderWindow.Engine.CurrentCamera.Target, this.editorRenderWindow.Engine.Terrain.CurrentHeightLevel);
            if (addPatchForm.ShowDialog() == DialogResult.OK)
            {
                TerrainPatch tp = new TerrainPatch(addPatchForm.PatchCoordinates, addPatchForm.DefaultHeight, addPatchForm.DefaultTerrainType);

                string destinationFilename = Helper.GetPatchFileName(tp.PatchId);

                if (File.Exists(destinationFilename))
                {
                    if (MessageBox.Show("Are you sure you want to overwrite?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, this.RightToLeft == RightToLeft.Yes ? MessageBoxOptions.RtlReading : 0) == DialogResult.Yes)
                    {
                        File.WriteAllBytes(destinationFilename, tp.ToByteArray());
                        this.editorRenderWindow.Engine.Terrain.ForcePatchReload(addPatchForm.PatchCoordinates);
                    }
                }
                else
                {
                    File.WriteAllBytes(destinationFilename, tp.ToByteArray());
                }
            }
        }
        /// <summary>
        /// Generates a terrain patch from an array of bytes; returns null if the data is invalid.
        /// </summary>
        /// <param name="data">The array of bytes to generate the patch from.</param>
        /// <returns>See summary.</returns>
        public static TerrainPatch FromByteArray(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            else
            {
                ReadOnlyCollection<Season> seasons = SeasonExtensions.GetSeasons();

                BinaryReader reader = new BinaryReader(new MemoryStream(data));

                try
                {
                    // Read the patch ID
                    int x = reader.ReadInt32();
                    int y = reader.ReadInt32();
                    int z = reader.ReadInt32();

                    // Create a patch object
                    TerrainPatch patch = new TerrainPatch(new Point3D(x, y, z));

                    // Read the array of heights
                    for (int i = 0; i < patch.vertexHeightsArray.Length; i++)
                    {
                        patch.vertexHeightsArray[i] = reader.ReadSingle();
                    }

                    // Read terrain types for all seasons
                    for (int j = 0; j < seasons.Count; j++)
                    {
                        // Read the array of textures
                        for (int i = 0; i < patch.vertexTexturesArray[j].Length; i++)
                        {
                            patch.vertexTexturesArray[(int)seasons[j]][i] = (TerrainType)reader.ReadInt16();
                        }
                    }

                    // Read the number of fluids
                    short countFluids = reader.ReadInt16();

                    // Read all the fluids
                    for (int i = 0; i < countFluids; i++)
                    {
                        // Create a new fluid object to store on the patch
                        Fluid fluid = new Fluid(patch.PatchId);

                        // Read fluid properties for all seasons
                        for (int j = 0; j < seasons.Count; j++)
                        {
                            // Read the vertices
                            Vector3 southWest = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            Vector3 southEast = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            Vector3 northWest = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            Vector3 northEast = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                            // Read the fluid type
                            short fluidType = reader.ReadInt16();

                            // Read the fluid flow direction
                            short flowDirection = reader.ReadInt16();

                            // Read the fluid flow speed
                            float flowSpeed = reader.ReadSingle();

                            // Copy the read variables into the properties of the fluid object
                            fluid.SetPoint(seasons[j], FluidVertex.Southwest, southWest);
                            fluid.SetPoint(seasons[j], FluidVertex.Southeast, southEast);
                            fluid.SetPoint(seasons[j], FluidVertex.Northwest, northWest);
                            fluid.SetPoint(seasons[j], FluidVertex.Northeast, northEast);
                            fluid.SetFluidType(seasons[j], (FluidType)fluidType);
                            fluid.SetFlowDirection(seasons[j], (FluidFlowDirection)flowDirection);
                            fluid.SetFlowSpeed(seasons[j], flowSpeed);
                        }

                        // Add the fluid to the patch
                        patch.Fluids.Add(fluid);
                    }

                    return patch;
                }
                catch (EndOfStreamException)
                {
                    return null;
                }
                catch (IOException)
                {
                    return null;
                }
                finally
                {
                    reader.Close();
                }
            }
        }
        /// <summary>
        /// Creates a new instance of the TerrainPatch class using all the properties
        /// of an existing TerrainPatch but with a different patch ID.
        /// </summary>
        /// <param name="patchId">The ID of the terrain patch.</param>
        /// <param name="terrainPatch">The terrain patch whose properties to use.</param>
        /// <returns>See summary.</returns>
        public static TerrainPatch FromExisting(Point3D patchId, TerrainPatch terrainPatch)
        {
            TerrainPatch pat = terrainPatch.Clone() as TerrainPatch;
            pat.PatchId = patchId;

            return pat;
        }
Example #4
0
        /// <summary>
        /// Draws the specified terrain patch using the specified graphics context.
        /// </summary>
        /// <param name="terrainPatch">The terrain patch to draw.</param>
        /// <param name="lowestPatchID">The lowest terrain patch ID that will be needed to draw the map.</param>
        /// <param name="bitmapSize">The height of the finished world map, in pixels.</param>
        /// <param name="g">The graphics context to draw in.</param>
        /// <param name="textured">Whether the map should be drawn textured.</param>
        /// <param name="season">The season to draw the map in.</param>
        /// <param name="hideBase">
        /// Whether to draw undefined for non-base season
        /// instead of showing the base season terrain.
        /// </param>
        private static void DrawTerrainPatch(TerrainPatch terrainPatch, Point3D lowestPatchID, Size bitmapSize, Graphics g, bool textured, Season season, bool hideBase)
        {
            for (int x = 0; x < TerrainPatch.PatchSize; x++)
            {
                for (int y = 0; y < TerrainPatch.PatchSize; y++)
                {
                    // Get the patch local point and screen point
                    Vector2 localPoint = new Vector2(x, y);
                    Xna.Point screen = WorldMap.ProjectScreenPoint(lowestPatchID, CoordinateConverter.LocalToWorld(terrainPatch.PatchId, new Xna.Point(x, y)), bitmapSize);

                    // Initially set the draw color to that of the terrain
                    Color drawColor = WorldMap.GetDrawColor(terrainPatch.GetTerrainTypeDataForSeason(localPoint, season, hideBase), x, y, textured);
                    
                    // Store the heighest terrain height so far
                    float highestHeight = terrainPatch.GetExactElevation(localPoint);

                    // Loop through all the fluids
                    for (int i = 0; i < terrainPatch.Fluids.Count; i++)
                    {
                        // If the fluid contains the local point, check its height
                        if (terrainPatch.Fluids[i].ContainsPoint(season, localPoint))
                        {
                            // If the fluid's height is higher than the highest height (initially, the terrain's)
                            if (terrainPatch.Fluids[i].GetExactHeight(season, localPoint) > highestHeight)
                            {
                                // Set the highest height to this fluid's, and set the draw color to this fluid's
                                highestHeight = terrainPatch.Fluids[i].GetExactHeight(season, localPoint);
                                drawColor = WorldMap.GetDrawColor(terrainPatch.Fluids[i].GetFluidType(season), x, y, textured);
                            }
                        }
                    }

                    g.FillRectangle(new SolidBrush(drawColor), screen.X, screen.Y, 1, 1);
                }
            }
        }