/// <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> /// 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); } } }