public static void PostFix(ref float __result, int tile, bool perceivedStatic, int?ticksAbs, StringBuilder explanation) { if (__result <= 999f || !Find.WorldGrid.InBounds(tile)) { return; } try { var tile2 = Find.WorldGrid[tile]; if (tile2.Roads == null) { return; } RoadDef BestRoad = null; foreach (var roadLink in tile2.Roads) { var currentRoad = roadLink.road; if (currentRoad == null) { continue; } if (BestRoad == null) { BestRoad = currentRoad; continue; } if (BestRoad.movementCostMultiplier < currentRoad.movementCostMultiplier) { BestRoad = roadLink.road; } } var roadDefExtension = BestRoad?.GetModExtension <DefModExtension_RotR_RoadDef>(); if (roadDefExtension == null) { return; } if ((!tile2.biome.impassable || !(roadDefExtension.biomeModifier > 0)) && tile2.hilliness != Hilliness.Impassable) { return; } __result = 12f; RoadsOfTheRim.DebugLog( $"[RotR] - Impassable Tile {tile} of biome {tile2.biome.label} movement difficulty patched to 12"); } catch (Exception e) { RoadsOfTheRim.DebugLog( $"[RotR] - CalculatedMovementDifficultyAt Patch - Catastrophic failure for tile {Find.WorldGrid[tile]}", e); } }
public void updateRoadTech() { RoadDef def = this.roadDef; if (def == RoadDefOf.AncientAsphaltHighway) { return; } if (Find.ResearchManager.GetProgress(DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingHighway", false)) == DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingHighway", false).baseCost) { def = RoadDefOf.AncientAsphaltHighway; //Log.Message("Empire roadDef updated to " + def.ToString()); } else if (Find.ResearchManager.GetProgress(DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingRoad", false)) == DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingRoad", false).baseCost) { def = RoadDefOf.AncientAsphaltRoad; //Log.Message("Empire roadDef updated to " + def.ToString()); } else if (def != RoadDefOf.AncientAsphaltHighway && Find.ResearchManager.GetProgress(DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingDirt", false)) == DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingDirt", false).baseCost) { def = RoadDefOf.DirtRoad; //Log.Message("Empire roadDef updated to " + def.ToString()); } foreach (FCRoadBuilderQueue queue in roadQueues) { queue.roadDef = def; } this.roadDef = def; calculateRoadPathForWorld(); }
/* * For resources (including work) that are part of the cost of both the road to build and the best existing road, * grant CostUpgradeRebate% (default 30%) of the best existing road build costs as a rebate on the costs of the road to be built * i.e. the exisitng road cost 300 stones, the new road cost 600 stones, the rebate is 300*30% = 90 stones */ public static void GetUpgradeModifiers(int fromTile_int, int toTile_int, RoadDef roadToBuild, out Dictionary <string, int> rebate) { rebate = new Dictionary <string, int>(); RoadDef bestExistingRoad = RoadsOfTheRim.BestExistingRoad(fromTile_int, toTile_int); if (bestExistingRoad != null) { DefModExtension_RotR_RoadDef bestExistingRoadDefModExtension = bestExistingRoad.GetModExtension <DefModExtension_RotR_RoadDef>(); DefModExtension_RotR_RoadDef roadToBuildRoadDefModExtension = roadToBuild.GetModExtension <DefModExtension_RotR_RoadDef>(); if (bestExistingRoadDefModExtension != null && roadToBuildRoadDefModExtension != null && RoadsOfTheRim.isRoadBetter(roadToBuild, bestExistingRoad)) { foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork) { int existingCost = bestExistingRoadDefModExtension.GetCost(resourceName); int toBuildCost = roadToBuildRoadDefModExtension.GetCost(resourceName); if (existingCost != 0 && toBuildCost != 0) { if ((int)(existingCost * (float)RoadsOfTheRim.settings.CostUpgradeRebate / 100) > toBuildCost) { rebate[resourceName] = toBuildCost; } else { rebate[resourceName] = (int)(existingCost * (float)RoadsOfTheRim.settings.CostUpgradeRebate / 100); } } } } } }
public FCPlanetRoadQueue(string planetName, RoadDef roadDef, int daysBetweenTicks) { this.planetName = planetName ?? Find.World.info.name; this.roadDef = roadDef; this.daysBetweenTicks = daysBetweenTicks; this.nextRoadTick = this.nextRoadTick == 0 ? Find.TickManager.TicksGame : this.nextRoadTick; }
public void CheckForTechChanges() { FactionFC faction = Find.World.GetComponent <FactionFC>(); RoadDef def = this.roadDef; if (DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingHighway", false).IsFinished) { def = RoadDefOf.AncientAsphaltHighway; } else if (DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingRoad", false).IsFinished) { def = RoadDefOf.AncientAsphaltRoad; } else if (DefDatabase <ResearchProjectDef> .GetNamed("FCRoadBuildingDirt", false).IsFinished) { def = RoadDefOf.DirtRoad; } if (this.roadDef != def) { this.roadDef = def; foreach (FCPlanetRoadQueue queue in this.roadQueues) { queue.RoadDef = def; } } }
public void TryToSkipBetterRoads(Caravan caravan = null) { RoadConstructionLeg nextLeg = GetNextLeg(); if (nextLeg != null) // nextLeg == null should never happen { RoadDef bestExistingRoad = RoadsOfTheRim.BestExistingRoad(Tile, nextLeg.Tile); // We've found an existing road that is better than the one we intend to build : skip this leg and move to the next if (!RoadsOfTheRim.isRoadBetter(roadDef, bestExistingRoad)) { Messages.Message("RoadsOfTheRim_BetterRoadFound".Translate(caravan.Name, bestExistingRoad.label, roadDef.label), MessageTypeDefOf.NeutralEvent); int currentTile = Tile; Tile = nextLeg.Tile; // The construction site moves to the next leg RoadConstructionLeg nextNextLeg = nextLeg.Next; if (nextNextLeg != null) { nextNextLeg.Previous = null; // The nextNext leg is now the next GetComponent <WorldObjectComp_ConstructionSite>().setCosts(); MoveWorkersToNextLeg(currentTile); } else // Finish construction { GetComponent <WorldObjectComp_ConstructionSite>().EndConstruction(caravan); } Find.World.worldObjects.Remove(nextLeg); } } }
/// <summary> /// Builds 1 segment of road. Returns if a segment was built /// </summary> /// <returns> this.IsCompleted </returns> /// <param name="roadDef">Road def.</param> public bool BuildSegment(RoadDef roadDef) { start: if (!this.Path.Found || this.IsCompleted) { return(false); } int tile = this.Path.ConsumeNextNode(); int lastTile = this.Path.Peek(-1); WorldGrid grid = Find.WorldGrid; RoadDef existingRoad = grid.GetRoadDef(lastTile, tile); if (IsNewRoadBetter(existingRoad, roadDef)) { // Replaces the road if this.Road.priority > the existing road's priority grid.OverlayRoad(lastTile, tile, roadDef); Find.WorldPathGrid.RecalculatePerceivedMovementDifficultyAt(lastTile); Find.WorldPathGrid.RecalculatePerceivedMovementDifficultyAt(tile); } else { goto start; } return(true); }
public FCRoadBuilderQueue(string planetName, RoadDef roadDef) { this.planetName = planetName; this.ToBuild = new List <WorldPath>(); this.roadDef = roadDef; this.nextRoadTick = Find.TickManager.TicksGame + 60000; }
public static string ShowBestRoad(Pawn p) { RoadDef BestRoadDef = null; if (PawnBuildingUtility.HealthyColonist(p)) { foreach (RoadDef thisDef in DefDatabase <RoadDef> .AllDefs) { if (thisDef.HasModExtension <DefModExtension_RotR_RoadDef>() && thisDef.GetModExtension <DefModExtension_RotR_RoadDef>().built) // Only add RoadDefs that are buildable, based on DefModExtension_RotR_RoadDef.built { DefModExtension_RotR_RoadDef RoadDefMod = thisDef.GetModExtension <DefModExtension_RotR_RoadDef>(); if (PawnBuildingUtility.ConstructionLevel(p) >= RoadDefMod.minConstruction) { if ((BestRoadDef == null) || (thisDef.movementCostMultiplier < BestRoadDef.movementCostMultiplier)) { BestRoadDef = thisDef; } } } } if (BestRoadDef != null) { return(BestRoadDef.label); } } return("-"); }
public static int RandomBestExitTileFrom(Map map) { Tile tile = map.TileInfo; List <int> options = CaravanExitMapUtility.AvailableExitTilesAt(map); if (!options.Any()) { return(-1); } if (tile.roads == null) { return(options.RandomElement()); } int bestRoadIndex = -1; for (int i = 0; i < tile.roads.Count; i++) { List <int> list = options; Tile.RoadLink roadLink = tile.roads[i]; if (list.Contains(roadLink.neighbor)) { if (bestRoadIndex == -1) { goto IL_00e9; } Tile.RoadLink roadLink2 = tile.roads[i]; int priority = roadLink2.road.priority; Tile.RoadLink roadLink3 = tile.roads[bestRoadIndex]; if (priority > roadLink3.road.priority) { goto IL_00e9; } } continue; IL_00e9: bestRoadIndex = i; } if (bestRoadIndex == -1) { return(options.RandomElement()); } Tile.RoadLink roadLink4 = tile.roads.Where(delegate(Tile.RoadLink rl) { int result; if (options.Contains(rl.neighbor)) { RoadDef road = rl.road; Tile.RoadLink roadLink5 = tile.roads[bestRoadIndex]; result = ((road == roadLink5.road) ? 1 : 0); } else { result = 0; } return((byte)result != 0); }).RandomElement(); return(roadLink4.neighbor); }
public static bool BiomeAllowed(int tile, RoadDef roadDef, out BiomeDef biomeHere) { DefModExtension_RotR_RoadDef RoadDefMod = roadDef.GetModExtension <DefModExtension_RotR_RoadDef>(); biomeHere = Find.WorldGrid.tiles[tile].biome; if (RoadDefMod.canBuildOnWater && (biomeHere.defName == "Ocean" || biomeHere.defName == "Lake")) { return(true); } return(biomeHere.allowRoads); }
public static bool ImpassableAllowed(int tile, RoadDef roadDef) { DefModExtension_RotR_RoadDef RoadDefMod = roadDef.GetModExtension <DefModExtension_RotR_RoadDef>(); Hilliness hillinnessHere = Find.WorldGrid.tiles[tile].hilliness; if (RoadDefMod.canBuildOnImpassable && hillinnessHere == Hilliness.Impassable) { return(true); } return(hillinnessHere != Hilliness.Impassable); }
/******************************** * Convenience static functions * ********************************/ // Compares the movement cost multiplier of 2 roaddefs, returns TRUE if roadA is better or roadB is null. returns FALSE in all other cases public static bool isRoadBetter(RoadDef roadA, RoadDef roadB) { if (roadA == null) { return(false); } if (roadB == null) { return(true); } return(roadA.movementCostMultiplier < roadB.movementCostMultiplier); }
public bool testPath(WorldPath path) { WorldGrid grid = Find.WorldGrid; WorldPath testpath = new WorldPath(); testpath = path; List <int> nodeList = (List <int>)(typeof(WorldPath).GetField("nodes", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(testpath)); typeof(WorldPath).GetField("curNodeIndex", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(testpath, nodeList.Count - 1, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, null); int nodes = testpath.NodesLeftCount; int prevtile = testpath.FirstNode; int tile; bool hasRoad = true; for (int i = 0; i < nodes - 1; i++) { if (testpath.NodesLeftCount == 1) { tile = testpath.LastNode; } else { tile = testpath.ConsumeNextNode(); } RoadDef def = grid.GetRoadDef(prevtile, tile); if (def == roadDef) { prevtile = tile; continue; } if (def != null && isNewRoadBetter(def, roadDef)) { return(false); //road creatable } else if (def == null) { return(false); //road creatable } else //if road exists, but new road is not better { //Make no changes } prevtile = tile; continue; } return(true); }
public static bool IsNewRoadBetter(RoadDef oldRoad, RoadDef newRoad) { if (newRoad == null) { return(false); } if (oldRoad == null) { return(true); } return(newRoad.priority > oldRoad.priority); }
public static void PostFix(ref float __result, int tile, bool perceivedStatic, int?ticksAbs, StringBuilder explanation) { if (__result > 999f) { try { if (Find.WorldGrid.InBounds(tile)) { Tile tile2 = Find.WorldGrid.tiles[tile]; List <Tile.RoadLink> roads = tile2.Roads; if (roads?.Count > 0) { RoadDef BestRoad = null; for (int i = 0; i < roads.Count; i++) { if (BestRoad == null) { BestRoad = roads[i].road; } else { if (BestRoad.movementCostMultiplier < roads[i].road.movementCostMultiplier) { BestRoad = roads[i].road; } } } if (BestRoad != null) { DefModExtension_RotR_RoadDef roadDefExtension = BestRoad.GetModExtension <DefModExtension_RotR_RoadDef>(); if (roadDefExtension != null && ((tile2.biome.impassable && roadDefExtension.biomeModifier > 0) || (tile2.hilliness == Hilliness.Impassable))) { __result = 12f; //RoadsOfTheRim.DebugLog(String.Format("[RotR] - Impassable Tile {0} of biome {1} movement difficulty patched to 12", tile , tile2.biome.label)); } } } } else { RoadsOfTheRim.DebugLog("[RotR] - CalculatedMovementDifficultyAt Patch - Tile out of bounds"); } } catch (Exception e) { RoadsOfTheRim.DebugLog("[RotR] - CalculatedMovementDifficultyAt Patch - Catastrophic failure", e); return; } } }
public void OverlayRoad(int fromTile, int toTile, RoadDef roadDef) { if (roadDef == null) { Log.ErrorOnce("Attempted to remove road with overlayRoad; not supported", 90292249); return; } RoadDef roadDef2 = GetRoadDef(fromTile, toTile, visibleOnly: false); if (roadDef2 == roadDef) { return; } Tile tile = this[fromTile]; Tile tile2 = this[toTile]; if (roadDef2 != null) { if (roadDef2.priority >= roadDef.priority) { return; } tile.potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == toTile); tile2.potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == fromTile); } if (tile.potentialRoads == null) { tile.potentialRoads = new List <Tile.RoadLink>(); } if (tile2.potentialRoads == null) { tile2.potentialRoads = new List <Tile.RoadLink>(); } List <Tile.RoadLink> potentialRoads = tile.potentialRoads; Tile.RoadLink item = new Tile.RoadLink { neighbor = toTile, road = roadDef }; potentialRoads.Add(item); List <Tile.RoadLink> potentialRoads2 = tile2.potentialRoads; item = new Tile.RoadLink { neighbor = fromTile, road = roadDef }; potentialRoads2.Add(item); }
private void DrawLinksOnWorld(List <Link> linkFinal, List <int> indexToTile) { foreach (Link item in linkFinal) { WorldPath worldPath = Find.WorldPathFinder.FindPath(indexToTile[item.indexA], indexToTile[item.indexB], null); List <int> nodesReversed = worldPath.NodesReversed; RoadDef roadDef = DefDatabase <RoadDef> .AllDefsListForReading.Where((RoadDef rd) => !rd.ancientOnly).RandomElementWithFallback(); for (int i = 0; i < nodesReversed.Count - 1; i++) { Find.WorldGrid.OverlayRoad(nodesReversed[i], nodesReversed[i + 1], roadDef); } worldPath.ReleaseToPool(); } }
public static float calculateRoadModifier(RoadDef roadDef, float BiomeMovementDifficulty, float HillinessOffset, float WinterOffset, out float BiomeModifier, out float HillModifier, out float WinterModifier) { BiomeModifier = 0f; HillModifier = 0f; WinterModifier = 0f; if (roadDef.HasModExtension <DefModExtension_RotR_RoadDef>()) { BiomeModifier = roadDef.GetModExtension <DefModExtension_RotR_RoadDef>().biomeModifier; HillModifier = roadDef.GetModExtension <DefModExtension_RotR_RoadDef>().hillinessModifier; WinterModifier = roadDef.GetModExtension <DefModExtension_RotR_RoadDef>().winterModifier; } float BiomeCoef = (1 + (BiomeMovementDifficulty - 1) * (1 - BiomeModifier)) / BiomeMovementDifficulty; //RoadsOfTheRim.DebugLog("calculateRoadModifier: BiomeCoef=" +BiomeCoef+ ", BiomeMovementDifficulty="+ BiomeMovementDifficulty+ ", HillModifier"+ HillModifier+ ", HillinessOffset="+ HillinessOffset+ ", WinterModifier="+ WinterModifier+ ", WinterOffset="+ WinterOffset); return(((BiomeCoef * BiomeMovementDifficulty) + ((1 - HillModifier) * HillinessOffset) + ((1 - WinterModifier) * WinterOffset)) / (BiomeMovementDifficulty + HillinessOffset + WinterOffset)); }
private void DrawLinksOnWorld(List <WorldGenStep_Roads.Link> linkFinal, List <int> indexToTile) { foreach (WorldGenStep_Roads.Link current in linkFinal) { WorldPath worldPath = Find.WorldPathFinder.FindPath(indexToTile[current.indexA], indexToTile[current.indexB], null, null); List <int> nodesReversed = worldPath.NodesReversed; RoadDef roadDef = (from rd in DefDatabase <RoadDef> .AllDefsListForReading where !rd.ancientOnly select rd).RandomElementWithFallback(null); for (int i = 0; i < nodesReversed.Count - 1; i++) { Find.WorldGrid.OverlayRoad(nodesReversed[i], nodesReversed[i + 1], roadDef); } worldPath.ReleaseToPool(); } }
public void OverlayRoad(int fromTile, int toTile, RoadDef roadDef) { if (roadDef == null) { Log.ErrorOnce("Attempted to remove road with overlayRoad; not supported", 90292249, false); } else { RoadDef roadDef2 = this.GetRoadDef(fromTile, toTile, false); if (roadDef2 != roadDef) { Tile tile = this[fromTile]; Tile tile2 = this[toTile]; if (roadDef2 != null) { if (roadDef2.priority >= roadDef.priority) { return; } tile.potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == toTile); tile2.potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == fromTile); } if (tile.potentialRoads == null) { tile.potentialRoads = new List <Tile.RoadLink>(); } if (tile2.potentialRoads == null) { tile2.potentialRoads = new List <Tile.RoadLink>(); } tile.potentialRoads.Add(new Tile.RoadLink { neighbor = toTile, road = roadDef }); tile2.potentialRoads.Add(new Tile.RoadLink { neighbor = fromTile, road = roadDef }); } } }
public override IEnumerable <CaravanToil> MakeNewToils() { yield return(new CaravanToil() { initAction = delegate { //Log.Message("WorkStarted"); } }); yield return(CaravanToils_Goto.GotoObject(Verse.AI.TargetIndex.A)); CaravanToil nextToil = new CaravanToil() { initAction = delegate { if (BlueprintToWorkOn.nextBlueprint is RoadBlueprint nextBlueprint) { int fromTile = this.GetActor().Tile; int toTile = nextBlueprint.Tile; RoadDef roadDef2 = Find.WorldGrid.GetRoadDef(fromTile, toTile, false); if (roadDef2 != null) { if (roadDef2.priority >= DefToCheck.roadDef.priority) { Find.World.GetComponent <RoadTracker>().TryRemoveBlueprint(BlueprintToWorkOn); this.ReadyForNextToil(); return; } //Find.WorldGrid[fromTile].potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == toTile); //Find.WorldGrid[toTile].potentialRoads.RemoveAll((Tile.RoadLink rl) => rl.neighbor == fromTile); } } //Log.Message("WorkStarted2"); this.workLeft = BaseWorkAmount; if (!BlueprintToWorkOn.CheckAndConsumeResources(this.GetActor(), DefToCheck, true)) { Find.World.GetComponent <CaravanJobGiver>().Tracker(this.GetActor()).StopAll(); } },
public bool isNewRoadBetter(RoadDef old, RoadDef newroad) { if (old == newroad) { return(false); } if (newroad == RoadDefOf.AncientAsphaltHighway) { return(true); } if (newroad == RoadDefOf.AncientAsphaltRoad && old != RoadDefOf.AncientAsphaltHighway) { return(true); } if (newroad == RoadDefOf.DirtRoad && old == DefDatabase <RoadDef> .GetNamed("DirtPath")) { return(true); } return(false); }
/* * For resources (including work) that are part of the cost of both the road to build and the best existing road, * grant CostUpgradeRebate% (default 30%) of the best existing road build costs as a rebate on the costs of the road to be built * i.e. the exisitng road cost 300 stones, the new road cost 600 stones, the rebate is 300*30% = 90 stones */ private static void GetUpgradeModifiers(int fromTile_int, int toTile_int, RoadDef roadToBuild, out Dictionary <string, int> rebate) { rebate = new Dictionary <string, int>(); var bestExistingRoad = RoadsOfTheRim.BestExistingRoad(fromTile_int, toTile_int); if (bestExistingRoad == null) { return; } var bestExistingRoadDefModExtension = bestExistingRoad.GetModExtension <DefModExtension_RotR_RoadDef>(); var roadToBuildRoadDefModExtension = roadToBuild.GetModExtension <DefModExtension_RotR_RoadDef>(); if (bestExistingRoadDefModExtension == null || roadToBuildRoadDefModExtension == null || !RoadsOfTheRim.IsRoadBetter(roadToBuild, bestExistingRoad)) { return; } foreach (var resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork) { var existingCost = bestExistingRoadDefModExtension.GetCost(resourceName); var toBuildCost = roadToBuildRoadDefModExtension.GetCost(resourceName); if (existingCost == 0 || toBuildCost == 0) { continue; } if ((int)(existingCost * (float)RoadsOfTheRim.settings.CostUpgradeRebate / 100) > toBuildCost) { rebate[resourceName] = toBuildCost; } else { rebate[resourceName] = (int)(existingCost * (float)RoadsOfTheRim.settings.CostUpgradeRebate / 100); } } }
public static string ShowBestRoad(Pawn p) { RoadDef BestRoadDef = null; if (!HealthyColonist(p)) { return("-"); } foreach (var thisDef in DefDatabase <RoadDef> .AllDefs) { if (!thisDef.HasModExtension <DefModExtension_RotR_RoadDef>() || !thisDef.GetModExtension <DefModExtension_RotR_RoadDef>().built ) // Only add RoadDefs that are buildable, based on DefModExtension_RotR_RoadDef.built { continue; } var RoadDefMod = thisDef.GetModExtension <DefModExtension_RotR_RoadDef>(); if (ConstructionLevel(p) < RoadDefMod.minConstruction) { continue; } if (BestRoadDef != null && thisDef.movementCostMultiplier >= BestRoadDef.movementCostMultiplier) { continue; } BestRoadDef = thisDef; } if (BestRoadDef == null) { return("-"); } return(BestRoadDef.label); }
/* * Returns the road with the best movement cost multiplier between 2 neighbouring tiles. * returns null if there's no road or if the tiles are not neighbours */ public static RoadDef BestExistingRoad(int fromTile_int, int toTile_int) { RoadDef bestExistingRoad = null; try { var worldGrid = Find.WorldGrid; var fromTile = worldGrid[fromTile_int]; var toTile = worldGrid[toTile_int]; if (fromTile.potentialRoads != null) { foreach (var aLink in fromTile.potentialRoads) { if ((aLink.neighbor == toTile_int) & IsRoadBetter(aLink.road, bestExistingRoad)) { bestExistingRoad = aLink.road; } } } if (toTile.potentialRoads != null) { foreach (var aLink in toTile.potentialRoads) { if ((aLink.neighbor == fromTile_int) & IsRoadBetter(aLink.road, bestExistingRoad)) { bestExistingRoad = aLink.road; } } } } catch (Exception e) { DebugLog(null, e); } return(bestExistingRoad); }
protected override bool TryExecuteWorker(IncidentParms parms) { if (!TryGetRandomAvailableTargetMap(out map)) { return(false); } SettlementBase settlementBase = RandomNearbyTradeableSettlement(map.Tile); if (settlementBase == null) { return(false); } int destination = Rand.Chance(directConnectionChance) ? map.Tile : AllyOfNearbySettlement(settlementBase)?.Tile ?? map.Tile; int maxPriority = settlementBase.Faction.def.techLevel >= TechLevel.Medieval ? 30 : 20; RoadDef roadToBuild = DefDatabase <RoadDef> .AllDefsListForReading.Where(x => x.priority <= maxPriority).RandomElement(); WorldPath path = WorldPath.NotFound; //StringBuilder stringBuilder = new StringBuilder(); int cost2 = 12000; int timeToBuild = 0; string letterTitle = "MFI_RoadWorks".Translate(); List <WorldObject_RoadConstruction> list = new List <WorldObject_RoadConstruction>(); using (path = Find.WorldPathFinder.FindPath(destination, settlementBase.Tile, null)) { if (path != null && path != WorldPath.NotFound) { float roadCount = path.NodesReversed.Count(x => !Find.WorldGrid[x].Roads.NullOrEmpty() && Find.WorldGrid[x].Roads.Any(roadLink => roadLink.road.priority >= roadToBuild.priority) || Find.WorldObjects.AnyWorldObjectOfDefAt(MFI_DefOf.MFI_RoadUnderConstruction, x)); if (roadCount / path.NodesReversed.Count >= maxRoadCoverage) { Log.Message($"MFI :: too many roads leading from {(Find.WorldObjects.AnyWorldObjectAt(destination) ? Find.WorldObjects.ObjectsAt(destination).FirstOrDefault()?.Label : destination.ToString())} to {settlementBase} for road project"); return(false); } //stringBuilder.Append($"Path found from {settlementBase.Label} to {map.info.parent.Label}. Length = {path.NodesReversed.Count} "); //not 0 and - 1 for (int i = 1; i < path.NodesReversed.Count - 1; i++) { cost2 += Caravan_PathFollower.CostToMove(CaravanTicksPerMoveUtility.DefaultTicksPerMove, path.NodesReversed[i], path.NodesReversed[i + 1]); timeToBuild += (int)(2 * GenDate.TicksPerHour * WorldPathGrid.CalculatedMovementDifficultyAt(path.NodesReversed[i], true) * Find.WorldGrid.GetRoadMovementDifficultyMultiplier(i, i + 1)); if (!Find.WorldGrid[path.NodesReversed[i]].Roads.NullOrEmpty() && Find.WorldGrid[path.NodesReversed[i]].Roads.Any(roadLink => roadLink.road.priority >= roadToBuild.priority)) { timeToBuild = timeToBuild / 2; } WorldObject_RoadConstruction roadConstruction = (WorldObject_RoadConstruction)WorldObjectMaker.MakeWorldObject(MFI_DefOf.MFI_RoadUnderConstruction); roadConstruction.Tile = path.NodesReversed[i]; roadConstruction.nextTile = path.NodesReversed[i + 1]; roadConstruction.road = roadToBuild; roadConstruction.SetFaction(settlementBase.Faction); roadConstruction.projectedTimeOfCompletion = Find.TickManager.TicksGame + timeToBuild; list.Add(roadConstruction); } cost2 = cost2 / 10; DiaNode node = new DiaNode("MFI_RoadWorksDialogue".Translate(settlementBase, path.NodesReversed.Count, cost2)); // {settlementBase} wants {cost2 / 10} to build a road of {path.NodesReversed.Count}"); DiaOption accept = new DiaOption("OK".Translate()) { resolveTree = true, action = () => { TradeUtility.LaunchSilver(TradeUtility.PlayerHomeMapWithMostLaunchableSilver(), cost2); foreach (WorldObject_RoadConstruction worldObjectRoadConstruction in list) { Find.WorldObjects.Add(worldObjectRoadConstruction); } list.Clear(); } }; if (!TradeUtility.ColonyHasEnoughSilver(TradeUtility.PlayerHomeMapWithMostLaunchableSilver(), cost2)) { accept.Disable("NeedSilverLaunchable".Translate(cost2)); } DiaOption reject = new DiaOption("RejectLetter".Translate()) { resolveTree = true, action = () => { for (int i = list.Count - 1; i >= 0; i--) { list[i] = null; } list.Clear(); } }; node.options.Add(accept); node.options.Add(reject); //Log.Message(stringBuilder.ToString()); Find.WindowStack.Add(new Dialog_NodeTreeWithFactionInfo(node, settlementBase.Faction)); Find.Archive.Add(new ArchivedDialog(node.text, letterTitle, settlementBase.Faction)); } } return(true); }
private void RawDataToTiles() { if (this.tiles.Count != this.TilesCount) { this.tiles.Clear(); for (int m = 0; m < this.TilesCount; m++) { this.tiles.Add(new Tile()); } } else { for (int j = 0; j < this.TilesCount; j++) { this.tiles[j].potentialRoads = null; this.tiles[j].potentialRivers = null; } } DataSerializeUtility.LoadUshort(this.tileBiome, this.TilesCount, delegate(int i, ushort data) { this.tiles[i].biome = (DefDatabase <BiomeDef> .GetByShortHash(data) ?? BiomeDefOf.TemperateForest); }); DataSerializeUtility.LoadUshort(this.tileElevation, this.TilesCount, delegate(int i, ushort data) { this.tiles[i].elevation = (float)(data - 8192); }); DataSerializeUtility.LoadByte(this.tileHilliness, this.TilesCount, delegate(int i, byte data) { this.tiles[i].hilliness = (Hilliness)data; }); DataSerializeUtility.LoadUshort(this.tileTemperature, this.TilesCount, delegate(int i, ushort data) { this.tiles[i].temperature = (float)data / 10f - 300f; }); DataSerializeUtility.LoadUshort(this.tileRainfall, this.TilesCount, delegate(int i, ushort data) { this.tiles[i].rainfall = (float)data; }); DataSerializeUtility.LoadByte(this.tileSwampiness, this.TilesCount, delegate(int i, byte data) { this.tiles[i].swampiness = (float)data / 255f; }); int[] array = DataSerializeUtility.DeserializeInt(this.tileRoadOrigins); byte[] array2 = DataSerializeUtility.DeserializeByte(this.tileRoadAdjacency); ushort[] array3 = DataSerializeUtility.DeserializeUshort(this.tileRoadDef); for (int k = 0; k < array.Length; k++) { int num = array[k]; int tileNeighbor = this.GetTileNeighbor(num, (int)array2[k]); RoadDef byShortHash = DefDatabase <RoadDef> .GetByShortHash(array3[k]); if (byShortHash != null) { if (this.tiles[num].potentialRoads == null) { this.tiles[num].potentialRoads = new List <Tile.RoadLink>(); } if (this.tiles[tileNeighbor].potentialRoads == null) { this.tiles[tileNeighbor].potentialRoads = new List <Tile.RoadLink>(); } this.tiles[num].potentialRoads.Add(new Tile.RoadLink { neighbor = tileNeighbor, road = byShortHash }); this.tiles[tileNeighbor].potentialRoads.Add(new Tile.RoadLink { neighbor = num, road = byShortHash }); } } int[] array4 = DataSerializeUtility.DeserializeInt(this.tileRiverOrigins); byte[] array5 = DataSerializeUtility.DeserializeByte(this.tileRiverAdjacency); ushort[] array6 = DataSerializeUtility.DeserializeUshort(this.tileRiverDef); for (int l = 0; l < array4.Length; l++) { int num2 = array4[l]; int tileNeighbor2 = this.GetTileNeighbor(num2, (int)array5[l]); RiverDef byShortHash2 = DefDatabase <RiverDef> .GetByShortHash(array6[l]); if (byShortHash2 != null) { if (this.tiles[num2].potentialRivers == null) { this.tiles[num2].potentialRivers = new List <Tile.RiverLink>(); } if (this.tiles[tileNeighbor2].potentialRivers == null) { this.tiles[tileNeighbor2].potentialRivers = new List <Tile.RiverLink>(); } this.tiles[num2].potentialRivers.Add(new Tile.RiverLink { neighbor = tileNeighbor2, river = byShortHash2 }); this.tiles[tileNeighbor2].potentialRivers.Add(new Tile.RiverLink { neighbor = num2, river = byShortHash2 }); } } }
public RimRoadLink(RoadDef def, int a, int b) { this.def = def; this.indexA = a; this.indexB = b; }
static RemoveModernStuff() { DebugString.AppendLine("Lord of the Rings - The Third Age - Start Removal Log"); DebugString.AppendLine("Tech Limiter Active: Max Level = " + MAX_TECHLEVEL.ToString()); giveApproppriateTechLevels(); removedDefs = 0; IEnumerable <ResearchProjectDef> projects = DefDatabase <ResearchProjectDef> .AllDefs.Where(rpd => rpd.techLevel > MAX_TECHLEVEL); things = new HashSet <ThingDef>(DefDatabase <ThingDef> .AllDefs.Where(td => td.techLevel > MAX_TECHLEVEL || (td.researchPrerequisites?.Any(rpd => projects.Contains(rpd)) ?? false) || new[] { "Gun_Revolver", "VanometricPowerCell", "PsychicEmanator", "InfiniteChemreactor", "Joywire", "Painstopper" }.Contains(td.defName))); DebugString.AppendLine("RecipeDef Removal List"); var recipeDefsToRemove = DefDatabase <RecipeDef> .AllDefs.Where(rd => rd.products.Any(tcc => things.Contains(tcc.thingDef)) || rd.AllRecipeUsers.All(td => things.Contains(td)) || projects.Contains(rd.researchPrerequisite)).Cast <Def>().ToList(); recipeDefsToRemove?.RemoveAll(x => x.defName == "ExtractMetalFromSlag" || x.defName == "SmeltWeapon" || x.defName == "DestroyWeapon" || x.defName == "OfferingOfPlants_Meagre" || x.defName == "OfferingOfPlants_Decent" || x.defName == "OfferingOfPlants_Sizable" || x.defName == "OfferingOfPlants_Worthy" || x.defName == "OfferingOfPlants_Impressive" || x.defName == "OfferingOfMeat_Meagre" || x.defName == "OfferingOfMeat_Decent" || x.defName == "OfferingOfMeat_Sizable" || x.defName == "OfferingOfMeat_Worthy" || x.defName == "OfferingOfMeat_Impressive" || x.defName == "OfferingOfMeals_Meagre" || x.defName == "OfferingOfMeals_Decent" || x.defName == "OfferingOfMeals_Sizable" || x.defName == "OfferingOfMeals_Worthy" || x.defName == "OfferingOfMeals_Impressive" || x.defName == "ROMV_ExtractBloodVial" || x.defName == "ROMV_ExtractBloodPack" ); RemoveStuffFromDatabase(typeof(DefDatabase <RecipeDef>), recipeDefsToRemove); DebugString.AppendLine("ResearchProjectDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <ResearchProjectDef>), projects.Cast <Def>()); DebugString.AppendLine("Scenario Part Removal List"); FieldInfo getThingInfo = typeof(ScenPart_ThingCount).GetField("thingDef", BindingFlags.NonPublic | BindingFlags.Instance); foreach (ScenarioDef def in DefDatabase <ScenarioDef> .AllDefs) { foreach (ScenPart sp in def.scenario.AllParts) { if (sp is ScenPart_ThingCount && things.Contains((ThingDef)getThingInfo?.GetValue(sp))) { def.scenario.RemovePart(sp); DebugString.AppendLine("- " + sp.Label + " " + ((ThingDef)getThingInfo?.GetValue(sp)).label + " from " + def.label); } } } foreach (ThingCategoryDef thingCategoryDef in DefDatabase <ThingCategoryDef> .AllDefs) { thingCategoryDef.childThingDefs.RemoveAll(things.Contains); } DebugString.AppendLine("Stock Generator Part Cleanup"); foreach (TraderKindDef tkd in DefDatabase <TraderKindDef> .AllDefs) { for (int i = tkd.stockGenerators.Count - 1; i >= 0; i--) { StockGenerator stockGenerator = tkd.stockGenerators[i]; switch (stockGenerator) { case StockGenerator_SingleDef sd when things.Contains(Traverse.Create(sd).Field("thingDef") .GetValue <ThingDef>()): ThingDef def = Traverse.Create(sd).Field("thingDef") .GetValue <ThingDef>(); tkd.stockGenerators.Remove(stockGenerator); DebugString.AppendLine("- " + def.label + " from " + tkd.label + "'s StockGenerator_SingleDef"); break; case StockGenerator_MultiDef md: Traverse thingListTraverse = Traverse.Create(md).Field("thingDefs"); List <ThingDef> thingList = thingListTraverse.GetValue <List <ThingDef> >(); var removeList = thingList.FindAll(things.Contains); removeList?.ForEach(x => DebugString.AppendLine("- " + x.label + " from " + tkd.label + "'s StockGenerator_MultiDef")); thingList.RemoveAll(things.Contains); if (thingList.NullOrEmpty()) { tkd.stockGenerators.Remove(stockGenerator); } else { thingListTraverse.SetValue(thingList); } break; } } } DebugString.AppendLine("IncidentDef Removal List"); IEnumerable <IncidentDef> incidents = DefDatabase <IncidentDef> .AllDefs .Where(id => new[] { typeof (IncidentWorker_ShipChunkDrop ), AccessTools .TypeByName( "IncidentWorker_ShipPartCrash"), typeof (IncidentWorker_QuestJourneyOffer ), typeof (IncidentWorker_ResourcePodCrash ), //typeof(IncidentWorker_RefugeePodCrash), typeof(IncidentWorker_TransportPodCrash), typeof (IncidentWorker_PsychicDrone ), typeof (IncidentWorker_RansomDemand ), typeof (IncidentWorker_ShortCircuit ), typeof (IncidentWorker_OrbitalTraderArrival ), typeof (IncidentWorker_PsychicSoothe ) }.SelectMany( it => it .AllSubclassesNonAbstract() .Concat( it)) .ToArray() .Contains( id .workerClass) || new[] { "Disease_FibrousMechanites", "Disease_SensoryMechanites", "RaidEnemyEscapeShip", "StrangerInBlackJoin" }.Contains( id .defName)).ToList(); foreach (IncidentDef incident in incidents) { incident.targetTags?.Clear(); incident.baseChance = 0f; incident.allowedBiomes?.Clear(); incident.earliestDay = int.MaxValue; } RemoveStuffFromDatabase(typeof(DefDatabase <IncidentDef>), incidents.Cast <Def>()); DebugString.AppendLine("Replaced Ancient Asphalt Road / Ancient Asphalt Highway with Stone Road"); RoadDef[] targetRoads = { RoadDefOf.AncientAsphaltRoad, RoadDefOf.AncientAsphaltHighway }; RoadDef originalRoad = DefDatabase <RoadDef> .GetNamed("StoneRoad"); List <string> fieldNames = AccessTools.GetFieldNames(typeof(RoadDef)); fieldNames.Remove("defName"); foreach (FieldInfo fi in fieldNames.Select(name => AccessTools.Field(typeof(RoadDef), name))) { object fieldValue = fi.GetValue(originalRoad); foreach (RoadDef targetRoad in targetRoads) { fi.SetValue(targetRoad, fieldValue); } } DebugString.AppendLine("Special Hediff Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <HediffDef>), (hediffs = new[] { HediffDefOf.Gunshot }).Cast <Def>()); DebugString.AppendLine("RaidStrategyDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <RaidStrategyDef>), DefDatabase <RaidStrategyDef> .AllDefs .Where(rs => typeof(ScenPart_ThingCount).IsAssignableFrom(rs.workerClass)).Cast <Def>()); // ItemCollectionGeneratorUtility.allGeneratableItems.RemoveAll(match: things.Contains); // // foreach (Type type in typeof(ItemCollectionGenerator_Standard).AllSubclassesNonAbstract()) // type.GetMethod(name: "Reset")?.Invoke(obj: null, parameters: null); DebugString.AppendLine("ThingDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <ThingDef>), things.ToArray()); DebugString.AppendLine("ThingSetMaker Reset"); ThingSetMakerUtility.Reset(); DebugString.AppendLine("TraitDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <TraitDef>), // { nameof(TraitDefOf.Prosthophobe), "Prosthophile" } ? DefDatabase <TraitDef> .AllDefs .Where(td => new[] { nameof(TraitDefOf.BodyPurist), "Transhumanist" }.Contains(td.defName)) .Cast <Def>()); DebugString.AppendLine("Designators Resolved Again"); MethodInfo resolveDesignatorsAgain = typeof(DesignationCategoryDef).GetMethod("ResolveDesignators", BindingFlags.NonPublic | BindingFlags.Instance); foreach (DesignationCategoryDef dcd in DefDatabase <DesignationCategoryDef> .AllDefs) { resolveDesignatorsAgain?.Invoke(dcd, null); } DebugString.AppendLine("PawnKindDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <PawnKindDef>), DefDatabase <PawnKindDef> .AllDefs .Where(pkd => (!pkd.defaultFactionType?.isPlayer ?? false) && (pkd.race.techLevel > MAX_TECHLEVEL || pkd.defaultFactionType?.techLevel > MAX_TECHLEVEL) && !pkd.defName.EqualsIgnoreCase("Villager") && !pkd.defName.EqualsIgnoreCase("SpaceRefugee")) .Cast <Def>()); DebugString.AppendLine("FactionDef Removal List"); RemoveStuffFromDatabase(typeof(DefDatabase <FactionDef>), DefDatabase <FactionDef> .AllDefs.Where(fd => !fd.isPlayer && fd.techLevel > MAX_TECHLEVEL).Cast <Def>()); DebugString.AppendLine("BackstoryDef Removal List"); BackstoryHandler.RemoveIncompatibleBackstories(DebugString); DebugString.AppendLine("MapGeneratorDef Removal List"); DebugString.AppendLine("- GenStep_SleepingMechanoids"); DebugString.AppendLine("- GenStep_Turrets"); DebugString.AppendLine("- GenStep_Power"); foreach (MapGeneratorDef mgd in DefDatabase <MapGeneratorDef> .AllDefs) { mgd.genSteps.RemoveAll(gs => gs.genStep is GenStep_SleepingMechanoids || gs.genStep is GenStep_Turrets || gs.genStep is GenStep_Power); } DebugString.AppendLine("RuleDef Removal List"); DebugString.AppendLine("- SymbolResolver_AncientCryptosleepCasket"); DebugString.AppendLine("- SymbolResolver_ChargeBatteries"); DebugString.AppendLine("- SymbolResolver_EdgeMannedMortor"); DebugString.AppendLine("- SymbolResolver_FirefoamPopper"); DebugString.AppendLine("- SymbolResolver_MannedMortar"); DebugString.AppendLine("- SymbolResolver_"); foreach (RuleDef rd in DefDatabase <RuleDef> .AllDefs) { rd.resolvers.RemoveAll(sr => sr is SymbolResolver_AncientCryptosleepCasket || sr is SymbolResolver_ChargeBatteries || sr is SymbolResolver_EdgeMannedMortar || sr is SymbolResolver_FirefoamPopper || sr is SymbolResolver_MannedMortar || sr is SymbolResolver_OutdoorLighting); if (rd.resolvers.Count == 0) { rd.resolvers.Add(new SymbolResolver_AddWortToFermentingBarrels()); } } Log.Message("Removed " + removedDefs + " modern defs"); PawnWeaponGenerator.Reset(); PawnApparelGenerator.Reset(); Debug.Log(DebugString.ToString()); DebugString = new StringBuilder(); }