public List <Speciality> getSettlementTileSpecialities(int tile) { ExposableList <Speciality> specialityList = null; if (settlementSpecialities.ContainsKey(tile)) { specialityList = settlementSpecialities[tile]; } else { float baseHumanMoveCost = 2500; int ticksPerDay = 60000 / 24 * 16; int searchDistance = ticksPerDay * 2; float moveCost = baseHumanMoveCost; Func <int, int, Speciality, bool> extraValidator = null; bool hasMountable = false; if (RimEconomy.GiddyUpCoreType != null) { extraValidator = (int currentPlace, int distanceInTiles, Speciality speciality) => { if (speciality != null && speciality.AnimalSpeciality != null) { bool mountable = (bool)RimEconomy.GiddyUpCoreType.GetMethod("isAllowedInModOptions", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[] { speciality.AnimalSpeciality.race.defName }); if (mountable) { hasMountable = true; return(true); } } return(false); }; } specialityList = getTileNeighboringSpecialities(tile, searchDistance, moveCost, extraValidator); if (RimEconomy.GiddyUpCoreType != null && hasMountable) { moveCost = moveCost / (1 + RimEconomy.GiddyUpCaravanBonus / 100); specialityList = getTileNeighboringSpecialities(tile, searchDistance, moveCost); } settlementSpecialities[tile] = specialityList; } return(specialityList); }
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); }