/* return a string describing modifiers to road costs building between two tiles, and sets totalCostModifer */ public static string CostModifersDescription(int fromTile_int, int toTile_int, ref float totalCostModifier) { StringBuilder result = new StringBuilder(); RoadsOfTheRimSettings settings = LoadedModManager.GetMod <RoadsOfTheRim>().GetSettings <RoadsOfTheRimSettings>(); // Show total cost modifiers float elevationModifier = 0f; float hillinessModifier = 0f; float swampinessModifier = 0f; float bridgeModifier = 0f; WorldObjectComp_ConstructionSite.GetCostsModifiers(fromTile_int, toTile_int, ref elevationModifier, ref hillinessModifier, ref swampinessModifier, ref bridgeModifier); result.Append("RoadsOfTheRim_ConstructionSiteDescription_CostModifiers".Translate( String.Format("{0:P0}", elevationModifier + hillinessModifier + swampinessModifier + bridgeModifier), String.Format("{0:P0}", elevationModifier), String.Format("{0:P0}", hillinessModifier), String.Format("{0:P0}", swampinessModifier), String.Format("{0:P0}", bridgeModifier) )); totalCostModifier = (1 + elevationModifier + hillinessModifier + swampinessModifier + bridgeModifier) * ((float)settings.BaseEffort / 10); return(result.ToString()); }
public override string GetInspectString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(base.GetInspectString()); if (stringBuilder.Length != 0) { stringBuilder.AppendLine(); } if (this.Next is null) { stringBuilder.Append("Goal"); } else { stringBuilder.Append("RoadsOfTheRim_siteInspectString".Translate(this.GetSite().roadDef.label, string.Format("{0:0.0}", this.GetSite().roadDef.movementCostMultiplier))); float totalCostModifier = 0f; stringBuilder.Append(WorldObjectComp_ConstructionSite.CostModifersDescription(this.Tile, this.Next.Tile, ref totalCostModifier)); // Show costs WorldObjectComp_ConstructionSite SiteComp = this.GetSite().GetComponent <WorldObjectComp_ConstructionSite>(); foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork) { if (SiteComp.GetCost(resourceName) > 0) { // The cost modifier doesn't affect some advanced resources, as defined in static DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers // TO DO : COuld this be combined with WorldObjectComp_ConstructionSite.setCosts() ? shares a lot in common except rebates. Can we really calcualte rebate on a leg ? float costModifierForThisResource = ((DefModExtension_RotR_RoadDef.allResourcesWithoutModifiers.Contains(resourceName)) ? 1 : totalCostModifier); stringBuilder.AppendLine(); stringBuilder.Append((int)SiteComp.GetCost(resourceName) * costModifierForThisResource + " " + resourceName); } } } return(stringBuilder.ToString()); }
public string progressDescription() { RoadConstructionSite parentSite = this.parent as RoadConstructionSite; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Main".Translate(String.Format("{0:P1}", GetPercentageDone("Work")))); // Description of ally's help, if any if (parentSite.helpFromFaction != null) { stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Help".Translate(parentSite.helpFromFaction.Name, (int)parentSite.helpAmount, String.Format("{0:0.0}", parentSite.helpWorkPerTick))); if (parentSite.helpFromTick > Find.TickManager.TicksGame) { stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_HelpStartsWhen".Translate(String.Format("{0:0.00}", (float)(parentSite.helpFromTick - Find.TickManager.TicksGame) / (float)GenDate.TicksPerDay))); } } // Show total cost modifiers float totalCostModifier = 0f; stringBuilder.Append(WorldObjectComp_ConstructionSite.CostModifersDescription(parentSite.Tile, parentSite.GetNextLeg().Tile, ref totalCostModifier)); List <Caravan> AllCaravansHere = new List <Caravan>(); Find.WorldObjects.GetPlayerControlledCaravansAt(parentSite.Tile, AllCaravansHere); int ISR2G = 0; foreach (Caravan c in AllCaravansHere) { int caravanISR2G = c.GetComponent <WorldObjectComp_Caravan>().useISR2G(); if (caravanISR2G > ISR2G) { ISR2G = caravanISR2G; } } // Per resource : show costs & how much is left to do foreach (string resourceName in DefModExtension_RotR_RoadDef.allResourcesAndWork) { if (GetCost(resourceName) > 0) { stringBuilder.AppendLine(); string ISR2Gmsg = ""; if (ISR2G > 0) { if (resourceName == "Work") { ISR2Gmsg = (ISR2G == 1 ? "RoadsOfTheRim_ConstructionSiteDescription_ISR2Gwork".Translate() : "RoadsOfTheRim_ConstructionSiteDescription_AISR2Gwork".Translate()); } else if (DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, ISR2G)) { ISR2Gmsg = (ISR2G == 1 ? "RoadsOfTheRim_ConstructionSiteDescription_ISR2GFree".Translate() : "RoadsOfTheRim_ConstructionSiteDescription_AISR2GFree".Translate()); } } stringBuilder.Append("RoadsOfTheRim_ConstructionSiteDescription_Resource".Translate( resourceName, String.Format((resourceName == "Work" ? "{0:##.00}" : "{0:##}"), GetLeft(resourceName)), // Only Work should be shown with 2 decimals (int)GetCost(resourceName), ISR2Gmsg )); } } return(stringBuilder.ToString()); }
/* * Based on the Caravan's resources, Pawns & the road's cost (modified by terrain) : * - Determine the amount of work done in a tick * - Consume the caravan's resources * - Return whether or not the Caravan must now stop because it ran out of resources * - NOTE : Does this need to be here ? Maybe better in Mod.cs * Returns TRUE if work finished * CALLED FROM : CompTick() of WorldObjectComp_Caravan */ public static bool doSomeWork(Caravan caravan, RoadConstructionSite site, out bool noMoreResources) { WorldObjectComp_Caravan caravanComp = caravan.GetComponent <WorldObjectComp_Caravan>(); WorldObjectComp_ConstructionSite siteComp = site.GetComponent <WorldObjectComp_ConstructionSite>(); DefModExtension_RotR_RoadDef roadDefExtension = site.roadDef.GetModExtension <DefModExtension_RotR_RoadDef>(); noMoreResources = false; int useISR2G = caravanComp.useISR2G(); Dictionary <string, int> available = new Dictionary <string, int>(); Dictionary <string, int> needed = new Dictionary <string, int>(); Dictionary <string, float> ratio = new Dictionary <string, float>(); float ratio_final = 1; //RoadsOfTheRim.DebugLog("[RotR] DEBUG ========== doSomeWork() =========="); //RoadsOfTheRim.DebugLog("[RotR] DEBUG ISR2G set to "+useISR2G); if (DebugSettings.godMode) { return(siteComp.finishWork(caravan)); } if (caravanComp.CaravanCurrentState() != CaravanState.ReadyToWork) { RoadsOfTheRim.DebugLog("[RotR] DEBUG : doSomeWork() failed because the caravan can't work."); return(false); } // Percentage of total work that can be done in this batch, might be 0 if no pawn was found with enough skill float amountOfWork = caravanComp.amountOfWork(true); // Work was 0 (not enough skill) if (Math.Abs(amountOfWork) < Double.Epsilon) { Messages.Message("RoadsOfTheRim_CaravanNoWork".Translate(caravan.Name, site.roadDef.label), MessageTypeDefOf.RejectInput); caravanComp.stopWorking(); return(false); } // calculate material present in the caravan foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources) { available[resourceName] = 0; } foreach (Thing aThing in CaravanInventoryUtility.AllInventoryItems(caravan)) { foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources) { if (isThis(aThing.def, resourceName)) { available[resourceName] += aThing.stackCount; } } } // What percentage of work will remain after amountOfWork is done ? float percentOfWorkLeftToDoAfter = (siteComp.GetLeft("Work") - amountOfWork) / siteComp.GetCost("Work"); // The amount of each resource left to spend in total is : percentOfWorkLeftToDoAfter * {this resource cost} // Materials that would be needed to do that much work foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources) { needed[resourceName] = (int)Math.Round(siteComp.GetLeft(resourceName) - (percentOfWorkLeftToDoAfter * siteComp.GetCost(resourceName))); // Check if there's enough material to go through this batch. Materials with a cost of 0 are always OK // Don't check when ISR2G is in use for this resource, don't check for work if (!DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, useISR2G) && resourceName != "Work") { ratio[resourceName] = (needed[resourceName] == 0 ? 1f : Math.Min((float)available[resourceName] / (float)needed[resourceName], 1f)); if (ratio[resourceName] < ratio_final) { ratio_final = ratio[resourceName]; } } } // The caravan didn't have enough resources for a full batch of work. Use as much as we can then stop working if (ratio_final < 1f) { Messages.Message("RoadsOfTheRim_CaravanNoResource".Translate(caravan.Name, site.roadDef.label), MessageTypeDefOf.RejectInput); foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources) { needed[resourceName] = (int)(needed[resourceName] * ratio_final); } caravanComp.stopWorking(); } //RoadsOfTheRim.DebugLog("[RotR] ISR2G DEBUG ratio final = " + ratio_final); // Consume resources from the caravan bool ResourcesHaveBeenConsumed = (site.roadDef.defName == "DirtPathBuilt"); // Always consider resources have been consumed when the road is a dirt path foreach (Thing aThing in CaravanInventoryUtility.AllInventoryItems(caravan)) { foreach (string resourceName in DefModExtension_RotR_RoadDef.allResources) { if (!DefModExtension_RotR_RoadDef.GetInSituModifier(resourceName, useISR2G)) { if (needed[resourceName] > 0 && isThis(aThing.def, resourceName)) { int amountUsed = (aThing.stackCount > needed[resourceName]) ? needed[resourceName] : aThing.stackCount; aThing.stackCount -= amountUsed; // Reduce how much of this resource is needed needed[resourceName] -= amountUsed; siteComp.ReduceLeft(resourceName, amountUsed); //RoadsOfTheRim.DebugLog("[RotR] ISR2G consumption DEBUG =" + resourceName + " Qty consumed = " + amountUsed); } } else { if (needed[resourceName] > 0) { //RoadsOfTheRim.DebugLog("[RotR] ISR2G consumption DEBUG =" + resourceName + " Qty freely awarded = " + needed[resourceName]); siteComp.ReduceLeft(resourceName, needed[resourceName]); needed[resourceName] = 0; } } } if (aThing.stackCount == 0) { aThing.Destroy(); } } caravanComp.teachPawns(ratio_final); // Pawns learn some construction // HARDCODED : ISR2G divides work done by 4 , AISR2G by 2 for all roads except dirt path if (useISR2G > 0 && site.roadDef.defName != "DirtPathBuilt") { amountOfWork = amountOfWork * 0.25f * useISR2G; } // Update amountOfWork based on the actual ratio worked & finally reducing the work & resources left amountOfWork = ratio_final * amountOfWork; return(siteComp.UpdateProgress(amountOfWork, caravan)); }