/// <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);
        }
Beispiel #6
0
        /// <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);
        }