/// <summary> /// Try to spawn another cave plant in the cluster or to spawn a new cluster. /// </summary> public static void TryToReproduce(CavePlant cavePlant) { // Test if it is growing on a fungiponics. if (CavePlant.IsOnCavePlantGrower(cavePlant.Position)) { return; } if (cavePlant.growth < minGrowthPercentToReproduce) { return; } if (CavePlant.IsTemperatureConditionOk(cavePlant.Position) == false) { return; } float chanceToReproduce = chanceToReproducePerDay / (30000f / GenTicks.TickLongInterval); if (Rand.Value < chanceToReproduce) { int cavePlantsInCluster = CountPlantsOfDefInRange(cavePlant.Position, cavePlant.GetClusterExclusivityRadius(), cavePlant.def); // Cluster is not mature, growth the cluster. if (cavePlantsInCluster < cavePlant.clusterSize) { TrySpawnCavePlantInThisCluster(cavePlant); } // Cluster is mature, spawn a new cluster. else { TrySpawnCavePlantInNewCluster(cavePlant); } } }
/// <summary> /// Try to spawn another cave plant in this cluster. /// </summary> public static void TrySpawnCavePlantInThisCluster(CavePlant cavePlant) { IntVec3 spawnPosition; if (GetRandomValidCellNearbyCluster(cavePlant, out spawnPosition)) { CavePlant newPlant = ThingMaker.MakeThing(cavePlant.def) as CavePlant; GenSpawn.Spawn(newPlant, spawnPosition); newPlant.clusterSize = cavePlant.clusterSize; } }
/// <summary> /// Try to spawn a new cluster away from cavePlant. /// </summary> public static void TrySpawnCavePlantInNewCluster(CavePlant cavePlant) { IntVec3 spawnPosition; int newClusterSize = Rand.RangeInclusive(cavePlant.def.plant.wildClusterSizeRange.min, cavePlant.def.plant.wildClusterSizeRange.max); if (GetRandomValidCellAwayFromCluster(cavePlant, newClusterSize, out spawnPosition)) { CavePlant newPlant = ThingMaker.MakeThing(cavePlant.def) as CavePlant; GenSpawn.Spawn(newPlant, spawnPosition); newPlant.clusterSize = newClusterSize; } }
/// <summary> /// Check if cell is valid to spawn a new cave plant. /// </summary> private static bool IsCellValidToSPawnANewCavePlant(IntVec3 cell) { bool cellIsValid = false; cellIsValid = Find.RoofGrid.Roofed(cell) && ((Find.ThingGrid.ThingsListAt(cell).Count == 0) || ((Find.ThingGrid.ThingAt(cell, ThingDef.Named("RockRubble")) != null) && (Find.ThingGrid.ThingAt(cell, ThingCategory.Plant) == null))) && CavePlant.IsLightConditionOk(cell) && CavePlant.IsNearNaturalRockBlock(cell) && CavePlant.IsTerrainConditionOk(cell) && CavePlant.IsTemperatureConditionOk(cell); return(cellIsValid); }
/// <summary> /// Get a valid cell to spawn a new cluster away from cavePlant. /// </summary> public static bool GetRandomValidCellAwayFromCluster(CavePlant cavePlant, int newClusterSize, out IntVec3 validCell) { float newClusterExclusivityRadius = CavePlant.GetClusterExclusivityRadius(cavePlant.def, newClusterSize); List <IntVec3> validCellsAwayFromCluster = new List <IntVec3>(); float newClusterMinDistance = cavePlant.GetClusterExclusivityRadius() + newClusterExclusivityRadius; float newClusterMaxDistance = 2f * newClusterMinDistance; IEnumerable <IntVec3> potentialCellsForNewCluster = GenRadial.RadialCellsAround(cavePlant.Position, newClusterMaxDistance, false); foreach (IntVec3 newClusterCell in potentialCellsForNewCluster) { if ((newClusterCell.InHorDistOf(cavePlant.Position, newClusterMinDistance) == false) && (newClusterCell.GetRoom() == cavePlant.GetRoom()) && IsCellValidToSPawnANewCavePlant(newClusterCell)) { float cavePlantSearchRadius = CavePlant.GetMaxClusterExclusivityRadius(cavePlant.def) * 2f; IEnumerable <IntVec3> cellsAroundNewCluster = GenRadial.RadialCellsAround(newClusterCell, cavePlantSearchRadius, false); bool anotherClusterIsTooClose = false; foreach (IntVec3 cell in cellsAroundNewCluster) { Thing potentialDistantCavePlant = Find.ThingGrid.ThingAt(cell, cavePlant.def); if (potentialDistantCavePlant != null) { CavePlant distantCavePlant = potentialDistantCavePlant as CavePlant; if (distantCavePlant.Position.InHorDistOf(cell, newClusterExclusivityRadius + distantCavePlant.GetClusterExclusivityRadius())) { anotherClusterIsTooClose = true; break; } } } if (anotherClusterIsTooClose == false) { validCellsAwayFromCluster.Add(newClusterCell); } } } if (validCellsAwayFromCluster.Count == 0) { validCell = new IntVec3(0, 0, 0); return(false); } validCell = validCellsAwayFromCluster.RandomElement <IntVec3>(); return(true); }
/// <summary> /// Tries to spawn a new cluster at a random position on the map. The exclusivity radius still applies. /// </summary> public bool TrySpawnNewClusterAtRandomPosition() { ThingDef cavePlantDef = GetRandomCavePlantDef(); int newClusterSize = Rand.RangeInclusive(cavePlantDef.plant.wildClusterSizeRange.min, cavePlantDef.plant.wildClusterSizeRange.max); float newClusterExclusivityRadius = CavePlant.GetClusterExclusivityRadius(cavePlantDef, newClusterSize); int checkedCellsNumber = 0; for (checkedCellsNumber = 0; checkedCellsNumber < 1000; checkedCellsNumber++) { IntVec3 newClusterCell = new IntVec3(Rand.Range(0, Find.Map.Size.x), 0, Rand.Range(0, Find.Map.Size.z)); if (Find.RoofGrid.Roofed(newClusterCell) && ((Find.ThingGrid.ThingsListAt(newClusterCell).Count == 0) || ((Find.ThingGrid.ThingAt(newClusterCell, ThingDef.Named("RockRubble")) != null) && (Find.ThingGrid.ThingAt(newClusterCell, ThingCategory.Plant) == null))) && CavePlant.IsLightConditionOk(newClusterCell) && CavePlant.IsNearNaturalRockBlock(newClusterCell) && CavePlant.IsTerrainConditionOk(newClusterCell) && CavePlant.IsTemperatureConditionOk(newClusterCell)) { float cavePlantSearchRadius = CavePlant.GetMaxClusterExclusivityRadius(cavePlantDef) * 2f; IEnumerable <IntVec3> cellsAroundNewCluster = GenRadial.RadialCellsAround(newClusterCell, cavePlantSearchRadius, false); bool anotherClusterIsTooClose = false; foreach (IntVec3 cell in cellsAroundNewCluster) { Thing potentialDistantCavePlant = Find.ThingGrid.ThingAt(cell, cavePlantDef); if (potentialDistantCavePlant != null) { CavePlant distantCavePlant = potentialDistantCavePlant as CavePlant; if (distantCavePlant.Position.InHorDistOf(cell, newClusterExclusivityRadius + distantCavePlant.GetClusterExclusivityRadius())) { anotherClusterIsTooClose = true; break; } } } if (anotherClusterIsTooClose == false) { GenSpawn.Spawn(cavePlantDef, newClusterCell); return(true); } } } return(false); }
/// <summary> /// Get a valid cell in this cluster to spawn another cave plant. /// </summary> public static bool GetRandomValidCellNearbyCluster(CavePlant cavePlant, out IntVec3 validCell) { List <IntVec3> validCellsNearbyCluster = new List <IntVec3>(); IEnumerable <IntVec3> cellsNearbyCluster = GenAdj.CellsAdjacent8Way(cavePlant); foreach (IntVec3 cell in cellsNearbyCluster) { if ((cell.GetRoom() == cavePlant.GetRoom()) && IsCellValidToSPawnANewCavePlant(cell)) { validCellsNearbyCluster.Add(cell); } } if (validCellsNearbyCluster.Count == 0) { validCell = new IntVec3(0, 0, 0); return(false); } validCell = validCellsNearbyCluster.RandomElement <IntVec3>(); return(true); }