public static void SimulateTradeableTransfer(List <Thing> all, List <Tradeable> tradeables, List <ThingStackPart> outThingsAfterTransfer) { outThingsAfterTransfer.Clear(); for (int i = 0; i < all.Count; i++) { outThingsAfterTransfer.Add(new ThingStackPart(all[i], all[i].stackCount)); } for (int j = 0; j < tradeables.Count; j++) { int countToTransfer = tradeables[j].CountToTransfer; int num = -countToTransfer; if (countToTransfer > 0) { TransferableUtility.TransferNoSplit(tradeables[j].thingsTrader, countToTransfer, delegate(Thing originalThing, int toTake) { outThingsAfterTransfer.Add(new ThingStackPart(originalThing, toTake)); }, false, false); } else if (num > 0) { TransferableUtility.TransferNoSplit(tradeables[j].thingsColony, num, delegate(Thing originalThing, int toTake) { for (int k = 0; k < outThingsAfterTransfer.Count; k++) { ThingStackPart thingStackPart = outThingsAfterTransfer[k]; if (thingStackPart.Thing == originalThing) { outThingsAfterTransfer[k] = thingStackPart.WithCount(thingStackPart.Count - toTake); break; } } }, false, false); } } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_General.Wait(10)); yield return(new Toil { initAction = delegate { Pawn otherPawn = this.$this.OtherPawn; if (!otherPawn.inventory.UnloadEverything) { this.$this.EndJobWith(JobCondition.Succeeded); } else { ThingStackPart firstUnloadableThing = otherPawn.inventory.FirstUnloadableThing; IntVec3 c; if (!firstUnloadableThing.Thing.def.EverStoreable || !this.$this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.$this.pawn, out c)) { Thing thing; otherPawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null); this.$this.EndJobWith(JobCondition.Succeeded); if (thing != null) { thing.SetForbidden(false, false); } } else { Thing thing2; otherPawn.inventory.innerContainer.TryTransferToContainer(firstUnloadableThing.Thing, this.$this.pawn.carryTracker.innerContainer, firstUnloadableThing.Count, out thing2, true); this.$this.job.count = thing2.stackCount; this.$this.job.SetTarget(TargetIndex.B, thing2); this.$this.job.SetTarget(TargetIndex.C, c); firstUnloadableThing.Thing.SetForbidden(false, false); } } } }); yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, true)); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.Wait(10)); yield return(new Toil { initAction = delegate { if (!this.$this.pawn.inventory.UnloadEverything) { this.$this.EndJobWith(JobCondition.Succeeded); } else { ThingStackPart firstUnloadableThing = this.$this.pawn.inventory.FirstUnloadableThing; IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.$this.pawn, out c)) { Thing thing; this.$this.pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null); this.$this.EndJobWith(JobCondition.Succeeded); } else { this.$this.job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); this.$this.job.SetTarget(TargetIndex.B, c); this.$this.countToDrop = firstUnloadableThing.Count; } } } }); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(new Toil { initAction = delegate { Thing thing = this.$this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.$this.pawn.inventory.innerContainer.Contains(thing)) { this.$this.EndJobWith(JobCondition.Incompletable); return; } if (!this.$this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStoreable) { this.$this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.$this.countToDrop, out thing, null); this.$this.EndJobWith(JobCondition.Succeeded); } else { this.$this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.$this.pawn.carryTracker.innerContainer, this.$this.countToDrop, out thing, true); this.$this.job.count = this.$this.countToDrop; this.$this.job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); }
/// <summary> /// Find spot, reserve spot, pull thing out of inventory, go to spot, drop stuff, repeat. /// </summary> /// <returns></returns> protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); HashSet <Thing> carriedThing = takenToInventory.GetHashSet(); if (ModCompatibilityCheck.ExtendedStorageIsActive) { //ES takes at least ~10 ticks to move from the feeder to the stockpile, so workaround ahoy UnloadDuration = 20; } Toil wait = Toils_General.Wait(UnloadDuration); Toil celebrate = Toils_General.Wait(UnloadDuration); yield return(wait); Toil findSpot = new Toil { initAction = () => { ThingStackPart unloadableThing = FirstUnloadableThing(pawn); if (unloadableThing.Count == 0 && carriedThing.Count == 0) { this.EndJobWith(JobCondition.Succeeded); } if (unloadableThing.Count != 0) { StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(pawn.Position, unloadableThing.Thing); if (!StoreUtility.TryFindStoreCellNearColonyDesperate(unloadableThing.Thing, this.pawn, out IntVec3 c)) { this.pawn.inventory.innerContainer.TryDrop(unloadableThing.Thing, ThingPlaceMode.Near, unloadableThing.Thing.stackCount, out Thing thing, null); this.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, unloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = unloadableThing.Thing.stackCount; } } } }; yield return(findSpot); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(new Toil { initAction = delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { carriedThing.Remove(thing); pawn.jobs.curDriver.JumpToToil(wait); return; } if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStoreable) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing, null); this.EndJobWith(JobCondition.Succeeded); carriedThing.Remove(thing); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing, true); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); carriedThing.Remove(thing); } try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { CombatExtended.CompInventory ceCompInventory = pawn.GetComp <CombatExtended.CompInventory>(); ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); //If the original cell is full, PlaceHauledThingInCell will set a different TargetIndex resulting in errors on yield return Toils_Reserve.Release. //We still gotta release though, mostly because of Extended Storage. Toil releaseReservation = new Toil { initAction = () => { if (pawn.Map.reservationManager.ReservedBy(this.job.targetB, pawn, pawn.CurJob) && !ModCompatibilityCheck.HCSKIsActive) { pawn.Map.reservationManager.Release(this.job.targetB, pawn, pawn.CurJob); } } }; yield return(releaseReservation); yield return(Toils_Jump.Jump(wait)); yield return(celebrate); }