protected override IEnumerable<Toil> MakeNewToils() { var fillInto = TargetThingB as Apparel; var toWC = fillInto.TryGetComp<CompWaterContainer>(); float packLitres = toWC.FreeSpaceLitres; CompWaterContainer fromWC; if (TargetA.HasThing) { // Packing from a Thing. var fillFrom = TargetThingA; fromWC = fillFrom.TryGetComp<CompWaterContainer>(); // Reserve and go to the source. yield return Toils_Water.ReserveWaterIfNeeded(fillFrom, fromWC, packLitres); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch). FailOnDespawnedOrForbidden(TargetIndex.A).FailOn(() => fromWC.IsEmpty); } else { // Packing from a bit of terrain. // This assumes that all terrain water acts as an infinite source. fromWC = new CompWaterSource(); fromWC.Initialize(new CompPropertiesWaterSource() { unlimitedSource = true }); yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch); } // Get water from the source. yield return Toils_Water.TransferWater(fromWC, toWC, packLitres); }
protected override IEnumerable<Toil> MakeNewToils() { var need = pawn.needs.TryGetNeed<Need_Water>(); CompWaterContainer wc; bool worn = false; if (TargetA.HasThing) { wc = TargetThingA.TryGetComp<CompWaterContainer>(); var wearable = TargetThingA as Apparel; worn = (wearable != null) && (pawn.apparel.WornApparel.Contains(wearable)); if (!worn) { // Actor not wearing a drinkable Thing. // Reserve it if necessary and move to the Thing. yield return Toils_Water.ReserveWaterIfNeeded(TargetThingA, wc, need.HydrationWantedLitres); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch). FailOnDespawnedOrForbidden(TargetIndex.A).FailOn(() => wc.IsEmpty); } } else { // We're targeting a piece of terrain that has some water. // This assumes that all terrain water acts as an infinite source. wc = new CompWaterSource(); wc.Initialize(new CompPropertiesWaterSource() {unlimitedSource=true}); yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch); } // Now drink in little sips :P int sips = Toils_Water.SipsToDrink(need.HydrationWantedLitres); for (int i = 0; i < sips; i++) { yield return Toils_Water.SipWater(pawn, need, wc, worn); } }
// TODO: very similar to JobDriver_HaulWater, could split out a common subset. protected override IEnumerable<Toil> MakeNewToils() { // TargetA = from // TargetB = to // TargetC = tool Pawn patient = TargetThingB as Pawn; var patientNeed = patient.needs.TryGetNeed<Need_Water>(); var tool = TargetC.Thing; var toolWc = tool.TryGetComp<CompWaterContainer>(); // Grab the water carrying tool if it's not in our inventory. if (!this.pawn.inventory.container.Contains(tool)) { yield return Toils_Reserve.Reserve(TargetIndex.C); yield return Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedOrForbidden(TargetIndex.C); yield return Toils_General.PickUpTool(TargetIndex.C); } // If the tool is in our inventory, carry it. else { yield return Toils_General.CarryThingFromInventory(tool); } // Fill it if necessary. if (TargetA.IsValid) { float collectLitres = patientNeed.HydrationWantedLitres - toolWc.StoredLitres; if (collectLitres > toolWc.FreeSpaceLitres) { collectLitres = toolWc.FreeSpaceLitres; } if (collectLitres > 0) { CompWaterContainer fromWc; // Go to Thing water source. if (TargetA.HasThing) { fromWc = TargetThingA.TryGetComp<CompWaterContainer>(); yield return Toils_Water.ReserveWaterIfNeeded(TargetThingA, fromWc, collectLitres); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch). FailOnDespawnedOrForbidden(TargetIndex.A).FailOn(() => fromWc.IsEmpty); } // Go to Terrain water source. else { // This assumes that all terrain water acts as an infinite source. fromWc = new CompWaterSource(); fromWc.Initialize(new CompPropertiesWaterSource() { unlimitedSource = true }); yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch); } // (Partially) fill water carrying tool. yield return Toils_Water.TransferWater(fromWc, toolWc, collectLitres); } } // Carry to patient and give. yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDespawnedOrForbidden(TargetIndex.B); yield return Toils_General.FaceThing(TargetIndex.B); int sips = Toils_Water.SipsToDrink(patientNeed.HydrationWantedLitres); for (int i = 0; i < sips; i++) { yield return Toils_Water.SipWater(patient, patientNeed, toolWc, false); } // Put tool back in inventory. Speeds up multiple hauling trips and stops other colonists // trying to grab the tool all the time. yield return Verse.AI.Toils_General.PutCarriedThingInInventory(); }