public float GetHeight(HexagonTriangulation.Point point)
 {
     for (int index = 0; index < unique_points_dict[point.age].Count; index++)
     {
         if (unique_points_dict[point.age][index] == point)
         {
             return(heights_dict[point.age][index]);
         }
     }
     return(-1);
 }
    private void ResetRendererData()
    {
        // Reset the renderer data
        renderer_vertices  = new Vector3[triangles.Count * 3];
        renderer_triangles = new int[triangles.Count * 3];

        // Set the renderer data
        int vertices_counter = 0;

        foreach (HexagonTriangulation.Point[] triangle in triangles)
        {
            for (int i = 0; i < 3; i++)
            {
                // Fetch the Point
                HexagonTriangulation.Point point = triangle[i];

                // Locate the Point in the points_dictionary
                float height = GetHeight(point);
                renderer_vertices[vertices_counter]  = new Vector3(point.location[0], height, point.location[2]);
                renderer_triangles[vertices_counter] = vertices_counter;
                vertices_counter += 1;
            }
        }
    }
    public void CalculateMeshHeights()
    {
        HextileManager hextile_manager = gameObject.GetComponent <HextileManager>();

        // Step 1: Set heights for the initial points of the hexagon - the ones with age 0
        heights_dict[0][0] = CalculateHeightValue(gameObject.GetComponent <HextileGeography>().GetBaseHeight(), gameObject.GetComponent <HextileGeography>().GetDeviation(), 0);
        for (int i = 1; i < 7; i++)
        {
            // Get the hextiles that neighbor the current point
            string[,] direction_codes =
            {
                { "top_left",    "top_right"    }, // Top Point
                { "right",       "top_right"    }, // Top right Point
                { "right",       "bottom_right" }, // Bottom right Point
                { "bottom_left", "bottom_right" }, // Bottom Point
                { "bottom_left", "left"         }, // Bottom left Point
                { "left",        "top_left"     } // Top left Point
            };
            GameObject hextile_1 = TectonicOrder.GetRelativeHextile(hextile_manager.hextile_row, hextile_manager.hextile_col, direction_codes[i - 1, 0]);
            GameObject hextile_2 = TectonicOrder.GetRelativeHextile(hextile_manager.hextile_row, hextile_manager.hextile_col, direction_codes[i - 1, 1]);

            // Check if those hextiles have had their heights assigned
            int[,] opposite_origin_points = { { 3, 5 }, { 6, 4 }, { 5, 1 }, { 2, 6 }, { 1, 3 }, { 2, 4 } };
            float height = -1.0f;
            if (hextile_1 != null)
            {
                height = hextile_1.GetComponent <HextileMesh>().heights_dict[0][opposite_origin_points[i - 1, 0]];
            }
            if (hextile_2 != null && height == -1.0f)
            {
                height = hextile_2.GetComponent <HextileMesh>().heights_dict[0][opposite_origin_points[i - 1, 1]];
            }

            // Set the height for this Point
            if (height == -1.0f)
            {
                float base_height = gameObject.GetComponent <HextileGeography>().GetBaseHeight();
                float deviation   = gameObject.GetComponent <HextileGeography>().GetDeviation();

                if (hextile_1 != null)
                {
                    if (hextile_1.GetComponent <HextileGeography>().GetBaseHeight() < base_height)
                    {
                        base_height = hextile_1.GetComponent <HextileGeography>().GetBaseHeight();
                    }
                    if (hextile_1.GetComponent <HextileGeography>().GetDeviation() > deviation)
                    {
                        deviation = hextile_1.GetComponent <HextileGeography>().GetDeviation();
                    }
                }
                if (hextile_2 != null)
                {
                    if (hextile_2.GetComponent <HextileGeography>().GetBaseHeight() < base_height)
                    {
                        base_height = hextile_1.GetComponent <HextileGeography>().GetBaseHeight();
                    }
                    if (hextile_2.GetComponent <HextileGeography>().GetDeviation() > deviation)
                    {
                        deviation = hextile_1.GetComponent <HextileGeography>().GetDeviation();
                    }
                }

                // Fluctuate the height
                heights_dict[0][i] = CalculateHeightValue(base_height, deviation, 0);
            }
            else
            {
                heights_dict[0][i] = height;
            }
        }

        // Step 2: Set heights for all Point of a given age, increasing the age with every step
        for (int age = 1; age < unique_points_dict.Count; age++)
        {
            // Go through every Point of that age and assign a height to it
            for (int i = 0; i < unique_points_dict[age].Count; i++)
            {
                // Get the value of the point - dont modify this, this is not the reference
                HexagonTriangulation.Point point = unique_points_dict[age][i];

                // If the Point is an inner point, calculate the height based on its two neighbors
                if (unique_points_dict[age][i].opp_correspondance.Count == 0)
                {
                    float base_height = Mathf.Clamp(
                        (GetHeight(point.neighbors[0]) + GetHeight(point.neighbors[1])) / 2,
                        0.0f,
                        gameObject.GetComponent <HextileGeography>().GetBaseHeight() + gameObject.GetComponent <HextileGeography>().GetDeviation()
                        );
                    float deviation = gameObject.GetComponent <HextileGeography>().GetDeviation();
                    heights_dict[age][i] = CalculateHeightValue(base_height, deviation, i);
                }
                else
                {
                    // Get the relative Hextile
                    GameObject hextile = TectonicOrder.GetRelativeHextile(hextile_manager.hextile_row, hextile_manager.hextile_col, point.neighb_hextile_dir);

                    // Grab the height of the relative Hextile's Point that touches the current Point
                    float height = -1.0f;
                    if (hextile != null)
                    {
                        foreach (HexagonTriangulation.Point a_point in unique_points_dict[point.age])
                        {
                            if (a_point == point.opp_correspondance[0])
                            {
                                height = hextile.GetComponent <HextileMesh>().GetHeight(a_point);
                            }
                        }
                    }

                    // If that Point has had its height assigned, assign the same value to this Point, else calculate the height based on the Point's neighbors
                    if (height != -1.0f)
                    {
                        heights_dict[age][i] = height;
                    }
                    else
                    {
                        float base_height = (GetHeight(point.neighbors[0]) + GetHeight(point.neighbors[1])) / 2;
                        float deviation   = gameObject.GetComponent <HextileGeography>().GetDeviation();
                        if (hextile != null)
                        {
                            if (hextile.GetComponent <HextileGeography>().GetDeviation() > deviation)
                            {
                                deviation = hextile.GetComponent <HextileGeography>().GetDeviation();
                            }
                        }
                        heights_dict[age][i] = CalculateHeightValue(base_height, deviation, i);
                    }
                }
            }
        }

        // Step 3: Recalculate and apply the renderer data
        ResetRendererData();
        gameObject.GetComponent <MeshFilter>().mesh.vertices  = renderer_vertices;
        gameObject.GetComponent <MeshFilter>().mesh.triangles = renderer_triangles;
    }