public static bool CalculateAtmoTravelPath(ImprovedSpawnGroup spawnGroup, Vector3D startCoords, MyPlanet planet, out Vector3D startPathCoords, out Vector3D endPathCoords, out MatrixD startMatrix) { startPathCoords = Vector3D.Zero; endPathCoords = Vector3D.Zero; startMatrix = MatrixD.CreateWorld(Vector3D.Zero, Vector3D.Forward, Vector3D.Up); SpawnResources.RefreshEntityLists(); if (planet == null) { return(false); } var planetEntity = planet as IMyEntity; for (int i = 0; i < Settings.PlanetaryCargoShips.MaxSpawnAttempts; i++) { //Get Starting Point var randDirFromPlayer = SpawnResources.GetRandomCompassDirection(startCoords, planet); var pathDist = SpawnResources.GetRandomPathDist(Settings.PlanetaryCargoShips.MinPathDistanceFromPlayer, Settings.PlanetaryCargoShips.MaxPathDistanceFromPlayer); var midPointSurface = SpawnResources.GetNearestSurfacePoint(randDirFromPlayer * pathDist + startCoords, planet); var upDir = Vector3D.Normalize(midPointSurface - planetEntity.GetPosition()); var altitudeFromMid = SpawnResources.GetRandomPathDist(Settings.PlanetaryCargoShips.MinSpawningAltitude, Settings.PlanetaryCargoShips.MaxSpawningAltitude); var tempStartPath = upDir * altitudeFromMid + midPointSurface; if (spawnGroup.PlanetRequiresAtmo == true && planet.GetAirDensity(tempStartPath) < Settings.PlanetaryCargoShips.MinAirDensity) { tempStartPath = upDir * Settings.PlanetaryCargoShips.MinSpawningAltitude + midPointSurface; if (spawnGroup.PlanetRequiresAtmo == true && planet.GetAirDensity(tempStartPath) < Settings.PlanetaryCargoShips.MinAirDensity) { continue; } } if (SpawnResources.IsPositionNearEntities(tempStartPath, Settings.PlanetaryCargoShips.MinSpawnFromGrids) == true) { continue; } var startCoordsDistFromCenter = Vector3D.Distance(planetEntity.GetPosition(), tempStartPath); //Get Ending Point var randPathDir = SpawnResources.GetRandomCompassDirection(tempStartPath, planet); var randPathDist = SpawnResources.GetRandomPathDist(Settings.PlanetaryCargoShips.MinPathDistance, Settings.PlanetaryCargoShips.MaxPathDistance); var endPathA = randPathDir * randPathDist + tempStartPath; var endPathB = -randPathDir * randPathDist + tempStartPath; var tempEndPath = Vector3D.Zero; if (Vector3D.Distance(endPathA, startCoords) < Vector3D.Distance(endPathB, startCoords)) { tempEndPath = endPathA; } else { tempEndPath = endPathB; randPathDir *= -1; } //TODO: Set At Same Height From Sealevel As Start var endUpDir = Vector3D.Normalize(tempEndPath - planetEntity.GetPosition()); tempEndPath = endUpDir * startCoordsDistFromCenter + planetEntity.GetPosition(); //Check Path var tempMatrix = MatrixD.CreateWorld(tempStartPath, randPathDir, upDir); var truePathDir = Vector3D.Normalize(tempEndPath - tempStartPath); bool badPath = false; foreach (var prefab in spawnGroup.SpawnGroup.Prefabs) { var modifiedStart = Vector3D.Transform((Vector3D)prefab.Position, tempMatrix); double totalSteps = 0; while (totalSteps < randPathDist) { var testPath = totalSteps * truePathDir + modifiedStart; if (SpawnResources.IsPositionInSafeZone(testPath) == true) { badPath = true; break; } if (SpawnResources.GetDistanceFromSurface(testPath, planet) < Settings.PlanetaryCargoShips.MinPathAltitude) { badPath = true; break; } totalSteps += Settings.PlanetaryCargoShips.PathStepCheckDistance; } if (badPath == true) { break; } } if (badPath == true) { continue; } startPathCoords = tempStartPath; endPathCoords = tempEndPath; startMatrix = tempMatrix; return(true); } return(false); }
public static bool GetSpawnCoords(ImprovedSpawnGroup spawnGroup, Vector3D startCoords, out Vector3D spawnCoords) { spawnCoords = Vector3D.Zero; SpawnResources.RefreshEntityLists(); MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords); var planetEntity = planet as IMyEntity; double extraDistance = 0; double terrainVarianceCheckTarget = Settings.PlanetaryInstallations.SmallTerrainCheckDistance; if (planetEntity == null || planet == null) { Logger.AddMsg("Planet Somehow Doesn't Exist... Even Though It Should If Script Got Here...", true); return(false); } if (spawnGroup.PlanetaryInstallationType == "Medium") { extraDistance = Settings.PlanetaryInstallations.MediumSpawnDistanceIncrement; terrainVarianceCheckTarget = Settings.PlanetaryInstallations.MediumTerrainCheckDistance; } if (spawnGroup.PlanetaryInstallationType == "Large") { extraDistance = Settings.PlanetaryInstallations.LargeSpawnDistanceIncrement; terrainVarianceCheckTarget = Settings.PlanetaryInstallations.LargeTerrainCheckDistance; } var startDist = Settings.PlanetaryInstallations.MinimumSpawnDistanceFromPlayers + extraDistance; var endDist = Settings.PlanetaryInstallations.MaximumSpawnDistanceFromPlayers + extraDistance; var upDir = Vector3D.Normalize(startCoords - planetEntity.GetPosition()); var forwardDir = Vector3D.Normalize(MyUtils.GetRandomPerpendicularVector(ref upDir)); var searchMatrix = MatrixD.CreateWorld(startCoords, forwardDir, upDir); //Searches in 8 directions from the player position var searchDirections = new List <Vector3D>(); searchDirections.Add(searchMatrix.Forward); searchDirections.Add(searchMatrix.Backward); searchDirections.Add(searchMatrix.Left); searchDirections.Add(searchMatrix.Right); if (Settings.PlanetaryInstallations.AggressivePathCheck == true) { searchDirections.Add(Vector3D.Normalize(searchMatrix.Forward + searchMatrix.Left)); searchDirections.Add(Vector3D.Normalize(searchMatrix.Forward + searchMatrix.Right)); searchDirections.Add(Vector3D.Normalize(searchMatrix.Backward + searchMatrix.Left)); searchDirections.Add(Vector3D.Normalize(searchMatrix.Backward + searchMatrix.Right)); } int debugSpawnPointAttempts = 0; int searchDirectionAttempts = 0; foreach (var searchDirection in searchDirections) { searchDirectionAttempts++; double searchIncrement = startDist; while (searchIncrement < endDist) { debugSpawnPointAttempts++; var checkCoords = searchDirection * searchIncrement + startCoords; var surfaceCoords = SpawnResources.GetNearestSurfacePoint(checkCoords, planet); if (SpawnResources.IsPositionNearEntity(surfaceCoords, Settings.PlanetaryInstallations.MinimumSpawnDistanceFromOtherGrids) == true || SpawnResources.IsPositionInSafeZone(surfaceCoords) == true) { searchIncrement += Settings.PlanetaryInstallations.SearchPathIncrement; continue; } var checkUpDir = Vector3D.Normalize(surfaceCoords - planetEntity.GetPosition()); var checkForwardDir = Vector3D.Normalize(MyUtils.GetRandomPerpendicularVector(ref checkUpDir)); var checkMatrix = MatrixD.CreateWorld(surfaceCoords, checkForwardDir, checkUpDir); var checkDirections = new List <Vector3D>(); checkDirections.Add(checkMatrix.Forward); checkDirections.Add(checkMatrix.Backward); checkDirections.Add(checkMatrix.Left); checkDirections.Add(checkMatrix.Right); if (Settings.PlanetaryInstallations.AggressiveTerrainCheck == true) { checkDirections.Add(Vector3D.Normalize(checkMatrix.Forward + checkMatrix.Left)); checkDirections.Add(Vector3D.Normalize(checkMatrix.Forward + checkMatrix.Right)); checkDirections.Add(Vector3D.Normalize(checkMatrix.Backward + checkMatrix.Left)); checkDirections.Add(Vector3D.Normalize(checkMatrix.Backward + checkMatrix.Right)); } var distToCore = Vector3D.Distance(surfaceCoords, planetEntity.GetPosition()); bool badPosition = false; if (spawnGroup.SkipTerrainCheck == false) { foreach (var checkDirection in checkDirections) { double terrainCheckIncrement = 0; while (terrainCheckIncrement < terrainVarianceCheckTarget) { var checkTerrainCoords = checkDirection * terrainCheckIncrement + surfaceCoords; var checkTerrainSurfaceCoords = SpawnResources.GetNearestSurfacePoint(checkTerrainCoords, planet); var checkDistToCore = Vector3D.Distance(checkTerrainSurfaceCoords, planetEntity.GetPosition()); var elevationDiff = checkDistToCore - distToCore; if (elevationDiff < Settings.PlanetaryInstallations.MinimumTerrainVariance || elevationDiff > Settings.PlanetaryInstallations.MaximumTerrainVariance) { badPosition = true; break; } terrainCheckIncrement += Settings.PlanetaryInstallations.TerrainCheckIncrementDistance; } if (badPosition == true) { break; } } } if (badPosition == false) { spawnCoords = surfaceCoords; Logger.AddMsg("Found Installation Site After: " + debugSpawnPointAttempts.ToString() + " Attempts", true); Logger.AddMsg("Search Directions Used: " + searchDirectionAttempts.ToString(), true); return(true); } searchIncrement += Settings.PlanetaryInstallations.SearchPathIncrement; } } Logger.AddMsg("Could Not Find Installation Site After: " + debugSpawnPointAttempts.ToString() + " Attempts", true); return(false); }
public static bool CalculateRegularTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords) { startPathCoords = Vector3D.Zero; endPathCoords = Vector3D.Zero; SpawnResources.RefreshEntityLists(); MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords); List <IMyEntity> nearbyEntities = new List <IMyEntity>(); for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++) { var randDir = Vector3D.Normalize(MyUtils.GetRandomVector3D()); var closestPathDist = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer); var closestPathPoint = randDir * closestPathDist + startCoords; bool tryInvertedDir = SpawnResources.IsPositionInGravity(closestPathPoint, planet); if (tryInvertedDir == true) { randDir = randDir * -1; closestPathPoint = randDir * closestPathDist + startCoords; if (SpawnResources.IsPositionInGravity(closestPathPoint, planet) == true) { continue; } } var pathDist = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance); var pathDir = Vector3D.Normalize(MyUtils.GetRandomPerpendicularVector(ref randDir)); var pathHalfDist = pathDist / 2; var tempPathStart = pathDir * pathHalfDist + closestPathPoint; pathDir = pathDir * -1; var tempPathEnd = pathDir * pathHalfDist + closestPathPoint; bool badPath = false; IHitInfo hitInfo = null; if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true) { continue; } foreach (var entity in SpawnResources.EntityList) { if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities) { badPath = true; break; } } if (badPath == true) { continue; } var upDir = Vector3D.CalculatePerpendicularVector(pathDir); var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir); foreach (var prefab in spawnGroup.Prefabs) { double stepDistance = 0; var tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix); while (stepDistance < pathDist) { stepDistance += Settings.SpaceCargoShips.PathCheckStep; var pathCheckCoords = pathDir * stepDistance + tempPrefabStart; if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true) { badPath = true; break; } } if (badPath == true) { break; } } if (badPath == true) { continue; } startPathCoords = tempPathStart; endPathCoords = tempPathEnd; return(true); } return(false); }
public static bool CalculateLunarTravelPath(MySpawnGroupDefinition spawnGroup, Vector3D startCoords, out Vector3D startPathCoords, out Vector3D endPathCoords) { startPathCoords = Vector3D.Zero; endPathCoords = Vector3D.Zero; SpawnResources.RefreshEntityLists(); MyPlanet planet = SpawnResources.GetNearestPlanet(startCoords); if (planet == null) { return(false); } var planetEntity = planet as IMyEntity; for (int i = 0; i < Settings.SpaceCargoShips.MaxSpawnAttempts; i++) { var spawnAltitude = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinLunarSpawnHeight, (int)Settings.SpaceCargoShips.MaxLunarSpawnHeight); var abovePlayer = SpawnResources.CreateDirectionAndTarget(planetEntity.GetPosition(), startCoords, startCoords, spawnAltitude); var midpointDist = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistanceFromPlayer, (int)Settings.SpaceCargoShips.MaxPathDistanceFromPlayer); var pathMidpoint = SpawnResources.GetRandomCompassDirection(abovePlayer, planet) * midpointDist + abovePlayer; var pathDist = (double)SpawnResources.rnd.Next((int)Settings.SpaceCargoShips.MinPathDistance, (int)Settings.SpaceCargoShips.MaxPathDistance); var pathDir = SpawnResources.GetRandomCompassDirection(abovePlayer, planet); var pathHalfDist = pathDist / 2; var tempPathStart = pathDir * pathHalfDist + pathMidpoint; pathDir = pathDir * -1; var tempPathEnd = pathDir * pathHalfDist + pathMidpoint; bool badPath = false; IHitInfo hitInfo = null; if (MyAPIGateway.Physics.CastLongRay(tempPathStart, tempPathEnd, out hitInfo, true) == true) { continue; } foreach (var entity in SpawnResources.EntityList) { if (Vector3D.Distance(tempPathStart, entity.GetPosition()) < Settings.SpaceCargoShips.MinSpawnDistFromEntities) { badPath = true; break; } } if (badPath == true) { continue; } var upDir = Vector3D.CalculatePerpendicularVector(pathDir); var pathMatrix = MatrixD.CreateWorld(tempPathStart, pathDir, upDir); foreach (var prefab in spawnGroup.Prefabs) { double stepDistance = 0; var tempPrefabStart = Vector3D.Transform((Vector3D)prefab.Position, pathMatrix); while (stepDistance < pathDist) { stepDistance += Settings.SpaceCargoShips.PathCheckStep; var pathCheckCoords = pathDir * stepDistance + tempPrefabStart; if (SpawnResources.IsPositionInSafeZone(pathCheckCoords) == true || SpawnResources.IsPositionInGravity(pathCheckCoords, planet) == true) { badPath = true; break; } } if (badPath == true) { break; } } if (badPath == true) { continue; } startPathCoords = tempPathStart; endPathCoords = tempPathEnd; return(true); } return(false); }
public static bool GetSpawnCoords(ImprovedSpawnGroup spawnGroup, Vector3D startCoords, out Vector3D spawnCoords) { spawnCoords = Vector3D.Zero; SpawnResources.RefreshEntityLists(); MyPlanet planet = SpawnResources.GetNearestPlanet(spawnCoords); for (int i = 0; i < Settings.RandomEncounters.SpawnAttempts; i++) { var spawnDir = Vector3D.Normalize(MyUtils.GetRandomVector3D()); var randDist = (double)SpawnResources.rnd.Next((int)Settings.RandomEncounters.MinSpawnDistanceFromPlayer, (int)Settings.RandomEncounters.MaxSpawnDistanceFromPlayer); var tempSpawnCoords = spawnDir * randDist + startCoords; if (SpawnResources.IsPositionInGravity(tempSpawnCoords, planet) == true) { spawnDir *= -1; tempSpawnCoords = spawnDir * randDist + startCoords; if (SpawnResources.IsPositionInGravity(tempSpawnCoords, planet) == true) { continue; } } var tempMatrix = MatrixD.CreateWorld(tempSpawnCoords); var badPath = false; foreach (var prefab in spawnGroup.SpawnGroup.Prefabs) { var prefabCoords = Vector3D.Transform((Vector3D)prefab.Position, tempMatrix); planet = SpawnResources.GetNearestPlanet(prefabCoords); foreach (var entity in SpawnResources.EntityList) { if (Vector3D.Distance(entity.GetPosition(), prefabCoords) < Settings.RandomEncounters.MinDistanceFromOtherEntities) { badPath = true; break; } } if (SpawnResources.IsPositionInSafeZone(prefabCoords) == true || SpawnResources.IsPositionInGravity(prefabCoords, planet) == true) { badPath = true; break; } if (badPath == true) { break; } } if (badPath == true) { continue; } spawnCoords = tempSpawnCoords; return(true); } return(false); }