Terrain Height Issue...

The terrain property you are using looks to be the overall height of the terrain (i.e. from the lowest point in the ocean to the highest poing on land).

I know this because when I stand at the highest point on my current map it is 172m above sea level vs. what your mod is calculating/displaying at startup...

06/05/2026 00:07:09 AM | [FancyDrop] Map Highest Point: (500m) | Plane flying height: (~125m)​

Here is my current setting...

"Multiplier for (plane height * highest point on Map); Default 1.0": 0.25,

Here is your calculation...

Puts($"Map Highest Point: ({TerrainMeta.HighestPoint.y}m) | Plane flying height: (~{TerrainMeta.HighestPoint.y * configData.AirdropSettings.planeOffSetYMultiply}m)");

 

As a Unity developer I know you initially set the terrain & ocean objects at Vector3.zero and then adjust your terrain object up/down to get the max height where you want it.  So you also need to subtract that Y offset in your calculation to get the Max Terrain Height and then multiply it by your setting -or- simply add a number to it.

( TerrainMeta.HighestPoint.y - Offset ) * configData.AirdropSettings.planeOffSetYMultiply
-OR-
( TerrainMeta.HighestPoint.y - Offset ) + configData.AirdropSettings.planeOffSetY

 

I'll look deeper into this and try to get the correct terrain properties and formula ASAP. 

In the meantime, it might be better to simply allow admins to set the spawn height (above sea level).

The function below gives you the EXACT Maximum Terrain Height of the current map.  Call this function when your mod is initialized (i.e., whenever the server starts).  You can then use the MaxTerrainHeight value to apply your settings to make the final aircraft spawn height adjustments.

        private float MaxTerrainHeight;        
        private void GetMaxTerrainHeight()
        {
            // Get the active terrain's data
            TerrainData terrainData = Terrain.activeTerrain.terrainData;
            int width = terrainData.heightmapResolution;
            int height = width;
            // Push terrain heights data into a 2D array
            float[,] heights = terrainData.GetHeights(0, 0, width, height);
            // Loop through the heights data 
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // Get current terrain height data values (normalized between 0.0 and 1.0)
                    float currentHeight = heights[y, x];
                    // Is the current data larger thatn the previously read data?
                    if (currentHeight > MaxTerrainHeight)
                    {
                        // Update the Max Height value
                        MaxTerrainHeight = currentHeight;
                    }
                }
            }
            // Calculate real world Maxiumu Terrain Height
            MaxTerrainHeight = (MaxTerrainHeight * terrainData.size.y) - TerrainMeta.HighestPoint.y;
        }

 



Merged post

Replace this code, starting at line XXX...

            y = (TerrainMeta.HighestPoint.y * configData.AirdropSettings.planeOffSetYMultiply) + additionalheight;
            Vector3 startPos = Vector3Ex.Range(-1f, 1f);
            startPos.y = 0f;
            startPos.Normalize();
            startPos *= x * configData.AirdropSettings.planeOffSetXMultiply;
            startPos.y = y;
            Vector3 endPos = startPos * -1f;
            endPos.y = startPos.y;
            startPos += dropToPos;
            endPos += dropToPos;

With this code...

            y = (MaxTerrainHeight * (1f + configData.AirdropSettings.planeOffSetYMultiply)) + additionalheight;
            Vector3 startPos = Vector3Ex.Range(-1f, 1f);
            startPos.y = 0f;
            startPos.Normalize();
            startPos *= x * configData.AirdropSettings.planeOffSetXMultiply;
            startPos.y = y;
            Vector3 endPos = startPos * -1f;
            startPos += dropToPos;
            startPos.y = y;
            endPos += dropToPos;
            endPos.y = y;

You will of course need to add my GetMaxTerrainHeight function (posted above) just below Init() and add a call to it therein.

        private void Init()
        {
            Instance = this;
            initialized = false;
            msgConsoleDropSpawn = msg("msgConsoleDropSpawn");
            msgConsoleDropLanded = msg("msgConsoleDropLanded");

            Interface.CallHook("OnFancyDropTypes", configData.DropSettings.setupDropTypes);

            // Get maximum terrain height from active terrain
            GetMaxTerrainHeight();
        }
        private void GetMaxTerrainHeight()
        {
            // Get the active terrain's data
            TerrainData terrainData = Terrain.activeTerrain.terrainData;
            int width = terrainData.heightmapResolution;
            int height = width;
            // Push terrain heights data into a 2D array
            float[,] heights = terrainData.GetHeights(0, 0, width, height);
            // Loop through the heights data
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // Get current terrain height data values (normalized between 0.0 and 1.0)
                    float currentHeight = heights[y, x];
                    // If the current data is larger thatn the previously read data...
                    if (currentHeight > MaxTerrainHeight)
                    {
                        // Update the Max Height value
                        MaxTerrainHeight = currentHeight;
                    }
                }
            }
            // Calculate real world Maxiumu Terrain Height           
            MaxTerrainHeight = (MaxTerrainHeight * terrainData.size.y) - TerrainMeta.HighestPoint.y;
            // Log the terrain findings
            Puts($"Max Terrain Height: {MaxTerrainHeight.ToString("N1")}m, Terrain Size X/Y/Z: {width}/{terrainData.size.y}/{height}.", true);
        }

Note I left the planeOffSetYMultiply setting alone (see below), so setting it to zero (0) sets the flight altitude to the Max Terrain Height (MTH), setting it to one (1) doubles the MTH, or two (2) trebles the MTH.

[JsonProperty(PropertyName = "Multiplier for (plane height * highest point on Map); Default 1.0")]

So at this point, I would recommend converting this property to an integer value for Meters Above MTH (similar to the additionalheight setting under DropTypes).



Merged post

Just realized that the func tion neds to be called after the Server is Initialized vs. in the plugin's Init...
private void OnServerInitialized(bool initial)​