protected ExposableList <Speciality> getTileNeighboringSpecialities(int tile, int timeLimit, float moveCost, Func <int, int, Speciality, bool> extraValidator = null) { ExposableList <Speciality> specialityList = new ExposableList <Speciality>(); specialityList.Exposer = (List <Speciality> list) => { Scribe_Collections.Look <Speciality>(ref list, "data", LookMode.Reference); }; WorldGrid grid = Find.WorldGrid; Dictionary <int, float> timeCostToTile = new Dictionary <int, float>(); Find.WorldFloodFiller.FloodFill(tile, (int currentPlace) => { if (Find.World.Impassable(currentPlace)) { return(false); } Tile tileObject = grid.tiles[currentPlace]; if (tileObject == null || tileObject.WaterCovered || tileObject.hilliness == Hilliness.Impassable) { return(false); } if (currentPlace == tile) { timeCostToTile[currentPlace] = 0; return(true); } List <int> neighbors = new List <int>(6); grid.GetTileNeighbors(currentPlace, neighbors); float bestNeighborTimeCost = -1; int bestNeighbor = currentPlace; foreach (int neighborTile in neighbors) { if (timeCostToTile.ContainsKey(neighborTile)) { if (bestNeighborTimeCost < 0) { bestNeighborTimeCost = timeCostToTile[neighborTile]; } if (timeCostToTile[neighborTile] < bestNeighborTimeCost) { bestNeighborTimeCost = timeCostToTile[neighborTile]; bestNeighbor = neighborTile; } } } float timeCostToCurrentPlace = bestNeighborTimeCost + getMoveCost(bestNeighbor, currentPlace, moveCost); if (timeCostToCurrentPlace <= timeLimit) { timeCostToTile[currentPlace] = timeCostToCurrentPlace; return(true); } else { return(false); } }, (int currentPlace, int distanceInTiles) => { Speciality speciality = getTileSpeciality(currentPlace); if (speciality != null) { specialityList.Add(speciality); } if (extraValidator != null) { return(extraValidator(currentPlace, distanceInTiles, speciality)); } return(false); }); return(specialityList); }
private void generateSpecialities(string seed) { float chanceAnimal = RimEconomy.SettingFloat["specialityChanceAnimal"].Value; float chancePlant = RimEconomy.SettingFloat["specialityChancePlant"].Value; float chanceResourceRock = RimEconomy.SettingFloat["specialityChanceResourceRock"].Value; bool dontFilterSpeciality = RimEconomy.SettingBool["dontFilterSpeciality"].Value; float maxCommonalityOfAnimal = RimEconomy.SettingFloat["maxCommonalityOfAnimal"].Value; float maxCommonalityOfPlant = RimEconomy.SettingFloat["maxCommonalityOfPlant"].Value; if (seed != null) { Rand.Seed = GenText.StableStringHash(seed); } List <Tile> tiles = Find.WorldGrid.tiles; Dictionary <BiomeDef, IEnumerable <ThingDef> > biomePlantCache = new Dictionary <BiomeDef, IEnumerable <ThingDef> >(); Dictionary <BiomeDef, IEnumerable <PawnKindDef> > biomeAnimalCache = new Dictionary <BiomeDef, IEnumerable <PawnKindDef> >(); IEnumerable <ThingDef> resourceRocks = from d in DefDatabase <ThingDef> .AllDefs where d.category == ThingCategory.Building && d.building != null && d.building.isResourceRock select d; for (int i = 0; i <= Find.WorldGrid.TilesCount - 1; i++) { Tile tile = tiles[i]; if (!tile.WaterCovered) { BiomeDef biome = tile.biome; PawnKindDef animalKindDef = null; ThingDef plantDef = null; ThingDef resourceRock = null; if (Rand.Chance(chanceAnimal * biome.animalDensity)) { IEnumerable <PawnKindDef> animals = null; if (biomeAnimalCache.ContainsKey(biome)) { animals = biomeAnimalCache[biome]; } else { animals = biome.AllWildAnimals; biomeAnimalCache[biome] = animals; Log.Message("-----------deubg for animal----------------"); Log.Message("biome: " + biome); foreach (PawnKindDef def in animals) { Log.Message("def: " + def.race + " commonality: " + biome.CommonalityOfAnimal(def) / def.wildSpawn_GroupSizeRange.Average); } } animalKindDef = animals.RandomElementByWeight((PawnKindDef def) => { if (def.race == DefDatabase <ThingDef> .GetNamed("Rat", true)) { return(0); } if (def.wildSpawn_GroupSizeRange.Average > 0) { float commonality = biome.CommonalityOfAnimal(def) / def.wildSpawn_GroupSizeRange.Average; if (!dontFilterSpeciality && commonality >= maxCommonalityOfAnimal) { return(0); } return(commonality); } return(0); }); } if (Rand.Chance(chancePlant * biome.plantDensity)) { IEnumerable <ThingDef> plants = null; if (biomePlantCache.ContainsKey(biome)) { plants = biomePlantCache[biome]; } else { plants = from ThingDef def in biome.AllWildPlants where def.plant != null && (def.plant.harvestedThingDef != null || (def.plant.sowTags != null && def.plant.sowTags.Contains("Ground"))) select def; biomePlantCache[biome] = plants; Log.Message("-----------deubg for plant----------------"); Log.Message("biome: " + biome); foreach (ThingDef def in plants) { Log.Message("def: " + def + " commonality: " + biome.CommonalityOfPlant(def)); } } plantDef = plants.RandomElementByWeight((ThingDef def) => { if (def == DefDatabase <ThingDef> .GetNamed("PlantGrass", true)) { return(0); } float commonality = biome.CommonalityOfPlant(def); if (!dontFilterSpeciality && commonality >= maxCommonalityOfPlant) { return(0); } return(commonality); }); } if (Rand.Chance(chanceResourceRock)) { resourceRock = resourceRocks.RandomElementByWeight((ThingDef def) => def.building.mineableScatterCommonality); } if (animalKindDef != null || plantDef != null || resourceRock != null) { tileSpeciality[i] = new Speciality(i, animalKindDef, plantDef, resourceRock); } } } }
public List <Speciality> getSpecialityList() { Settlement settlement = TradeSession.trader as Settlement; if (settlement == null) { return(new List <Speciality>()); } List <Speciality> specialityList; if (specialityLists.ContainsKey(settlement)) { specialityList = specialityLists[settlement]; } else { specialityList = new List <Speciality>(); int ticksPerDay = 60000 / 24 * 14; WorldGrid grid = Find.WorldGrid; WorldPathFinder finder = Find.WorldPathFinder; SpecialityWorldManager specialityWorldManager = Find.World.GetComponent <SpecialityWorldManager>(); finder.FloodPathsWithCost(new List <int> { settlement.Tile }, (int currentPlace, int neighborPlace) => { float moveCost = 2500; Tile tile = grid.tiles[neighborPlace]; if (tile == null && tile.WaterCovered) { return(99999); } Season season = GenDate.Season(Find.TickManager.TicksGame, grid.LongLatOf(neighborPlace)); switch (season) { case Season.Spring: moveCost += tile.biome.pathCost_spring; break; case Season.Summer: case Season.PermanentSummer: moveCost += tile.biome.pathCost_summer; break; case Season.Fall: moveCost += tile.biome.pathCost_fall; break; case Season.Winter: case Season.PermanentWinter: moveCost += tile.biome.pathCost_winter; break; } moveCost *= grid.GetRoadMovementMultiplierFast(currentPlace, neighborPlace); return((int)moveCost); }, null, (int currentPlace, float cost) => { if (cost <= ticksPerDay) { Speciality speciality = specialityWorldManager.getSpeciality(currentPlace); if (speciality != null) { specialityList.Add(speciality); } return(false); } else { return(true); } }); specialityLists[settlement] = specialityList; } return(specialityList); }