private bool GetCoverPositionFrom(Pawn pawn, IntVec3 fromPosition, float maxDist, out IntVec3 coverPosition) { //First check if we have cover already Vector3 coverVec = (fromPosition - pawn.Position).ToVector3().normalized; IntVec3 coverCell = (pawn.Position.ToVector3Shifted() + coverVec).ToIntVec3(); Thing cover = coverCell.GetCover(); if (pawn.Position.Standable() && cover != null && !pawn.Position.ContainsStaticFire()) { coverPosition = pawn.Position; return(true); } List <IntVec3> cellList = new List <IntVec3>(GenRadial.RadialCellsAround(pawn.Position, maxDist, true)); IntVec3 nearestPosWithPlantCover = IntVec3.Invalid; //Store the nearest position with plant cover here as a fallback in case we find no hard cover //Go through each cell in radius around the pawn foreach (IntVec3 cell in cellList) { //Sanity checks if (cell.IsValid && cell.Standable() && !Find.PawnDestinationManager.DestinationIsReserved(cell) && pawn.CanReach(cell, PathEndMode.ClosestTouch, Danger.Deadly, false) && !cell.FireNearby()) { coverVec = (fromPosition - cell).ToVector3().normalized; //The direction in which we want to have cover coverCell = (cell.ToVector3Shifted() + coverVec).ToIntVec3(); //The cell we check for cover cover = coverCell.GetCover(); if (cover != null) { //If the cover is a plant we store the location for later if (cover.def.category == ThingCategory.Plant && nearestPosWithPlantCover == IntVec3.Invalid) { nearestPosWithPlantCover = cell; } //The cell has hard cover in the direction we want, so we return the cell and report success else { coverPosition = cell; return(true); } } } } //No hard cover to move up to, use nearest plant cover instead and report success if (nearestPosWithPlantCover.IsValid) { coverPosition = nearestPosWithPlantCover; return(true); } //No hard nor plant cover in the radius, report failure coverPosition = IntVec3.Invalid; return(false); }
public void spawnSpecialPlants(IntVec3 c) { List <ThingDef> list = new List <ThingDef>() { ThingDef.Named("TKKN_SaltCrystal"), }; TerrainDef terrain = c.GetTerrain(map); if (terrain.defName == "TKKN_SaltField" || terrain.defName == "TKKN_SandBeachWetSalt") { if (c.GetEdifice(map) == null && c.GetCover(map) == null && Rand.Value < .003f) { ThingDef thingDef = ThingDef.Named("TKKN_SaltCrystal"); Plant plant = (Plant)ThingMaker.MakeThing(thingDef, null); plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } GenSpawn.Spawn(plant, c, map); } } }
private void spawnPlant(IntVec3 place, MapGenFloatGrid caves, float desiredTotalDensity, ThingDef plantDef) { if (place.GetEdifice(map) == null && place.GetCover(map) == null && caves[place] <= 0f) { float num2 = map.fertilityGrid.FertilityAt(place); float num3 = num2 * desiredTotalDensity; if (Rand.Value < num3) { for (int j = 0; j < plantDef.plant.wildClusterSizeRange.RandomInRange; j++) { IntVec3 c2; if (j == 0) { c2 = place; } else if (!GenPlantReproduction.TryFindReproductionDestination(place, plantDef, SeedTargFindMode.MapGenCluster, map, out c2)) { break; } Plant plant = (Plant)ThingMaker.MakeThing(plantDef, null); plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } GenSpawn.Spawn(plant, c2, map); } } } }
public static bool CheckSpawnWildPlantAt(WildPlantSpawner __instance, ref bool __result, IntVec3 c, float plantDensity, float wholeMapNumDesiredPlants, bool setRandomGrowth = false) { Map map2 = map(__instance); if (plantDensity <= 0f || c.GetPlant(map2) != null || c.GetCover(map2) != null || c.GetEdifice(map2) != null || map2.fertilityGrid.FertilityAt(c) <= 0f || !PlantUtility.SnowAllowsPlanting(c, map2)) { __result = false; return(false); } bool cavePlants = GoodRoofForCavePlant2(map2, c); if (SaturatedAt2(map2, c, plantDensity, cavePlants, wholeMapNumDesiredPlants)) { __result = false; return(false); } List <ThingDef> tmpPossiblePlants = new List <ThingDef>(); CalculatePlantsWhichCanGrowAt2(__instance, c, tmpPossiblePlants, cavePlants, plantDensity); if (!tmpPossiblePlants.Any()) { __result = false; return(false); } Dictionary <ThingDef, float> distanceSqToNearbyClusters = CalculateDistancesToNearbyClusters2(__instance, c); List <KeyValuePair <ThingDef, float> > tmpPossiblePlantsWithWeight = new List <KeyValuePair <ThingDef, float> >(); tmpPossiblePlantsWithWeight.Clear(); for (int i = 0; i < tmpPossiblePlants.Count; i++) { float value = PlantChoiceWeight2(__instance, tmpPossiblePlants[i], c, distanceSqToNearbyClusters, wholeMapNumDesiredPlants, plantDensity); tmpPossiblePlantsWithWeight.Add(new KeyValuePair <ThingDef, float>(tmpPossiblePlants[i], value)); } if (!tmpPossiblePlantsWithWeight.TryRandomElementByWeight((KeyValuePair <ThingDef, float> x) => x.Value, out KeyValuePair <ThingDef, float> result)) { __result = false; return(false); } Plant plant = (Plant)ThingMaker.MakeThing(result.Key); if (setRandomGrowth) { plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } } GenSpawn.Spawn(plant, c, map2); __result = true; return(false); }
public bool CheckSpawnWildPlantAt(IntVec3 c, float plantDensity, float wholeMapNumDesiredPlants, bool setRandomGrowth = false) { bool result; if (plantDensity <= 0f || c.GetPlant(this.map) != null || c.GetCover(this.map) != null || c.GetEdifice(this.map) != null || this.map.fertilityGrid.FertilityAt(c) <= 0f || !GenPlant.SnowAllowsPlanting(c, this.map)) { result = false; } else { bool cavePlants = this.GoodRoofForCavePlant(c); if (this.SaturatedAt(c, plantDensity, cavePlants, wholeMapNumDesiredPlants)) { result = false; } else { this.CalculatePlantsWhichCanGrowAt(c, WildPlantSpawner.tmpPossiblePlants, cavePlants, plantDensity); if (!WildPlantSpawner.tmpPossiblePlants.Any <ThingDef>()) { result = false; } else { this.CalculateDistancesToNearbyClusters(c); WildPlantSpawner.tmpPossiblePlantsWithWeight.Clear(); for (int i = 0; i < WildPlantSpawner.tmpPossiblePlants.Count; i++) { float value = this.PlantChoiceWeight(WildPlantSpawner.tmpPossiblePlants[i], c, WildPlantSpawner.distanceSqToNearbyClusters, wholeMapNumDesiredPlants, plantDensity); WildPlantSpawner.tmpPossiblePlantsWithWeight.Add(new KeyValuePair <ThingDef, float>(WildPlantSpawner.tmpPossiblePlants[i], value)); } KeyValuePair <ThingDef, float> keyValuePair; if (!WildPlantSpawner.tmpPossiblePlantsWithWeight.TryRandomElementByWeight((KeyValuePair <ThingDef, float> x) => x.Value, out keyValuePair)) { result = false; } else { Plant plant = (Plant)ThingMaker.MakeThing(keyValuePair.Key, null); if (setRandomGrowth) { plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } } GenSpawn.Spawn(plant, c, this.map, WipeMode.Vanish); result = true; } } } } return(result); }
private void genPlants(IntVec3 c, Map map, List <ThingDef> list) { if (c.GetEdifice(map) == null && c.GetCover(map) == null) { IEnumerable <ThingDef> source = from def in list where def.CanEverPlantAt(c, map) select def; if (source.Any <ThingDef>()) { ThingDef thingDef = source.RandomElementByWeight((ThingDef x) => this.PlantChoiceWeight(x, map)); Plant plant = (Plant)ThingMaker.MakeThing(thingDef, null); plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } GenSpawn.Spawn(plant, c, map); } } }
private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 shooterPos) { // Check for invalid locations if (!cell.IsValid || !cell.Standable(pawn.Map) || !pawn.CanReserveAndReach(cell, PathEndMode.OnCell, Danger.Deadly) || cell.ContainsStaticFire(pawn.Map)) { return(-1); } float cellRating = 0; if (!GenSight.LineOfSight(shooterPos, cell, pawn.Map)) { cellRating += 2f; } else { //Check if cell has cover in desired direction Vector3 coverVec = (shooterPos - cell).ToVector3().normalized; IntVec3 coverCell = (cell.ToVector3Shifted() + coverVec).ToIntVec3(); Thing cover = coverCell.GetCover(pawn.Map); cellRating += GetCoverRating(cover); } //Check time to path to that location if (!pawn.Position.Equals(cell)) { // float pathCost = pawn.Map.pathFinder.FindPath(pawn.Position, cell, TraverseMode.NoPassClosedDoors).TotalCost; float pathCost = (pawn.Position - cell).LengthHorizontal; if (!GenSight.LineOfSight(pawn.Position, cell, pawn.Map)) { pathCost *= 5; } cellRating = cellRating / pathCost; } return(cellRating); }
private void leaveLoot() { float leaveSomething = Rand.Value; if (leaveSomething < 0.001f) { float leaveWhat = Rand.Value; List <string> allowed = new List <string>(); if (leaveWhat > 0.1f) { //leave trash; allowed = new List <string> { "Filth_Slime", "TKKN_FilthShells", "TKKN_FilthPuddle", "TKKN_FilthSeaweed", "TKKN_FilthDriftwood", "TKKN_Sculpture_Shell", "Kibble", "EggRoeFertilized", "EggRoeUnfertilized", }; } else if (leaveWhat > 0.05f) { //leave resource; allowed = new List <string> { "Steel", "Cloth", "WoodLog", "Synthread", "Hyperweave", "Kibble", "SimpleProstheticLeg", "MedicineIndustrial", "ComponentIndustrial", "Neutroamine", "Chemfuel", "MealSurvivalPack", "Pemmican", }; } else if (leaveWhat > 0.03f) { // leave treasure. allowed = new List <string> { "Silver", "Plasteel", "Gold", "Uranium", "Jade", "Heart", "Lung", "BionicEye", "ScytherBlade", "ElephantTusk", }; string text = "TKKN_NPS_TreasureWashedUpText".Translate(); Messages.Message(text, MessageTypeDefOf.NeutralEvent); } else if (leaveWhat > 0.02f) { //leave ultrarare allowed = new List <string> { "AIPersonaCore", "MechSerumHealer", "MechSerumNeurotrainer", "ComponentSpacer", "MedicineUltratech", "ThrumboHorn", }; string text = "TKKN_NPS_UltraRareWashedUpText".Translate(); Messages.Message(text, MessageTypeDefOf.NeutralEvent); } if (allowed.Count > 0) { int leaveWhat2 = Rand.Range(1, allowed.Count) - 1; Thing loot = ThingMaker.MakeThing(ThingDef.Named(allowed[leaveWhat2]), null); if (loot != null) { GenSpawn.Spawn(loot, location, this.map); } else { // Log.Error(allowed[leaveWhat2]); } } } else //grow water and shore plants: if (leaveSomething < 0.002f && location.GetPlant(map) == null && location.GetCover(this.map) == null) { List <ThingDef> plants = this.map.Biome.AllWildPlants; for (int i = plants.Count - 1; i >= 0; i--) { //spawn some water plants: ThingDef plantDef = plants[i]; if (plantDef.HasModExtension <ThingWeatherReaction>()) { TerrainDef terrain = currentTerrain; ThingWeatherReaction thingWeather = plantDef.GetModExtension <ThingWeatherReaction>(); List <TerrainDef> okTerrains = thingWeather.allowedTerrains; if (okTerrains != null && okTerrains.Contains <TerrainDef>(currentTerrain)) { Plant plant = (Plant)ThingMaker.MakeThing(plantDef, null); plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } GenSpawn.Spawn(plant, location, map); break; } } } } }
/// <summary> /// Check if position is valid to grow a plant. Does not check cluster exclusivity! /// </summary> public static bool IsValidPositionToGrowPlant(ThingDef_ClusterPlant plantDef, Map map, IntVec3 position, bool checkTemperature = true) { if (position.InBounds(map) == false) { return(false); } if (plantDef.isSymbiosisPlant) { // For symbiosis plant, only check there is a source symbiosis plant. if (position.GetFirstThing(map, plantDef.symbiosisPlantDefSource) != null) { return(true); } else { return(false); } } // Check there is no building or cover. if ((position.GetEdifice(map) != null) || (position.GetCover(map) != null)) { return(false); } // Check terrain condition. if (ClusterPlant.CanTerrainSupportPlantAt(plantDef, map, position) == false) { return(false); } // Check temperature conditions. if (ClusterPlant.IsTemperatureConditionOkAt(plantDef, map, position) == false) { return(false); } // Check light conditions. if (ClusterPlant.IsLightConditionOkAt(plantDef, map, position) == false) { return(false); } // Check there is no other plant. if (map.thingGrid.ThingAt(position, ThingCategory.Plant) != null) { return(false); } // Check the cell is not blocked by a plant, an item, a pawn, a rock... List <Thing> thingList = map.thingGrid.ThingsListAt(position); for (int thingIndex = 0; thingIndex < thingList.Count; thingIndex++) { Thing thing = thingList[thingIndex]; if (thing.def.BlockPlanting) { return(false); } if (plantDef.passability == Traversability.Impassable && (thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Plant)) { return(false); } } // Check snow level. if (GenPlant.SnowAllowsPlanting(position, map) == false) { return(false); } return(true); }
public static void Postfix(WildPlantSpawner __instance, IntVec3 c, float plantDensity, float wholeMapNumDesiredPlants, bool setRandomGrowth, ref bool __result) { if (__result == false) { Map map = Traverse.Create(__instance).Field("map").GetValue <Map>(); if (!(plantDensity <= 0.0) && c.GetPlant(map) == null && c.GetCover(map) == null && c.GetEdifice(map) == null && PlantUtility.SnowAllowsPlanting(c, map)) { //check if we're on water or salt. TerrainDef terrain = c.GetTerrain(map); BiomeSeasonalSettings biomeSet = map.Biome.GetModExtension <BiomeSeasonalSettings>(); if (biomeSet.specialPlants != null) { //spawn any special plants WildPlantSpawner.tmpPossiblePlants this.CalculatePlantsWhichCanGrowAt(c, WildPlantSpawner.tmpPossiblePlants, cavePlants, plantDensity); if (!WildPlantSpawner.tmpPossiblePlants.Any()) { return(false); } this.CalculateDistancesToNearbyClusters(c); WildPlantSpawner.tmpPossiblePlantsWithWeight.Clear(); for (int i = 0; i < WildPlantSpawner.tmpPossiblePlants.Count; i++) { float value = this.PlantChoiceWeight(WildPlantSpawner.tmpPossiblePlants[i], c, WildPlantSpawner.distanceSqToNearbyClusters, wholeMapNumDesiredPlants, plantDensity); WildPlantSpawner.tmpPossiblePlantsWithWeight.Add(new KeyValuePair <ThingDef, float>(WildPlantSpawner.tmpPossiblePlants[i], value)); } KeyValuePair <ThingDef, float> keyValuePair = default(KeyValuePair <ThingDef, float>); if (!((IEnumerable <KeyValuePair <ThingDef, float> >)WildPlantSpawner.tmpPossiblePlantsWithWeight).TryRandomElementByWeight <KeyValuePair <ThingDef, float> >((Func <KeyValuePair <ThingDef, float>, float>)((KeyValuePair <ThingDef, float> x) => x.Value), out keyValuePair)) { return(false); } Plant plant = (Plant)ThingMaker.MakeThing(keyValuePair.Key, null); if (setRandomGrowth) { plant.Growth = Rand.Range(0.07f, 1f); if (plant.def.plant.LimitedLifespan) { plant.Age = Rand.Range(0, Mathf.Max(plant.def.plant.LifespanTicks - 50, 0)); } } GenSpawn.Spawn(plant, c, map, WipeMode.Vanish); return(true); } PlantDef = c.GetPlant(map); if (__result == true && plantDef != null && c != null && map != null) { BiomeDef biome = map.Biome; BiomeSeasonalSettings biomeSettings = biome.GetModExtension <BiomeSeasonalSettings>(); if (biomeSettings != null) { if (!biomeSettings.canPutOnTerrain(c, plantDef, map)) { __result = false; } } } } } }
static bool CheckSpawnWildPlantAt(IntVec3 c, float plantDensity, float wholeMapNumDesiredPlants, bool setRandomGrowth = false) { if (!(plantDensity <= 0.0) && c.GetPlant(this.map) == null && c.GetCover(this.map) == null && c.GetEdifice(this.map) == null && !(this.map.fertilityGrid.FertilityAt(c) <= 0.0) && PlantUtility.SnowAllowsPlanting(c, this.map)) { } }
public void DoCellSteadyEffects(IntVec3 c) { //must be outdoors. Map map = base.SingleMap; BiomeSeasonalSettings biomeSettings = base.SingleMap.Biome.GetModExtension <BiomeSeasonalSettings>(); List <ThingDef> bloomPlants = biomeSettings.bloomPlants.ToList <ThingDef>(); if (bloomPlants.Count == 0) { return; } Room room = c.GetRoom(base.SingleMap, RegionType.Set_All); if (room != null) { return; } TerrainDef terrain = c.GetTerrain(base.SingleMap); if (terrain.fertility == 0) { return; } if (!c.Roofed(base.SingleMap) && c.GetEdifice(base.SingleMap) == null && c.GetCover(base.SingleMap) == null) { List <Thing> thingList = c.GetThingList(base.SingleMap); bool planted = false; for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing is Plant) { if (Rand.Value < 0.0065f) { Plant plant = (Plant)ThingMaker.MakeThing(thing.def, null); if (plant.def.plant.LimitedLifespan && plant.def.statBases.GetStatOffsetFromList(StatDefOf.Beauty) > 3 && plant.def.ingestible.foodType != FoodTypeFlags.Tree) { plant.Growth = 1; } planted = true; } } } if (planted) { return; } } else { return; } if (Rand.Value < 0.65f * base.SingleMap.fertilityGrid.FertilityAt(c) * this.howManyBlooms) { IEnumerable <ThingDef> source = from def in bloomPlants where def.CanEverPlantAt(c, base.SingleMap) select def; if (source.Any <ThingDef>()) { ThingDef thingDef = source.RandomElement(); Plant plant = (Plant)ThingMaker.MakeThing(thingDef, null); plant.Growth = 1; GenSpawn.Spawn(plant, c, base.SingleMap); } } }
/// <summary> /// Check if position is valid to grow a plant. Does not check cluster exclusivity! /// </summary> public static bool IsValidPositionToGrowPlant(ThingDef_ClusterPlant plantDef, IntVec3 position, bool checkTemperature = true) { if (position.InBounds() == false) { return false; } if (plantDef.isSymbiosisPlant) { // For symbiosis plant, only check there is a source symbiosis plant. if (position.GetFirstThing(plantDef.symbiosisPlantDefSource) != null) { return true; } else { return false; } } // Check there is no building or cover. if ((position.GetEdifice() != null) || (position.GetCover() != null)) { return false; } // Check terrain condition. if (ClusterPlant.CanTerrainSupportPlantAt(plantDef, position) == false) { return false; } // Check temperature conditions. if (ClusterPlant.IsTemperatureConditionOkAt(plantDef, position) == false) { return false; } // Check light conditions. if (ClusterPlant.IsLightConditionOkAt(plantDef, position) == false) { return false; } // Check there is no other plant. if (Find.ThingGrid.ThingAt(position, ThingCategory.Plant) != null) { return false; } // Check the cell is not blocked by a plant, an item, a pawn, a rock... List<Thing> thingList = Find.ThingGrid.ThingsListAt(position); for (int thingIndex = 0; thingIndex < thingList.Count; thingIndex++) { Thing thing = thingList[thingIndex]; //Log.Message("checking thing + " + thing.ToString() + " at " + position.ToString()); if (thing.def.BlockPlanting) { return false; } if (plantDef.passability == Traversability.Impassable && (thing.def.category == ThingCategory.Pawn || thing.def.category == ThingCategory.Item || thing.def.category == ThingCategory.Building || thing.def.category == ThingCategory.Plant)) { return false; } } // Check snow level. if (GenPlant.SnowAllowsPlanting(position) == false) { return false; } return true; }