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 postReplace 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 postJust 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)