public static void Postfix(ref string __result, Caravan __instance) { try { WorldObjectComp_Caravan CaravanComp = __instance.GetComponent <WorldObjectComp_Caravan>(); if (CaravanComp != null && CaravanComp.currentlyWorkingOnSite) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(__result); // remove "waiting" int waitingIndex = stringBuilder.ToString().IndexOf("CaravanWaiting".Translate()); if (waitingIndex >= 0) { stringBuilder.Remove(waitingIndex, "CaravanWaiting".Translate().Length); } // remove "resting (using x bedrolls)" int usedBedCount = __instance.beds.GetUsedBedCount(); int bedrollIndex = 0; string stringToFind = ""; if (usedBedCount == 1) { // remove singular version stringToFind = " (" + (string)"UsingBedroll".Translate() + ")"; bedrollIndex = stringBuilder.ToString().IndexOf(stringToFind); } else { // remove plural version stringToFind = " (" + (string)"UsingBedrolls".Translate(usedBedCount) + ")"; bedrollIndex = stringBuilder.ToString().IndexOf(stringToFind); } if (bedrollIndex >= 0) { stringBuilder.Remove(bedrollIndex, stringToFind.Length); int restingIndex = stringBuilder.ToString().IndexOf("CaravanResting".Translate()); if (restingIndex >= 0) { stringBuilder.Remove(restingIndex, "CaravanResting".Translate().Length); } } // Appending "working on road" stringBuilder.Replace("\n", ""); stringBuilder.Replace("\r", ""); stringBuilder.AppendLine(); stringBuilder.Append("RoadsOfTheRim_CaravanInspectStringWorkingOn".Translate(CaravanComp.getSite().fullName(), string.Format("{0:0.00}", CaravanComp.amountOfWork()))); __result = stringBuilder.ToString(); } } catch { // lazy way out : the caravan can, on occasions (mainly debug teleport, though...), not have a site linked to the comp } }
public override void Arrived(Caravan caravan) { try { WorldObjectComp_Caravan CaravanComp = caravan.GetComponent <WorldObjectComp_Caravan>(); CaravanComp.startWorking(); } catch (Exception e) { Log.Error("[Roads of the Rim] : Exception upon caravan arrival = " + e); } }
public static void Postfix(ref AlertReport __result) { List <Caravan> newList = new List <Caravan>(); foreach (Caravan caravan in Find.WorldObjects.Caravans) { WorldObjectComp_Caravan caravanComp = caravan.GetComponent <WorldObjectComp_Caravan>(); if (caravan.Spawned && caravan.IsPlayerControlled && !caravan.pather.MovingNow && !caravan.CantMove && !caravanComp.currentlyWorkingOnSite) { newList.Add(caravan); } } __result = AlertReport.CulpritsAre(newList); }
public static void Postfix(ref TaggedString __result) { StringBuilder stringBuilder = new StringBuilder(); foreach (Caravan caravan in Find.WorldObjects.Caravans) { WorldObjectComp_Caravan caravanComp = caravan.GetComponent <WorldObjectComp_Caravan>(); if (caravan.Spawned && caravan.IsPlayerControlled && !caravan.pather.MovingNow && !caravan.CantMove && !caravanComp.currentlyWorkingOnSite) { stringBuilder.AppendLine(" - " + caravan.Label); } } __result = "CaravanIdleDesc".Translate(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)); }