Files
WulaFallenEmpireRW/MCP/vector_cache/Source-StartCarryThing-Toil-Toils_Haul.txt
2025-08-11 21:22:41 +08:00

1333 lines
44 KiB
Plaintext

根据向量相似度分析,与 'Source, Toils_Haul, StartCarryThing, Toil' 最相关的代码定义如下:
---
**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\Toils_Haul.txt`
```csharp
public class Toils_Haul
{
public static bool ErrorCheckForCarry(Pawn pawn, Thing haulThing, bool canTakeFromInventory = false)
{
if (!haulThing.SpawnedOrAnyParentSpawned || (!canTakeFromInventory && !haulThing.Spawned))
{
Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which isn't spawned.");
pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
return true;
}
if (haulThing.stackCount == 0)
{
Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which had stackcount 0.");
pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
return true;
}
if (pawn.jobs.curJob.count <= 0)
{
Log.Error("Invalid count: " + pawn.jobs.curJob.count + ", setting to 1. Job was " + pawn.jobs.curJob);
pawn.jobs.curJob.count = 1;
}
return false;
}
public static Toil StartCarryThing(TargetIndex haulableInd, bool putRemainderInQueue = false, bool subtractNumTakenFromJobCount = false, bool failIfStackCountLessThanJobCount = false, bool reserve = true, bool canTakeFromInventory = false)
{
Toil toil = ToilMaker.MakeToil("StartCarryThing");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
Thing thing = curJob.GetTarget(haulableInd).Thing;
if (!ErrorCheckForCarry(actor, thing, canTakeFromInventory))
{
if (curJob.count == 0)
{
throw new Exception($"StartCarryThing job had count = {curJob.count}. Job: {curJob}");
}
int num = actor.carryTracker.AvailableStackSpace(thing.def);
if (num <= 0)
{
int num2 = actor.carryTracker.MaxStackSpaceEver(thing.def);
int num3 = 0;
if (actor.carryTracker.CarriedThing != null)
{
num3 = actor.carryTracker.CarriedThing.stackCount;
}
throw new Exception($"StartCarryThing got availableStackSpace {num} (haulTarg {thing}, Job: {curJob}, maximum: {num2}, carrying: {num3})");
}
if (failIfStackCountLessThanJobCount && thing.stackCount < curJob.count)
{
actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
}
else
{
int num4 = Mathf.Min(curJob.count, num, thing.stackCount);
if (num4 <= 0)
{
int num5 = actor.carryTracker.MaxStackSpaceEver(thing.def);
int num6 = 0;
if (actor.carryTracker.CarriedThing != null)
{
num6 = actor.carryTracker.CarriedThing.stackCount;
}
throw new Exception($"StartCarryThing zero or negative desiredNumToTake ({num4}), curJob.count: {curJob.count}, availableStackSpace: {num} (maximum: {num5}, carrying: {num6}), haulTarg.stackCount: {thing.stackCount}");
}
int stackCount = thing.stackCount;
int num7 = actor.carryTracker.TryStartCarry(thing, num4, reserve);
if (num7 == 0)
{
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
}
if (num7 < stackCount)
{
int num8 = curJob.count - num7;
if (putRemainderInQueue && num8 > 0)
{
curJob.GetTargetQueue(haulableInd).Insert(0, thing);
Job job = curJob;
if (job.countQueue == null)
{
job.countQueue = new List<int>();
}
curJob.countQueue.Insert(0, num8);
}
else if (actor.Map.reservationManager.ReservedBy(thing, actor, curJob))
{
actor.Map.reservationManager.Release(thing, actor, curJob);
}
}
if (subtractNumTakenFromJobCount)
{
curJob.count -= num7;
}
curJob.SetTarget(haulableInd, actor.carryTracker.CarriedThing);
actor.records.Increment(RecordDefOf.ThingsHauled);
}
}
};
return toil;
}
public static Toil StoreThingJob(TargetIndex thingIndex)
{
Toil toil = ToilMaker.MakeToil("StoreThingJob");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.CurJob;
Thing thing = curJob.GetTarget(thingIndex).Thing;
Job job = HaulAIUtility.HaulToStorageJob(actor, thing, curJob.playerForced);
if (job != null)
{
actor.jobs.TryTakeOrderedJob(job, JobTag.Misc);
}
};
return toil;
}
public static Toil DropCarriedThing()
{
Toil toil = ToilMaker.MakeToil("DropCarriedThing");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Thing resultingThing;
if (actor.carryTracker.CarriedThing == null)
{
Log.Error(actor?.ToString() + " tried to drop carried thing but is not carrying anything.");
}
else if (!actor.carryTracker.TryDropCarriedThing(actor.Position, ThingPlaceMode.Direct, out resultingThing))
{
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
}
};
return toil;
}
public static Toil JumpIfAlsoCollectingNextTargetInQueue(Toil gotoGetTargetToil, TargetIndex ind)
{
Toil toil = ToilMaker.MakeToil("JumpIfAlsoCollectingNextTargetInQueue");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
List<LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind);
if (!targetQueue.NullOrEmpty() && curJob.count > 0)
{
if (actor.carryTracker.CarriedThing == null)
{
Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor?.ToString() + " who is not carrying something.");
}
else if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) > 0)
{
for (int i = 0; i < targetQueue.Count; i++)
{
if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing))
{
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
break;
}
if (targetQueue[i].Thing.def == actor.carryTracker.CarriedThing.def)
{
curJob.SetTarget(ind, targetQueue[i].Thing);
targetQueue.RemoveAt(i);
actor.jobs.curDriver.JumpToToil(gotoGetTargetToil);
break;
}
}
}
}
};
return toil;
}
public static Toil CheckForGetOpportunityDuplicate(Toil getHaulTargetToil, TargetIndex haulableInd, TargetIndex storeCellInd, bool takeFromValidStorage = false, Predicate<Thing> extraValidator = null)
{
Toil toil = ToilMaker.MakeToil("CheckForGetOpportunityDuplicate");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
if (actor.carryTracker.CarriedThing.def.stackLimit != 1 && !actor.carryTracker.Full && curJob.count > 0)
{
Thing thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch, TraverseParms.For(actor), 8f, DupeValidator);
if (thing != null)
{
curJob.SetTarget(haulableInd, thing);
actor.jobs.curDriver.JumpToToil(getHaulTargetToil);
}
}
bool DupeValidator(Thing t)
{
if (!t.Spawned)
{
return false;
}
if (t.def != actor.carryTracker.CarriedThing.def)
{
return false;
}
if (!t.CanStackWith(actor.carryTracker.CarriedThing))
{
return false;
}
if (t.IsForbidden(actor))
{
return false;
}
if (!t.IsSociallyProper(actor, forPrisoner: false, animalsCare: true))
{
return false;
}
if (takeFromValidStorage && storeCellInd != 0 && curJob.GetTarget(storeCellInd).Cell.TryGetSlotGroup(actor.Map, out var group) && t.TryGetValidStoragePriority(out var priority) && (int)priority >= (int)group.Settings.Priority)
{
return false;
}
if (storeCellInd != 0 && !curJob.GetTarget(storeCellInd).Cell.IsValidStorageFor(actor.Map, t))
{
return false;
}
if (!actor.CanReserve(t))
{
return false;
}
if (extraValidator != null && !extraValidator(t))
{
return false;
}
return true;
}
};
return toil;
}
public static Toil CarryHauledThingToCell(TargetIndex squareIndex, PathEndMode pathEndMode = PathEndMode.ClosestTouch)
{
Toil toil = ToilMaker.MakeToil("CarryHauledThingToCell");
toil.initAction = delegate
{
IntVec3 cell3 = toil.actor.jobs.curJob.GetTarget(squareIndex).Cell;
toil.actor.pather.StartPath(cell3, pathEndMode);
};
toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
toil.AddEndCondition(delegate
{
Pawn actor2 = toil.actor;
IntVec3 cell2 = actor2.jobs.curJob.GetTarget(squareIndex).Cell;
CompPushable compPushable2 = actor2.carryTracker.CarriedThing.TryGetComp<CompPushable>();
if (compPushable2 != null)
{
Vector3 v = actor2.Position.ToVector3() + compPushable2.drawPos;
if (new IntVec3(v) == cell2)
{
return JobCondition.Succeeded;
}
}
return JobCondition.Ongoing;
});
toil.AddFailCondition(delegate
{
Pawn actor = toil.actor;
IntVec3 cell = actor.jobs.curJob.GetTarget(squareIndex).Cell;
if (actor.carryTracker.CarriedThing == null)
{
return true;
}
if (actor.jobs.curJob.haulMode == HaulMode.ToCellStorage && !cell.IsValidStorageFor(actor.Map, actor.carryTracker.CarriedThing))
{
return true;
}
CompPushable compPushable = actor.carryTracker.CarriedThing.TryGetComp<CompPushable>();
return (compPushable != null && !compPushable.canBePushed) ? true : false;
});
return toil;
}
public static Toil PlaceCarriedThingInCellFacing(TargetIndex facingTargetInd)
{
Toil toil = ToilMaker.MakeToil("PlaceCarriedThingInCellFacing");
toil.initAction = delegate
{
Pawn actor = toil.actor;
if (actor.carryTracker.CarriedThing == null)
{
Log.Error(actor?.ToString() + " tried to place hauled thing in facing cell but is not hauling anything.");
}
else
{
LocalTargetInfo target = actor.CurJob.GetTarget(facingTargetInd);
IntVec3 intVec = ((!target.HasThing) ? target.Cell : target.Thing.OccupiedRect().ClosestCellTo(actor.Position));
IntVec3 dropLoc = actor.Position + Pawn_RotationTracker.RotFromAngleBiased((actor.Position - intVec).AngleFlat).FacingCell;
if (!actor.carryTracker.TryDropCarriedThing(dropLoc, ThingPlaceMode.Direct, out var _))
{
actor.jobs.EndCurrentJob(JobCondition.Incompletable);
}
}
};
return toil;
}
public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false)
{
Toil toil = ToilMaker.MakeToil("PlaceHauledThingInCell");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
IntVec3 cell = curJob.GetTarget(cellInd).Cell;
if (actor.carryTracker.CarriedThing == null)
{
Log.Error(actor?.ToString() + " tried to place hauled thing in cell but is not hauling anything.");
}
else
{
SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing))
{
actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul);
}
Action<Thing, int> placedAction = null;
if (curJob.def == JobDefOf.DoBill || curJob.def == JobDefOf.RecolorApparel || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic)
{
placedAction = delegate(Thing th, int added)
{
HaulAIUtility.UpdateJobWithPlacedThings(curJob, th, added);
};
}
if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out var _, placedAction))
{
if (storageMode)
{
IntVec3 storeCell;
if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetSlotGroup(), out var foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell)))
{
if (actor.CanReserve(foundCell))
{
actor.Reserve(foundCell, actor.CurJob);
}
actor.CurJob.SetTarget(cellInd, foundCell);
actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
}
else if (HaulAIUtility.CanHaulAside(actor, actor.carryTracker.CarriedThing, out storeCell))
{
curJob.SetTarget(cellInd, storeCell);
curJob.count = int.MaxValue;
curJob.haulOpportunisticDuplicates = false;
curJob.haulMode = HaulMode.ToCellNonStorage;
if (nextToilOnPlaceFailOrIncomplete != null)
{
actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
}
}
else
{
Log.Warning($"Incomplete haul for {actor}: Could not find anywhere to put {actor.carryTracker.CarriedThing} near {actor.Position}. Destroying. This should be very uncommon!");
actor.carryTracker.CarriedThing.Destroy();
}
}
else if (nextToilOnPlaceFailOrIncomplete != null)
{
actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
}
}
}
};
return toil;
}
public static Toil CarryHauledThingToContainer()
{
Toil gotoDest = ToilMaker.MakeToil("CarryHauledThingToContainer");
gotoDest.initAction = delegate
{
gotoDest.actor.pather.StartPath(gotoDest.actor.jobs.curJob.targetB.Thing, PathEndMode.Touch);
};
gotoDest.AddFailCondition(delegate
{
Thing thing = gotoDest.actor.jobs.curJob.targetB.Thing;
if (thing.Destroyed || (!gotoDest.actor.jobs.curJob.ignoreForbidden && thing.IsForbidden(gotoDest.actor)))
{
return true;
}
ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner();
return (thingOwner != null && !thingOwner.CanAcceptAnyOf(gotoDest.actor.carryTracker.CarriedThing)) ? true : false;
});
gotoDest.defaultCompleteMode = ToilCompleteMode.PatherArrival;
return gotoDest;
}
public static Toil DepositHauledThingInContainer(TargetIndex containerInd, TargetIndex reserveForContainerInd, Action onDeposited = null)
{
Toil toil = ToilMaker.MakeToil("DepositHauledThingInContainer");
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
if (actor.carryTracker.CarriedThing == null)
{
Log.Error(actor?.ToString() + " tried to place hauled thing in container but is not hauling anything.");
}
else
{
Thing thing = curJob.GetTarget(containerInd).Thing;
ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner();
if (thingOwner != null)
{
int num = actor.carryTracker.CarriedThing.stackCount;
if (thing is IHaulEnroute haulEnroute)
{
ThingDef def = actor.carryTracker.CarriedThing.def;
num = Mathf.Min(haulEnroute.GetSpaceRemainingWithEnroute(def, actor), num);
if (reserveForContainerInd != 0)
{
Thing thing2 = curJob.GetTarget(reserveForContainerInd).Thing;
if (!thing2.DestroyedOrNull() && thing2 != haulEnroute && thing2 is IHaulEnroute enroute)
{
int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(def, actor);
num = Mathf.Min(num, actor.carryTracker.CarriedThing.stackCount - spaceRemainingWithEnroute);
}
}
}
Thing carriedThing = actor.carryTracker.CarriedThing;
int num2 = actor.carryTracker.innerContainer.TryTransferToContainer(carriedThing, thingOwner, num);
if (num2 != 0)
{
if (thing is IHaulEnroute container)
{
thing.Map.enrouteManager.ReleaseFor(container, actor);
}
if (thing is INotifyHauledTo notifyHauledTo)
{
notifyHauledTo.Notify_HauledTo(actor, carriedThing, num2);
}
if (thing is ThingWithComps thingWithComps)
{
foreach (ThingComp allComp in thingWithComps.AllComps)
{
if (allComp is INotifyHauledTo notifyHauledTo2)
{
notifyHauledTo2.Notify_HauledTo(actor, carriedThing, num2);
}
}
}
if (curJob.def == JobDefOf.DoBill)
{
HaulAIUtility.UpdateJobWithPlacedThings(curJob, carriedThing, num2);
}
onDeposited?.Invoke();
}
}
else if (curJob.GetTarget(containerInd).Thing.def.Minifiable)
{
actor.carryTracker.innerContainer.ClearAndDestroyContents();
}
else
{
Log.Error("Could not deposit hauled thing in container: " + curJob.GetTarget(containerInd).Thing);
}
}
};
return toil;
}
public static Toil JumpToCarryToNextContainerIfPossible(Toil carryToContainerToil, TargetIndex primaryTargetInd)
{
Toil toil = ToilMaker.MakeToil("JumpToCarryToNextContainerIfPossible");
toil.debugName = "Jump carry if possible";
toil.initAction = delegate
{
Pawn actor = toil.actor;
Job curJob = actor.jobs.curJob;
if (actor.carryTracker.CarriedThing != null && curJob.targetQueueB != null && curJob.targetQueueB.Count > 0)
{
if (TryGetNextDestinationFromQueue(primaryTargetInd, TargetIndex.B, actor.carryTracker.CarriedThing.def, curJob, actor, out var nextTarget))
{
curJob.targetQueueB.RemoveAll((LocalTargetInfo target) => target.Thing == nextTarget);
curJob.targetB = nextTarget;
curJob.targetC = nextTarget;
actor.jobs.curDriver.JumpToToil(carryToContainerToil);
}
}
};
return toil;
}
public static bool TryGetNextDestinationFromQueue(TargetIndex primaryIndex, TargetIndex destIndex, ThingDef stuff, Job job, Pawn actor, out Thing target)
{
Thing primaryTarget = job.GetTarget(primaryIndex).Thing;
target = null;
if (actor.carryTracker?.CarriedThing == null)
{
return false;
}
bool hasSpareItems = actor.carryTracker.CarriedThing.stackCount > 0;
if (primaryTarget != null && primaryTarget.Spawned && primaryTarget is IHaulEnroute enroute)
{
int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(stuff, actor);
hasSpareItems = actor.carryTracker.CarriedThing.stackCount > spaceRemainingWithEnroute;
}
target = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, from x in job.GetTargetQueue(destIndex)
select x.Thing, PathEndMode.Touch, TraverseParms.For(actor), 99999f, Validator);
return target != null;
bool Validator(Thing th)
{
if (!(th is IHaulEnroute enroute2))
{
return false;
}
if (enroute2.GetSpaceRemainingWithEnroute(stuff, actor) <= 0)
{
return false;
}
if (th != primaryTarget && !hasSpareItems)
{
return false;
}
return true;
}
}
public static Toil TakeToInventory(TargetIndex ind, int count)
{
return TakeToInventory(ind, count, null, null);
}
private static Toil TakeToInventory(TargetIndex ind, int? count, Func<int> countGetter, Func<Thing, int> countGetterPassingThing)
{
Toil takeThing = ToilMaker.MakeToil("TakeToInventory");
takeThing.initAction = delegate
{
Pawn actor = takeThing.actor;
Thing thing = actor.CurJob.GetTarget(ind).Thing;
if (!ErrorCheckForCarry(actor, thing))
{
int num = Mathf.Min(count ?? countGetterPassingThing?.Invoke(thing) ?? countGetter(), thing.stackCount);
if (actor.CurJob.checkEncumbrance)
{
num = Math.Min(num, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing));
}
if (num <= 0)
{
actor.jobs.curDriver.ReadyForNextToil();
}
else
{
actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num));
if (thing.def.ingestible != null && (int)thing.def.ingestible.preferability <= 5)
{
actor.mindState.lastInventoryRawFoodUseTick = Find.TickManager.TicksGame;
}
thing.def.soundPickup.PlayOneShot(new TargetInfo(actor.Position, actor.Map));
}
}
};
return takeThing;
}
public static Toil TakeToInventory(TargetIndex ind, Func<int> countGetter)
{
return TakeToInventory(ind, null, countGetter, null);
}
public static Toil TakeToInventory(TargetIndex ind, Func<Thing, int> countGetter)
{
return TakeToInventory(ind, null, null, countGetter);
}
public static Toil TakeFromOtherInventory(Thing item, ThingOwner taker, ThingOwner holder, int count = -1, TargetIndex indexToSet = TargetIndex.None)
{
Toil toil = ToilMaker.MakeToil("TakeFromOtherInventory");
toil.initAction = delegate
{
if (!holder.Contains(item))
{
toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
}
else
{
count = ((count < 0) ? toil.actor.jobs.curJob.count : count);
holder.TryTransferToContainer(item, taker, Mathf.Min(item.stackCount, count), out var resultingTransferredItem);
if (resultingTransferredItem == null)
{
Log.Warning($"Taker {toil.actor.Label} unable to take count {count} of thing {item.Label} from holder's inventory");
toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
}
else if (indexToSet != 0)
{
toil.actor.jobs.curJob.SetTarget(indexToSet, resultingTransferredItem);
}
}
};
return toil;
}
public static Toil CheckItemCarriedByOtherPawn(Thing item, TargetIndex targetPawnIfCarried = TargetIndex.None, Toil jumpIfCarriedByOther = null)
{
Toil toil = ToilMaker.MakeToil("CheckItemCarriedByOtherPawn");
toil.initAction = delegate
{
Pawn pawn = (item?.ParentHolder as Pawn_InventoryTracker)?.pawn;
if (pawn != null && pawn != toil.actor)
{
if (targetPawnIfCarried != 0)
{
toil.actor.jobs.curJob.SetTarget(targetPawnIfCarried, pawn);
}
if (jumpIfCarriedByOther != null)
{
toil.actor.jobs.curDriver.JumpToToil(jumpIfCarriedByOther);
}
}
};
toil.defaultCompleteMode = ToilCompleteMode.Instant;
toil.atomicWithPrevious = true;
return toil;
}
}
```
---
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_HaulToContainer.txt`
**相似度:** 0.6036
```csharp
public class JobDriver_HaulToContainer : JobDriver, IBuildableDriver
{
private Effecter graveDigEffect;
protected const TargetIndex CarryThingIndex = TargetIndex.A;
public const TargetIndex DestIndex = TargetIndex.B;
protected const TargetIndex PrimaryDestIndex = TargetIndex.C;
protected const int DiggingEffectInterval = 80;
public Thing ThingToCarry => (Thing)job.GetTarget(TargetIndex.A);
public Thing Container => (Thing)job.GetTarget(TargetIndex.B);
public ThingDef ThingDef => ThingToCarry.def;
protected virtual int Duration
{
get
{
if (Container == null || !(Container is Building building))
{
return 0;
}
return building.HaulToContainerDuration(ThingToCarry);
}
}
protected virtual EffecterDef WorkEffecter => null;
protected virtual SoundDef WorkSustainer => null;
public bool TryGetBuildableRect(out CellRect rect)
{
if (Container is Blueprint)
{
rect = Container.OccupiedRect();
return true;
}
rect = default(CellRect);
return false;
}
public override string GetReport()
{
Thing thing = ((pawn.CurJob != job || pawn.carryTracker.CarriedThing == null) ? base.TargetThingA : pawn.carryTracker.CarriedThing);
if (thing == null || !job.targetB.HasThing)
{
return "ReportHaulingUnknown".Translate();
}
return ((job.GetTarget(TargetIndex.B).Thing is Building_Grave) ? "ReportHaulingToGrave" : "ReportHaulingTo").Translate(thing.Label, job.targetB.Thing.LabelShort.Named("DESTINATION"), thing.Named("THING"));
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
if (!pawn.Reserve(job.GetTarget(TargetIndex.A), job, 1, -1, null, errorOnFailed))
{
return false;
}
if (Container.Isnt<IHaulEnroute>())
{
if (!pawn.Reserve(job.GetTarget(TargetIndex.B), job, 1, 1, null, errorOnFailed))
{
return false;
}
pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.B), job);
}
UpdateEnrouteTrackers();
pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.A), job);
return true;
}
protected virtual void ModifyPrepareToil(Toil toil)
{
}
private bool TryReplaceWithFrame(TargetIndex index)
{
Thing thing = GetActor().jobs.curJob.GetTarget(index).Thing;
Building edifice = thing.Position.GetEdifice(pawn.Map);
if (edifice != null && thing is Blueprint_Build blueprint_Build && edifice is Frame frame && frame.BuildDef == blueprint_Build.BuildDef)
{
job.SetTarget(TargetIndex.B, frame);
return true;
}
return false;
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDestroyedOrNull(TargetIndex.A);
this.FailOn(delegate
{
Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.B).Thing;
Thing thing2 = GetActor().jobs.curJob.GetTarget(TargetIndex.C).Thing;
if (thing == null)
{
return true;
}
if (thing2 != null && thing2.Destroyed && !TryReplaceWithFrame(TargetIndex.C))
{
job.SetTarget(TargetIndex.C, null);
}
if (!thing.Spawned || (thing.Destroyed && !TryReplaceWithFrame(TargetIndex.B)))
{
if (job.targetQueueB.NullOrEmpty())
{
return true;
}
if (!Toils_Haul.TryGetNextDestinationFromQueue(TargetIndex.C, TargetIndex.B, ThingDef, job, pawn, out var nextTarget))
{
return true;
}
job.targetQueueB.RemoveAll((LocalTargetInfo target) => target.Thing == nextTarget);
job.targetB = nextTarget;
}
ThingOwner thingOwner = Container.TryGetInnerInteractableThingOwner();
if (thingOwner != null && !thingOwner.CanAcceptAnyOf(ThingToCarry))
{
return true;
}
return (Container is IHaulDestination haulDestination && !haulDestination.Accepts(ThingToCarry)) ? true : false;
});
this.FailOnForbidden(TargetIndex.B);
this.FailOn(() => EnterPortalUtility.WasLoadingCanceled(Container));
this.FailOn(() => TransporterUtility.WasLoadingCanceled(Container));
this.FailOn(() => CompBiosculpterPod.WasLoadingCanceled(Container));
this.FailOn(() => Building_SubcoreScanner.WasLoadingCancelled(Container));
Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch, canGotoSpawnedParent: true).FailOn(() => ThingToCarry.ParentHolder is MinifiedThing).FailOnSelfAndParentsDespawnedOrNull(TargetIndex.A);
Toil uninstallIfMinifiable = Toils_Construct.UninstallIfMinifiable(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn(() => ThingToCarry.ParentHolder is MinifiedThing)
.FailOnSelfAndParentsDespawnedOrNull(TargetIndex.A)
.FailOnDestroyedOrNull(TargetIndex.A);
Toil startCarryingThing = Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, canTakeFromInventory: true);
Toil jumpIfAlsoCollectingNextTarget = Toils_Haul.JumpIfAlsoCollectingNextTargetInQueue(getToHaulTarget, TargetIndex.A);
Toil carryToContainer = Toils_Haul.CarryHauledThingToContainer();
yield return Toils_Jump.JumpIf(jumpIfAlsoCollectingNextTarget, () => pawn.IsCarryingThing(ThingToCarry));
yield return getToHaulTarget;
yield return uninstallIfMinifiable;
yield return startCarryingThing;
yield return jumpIfAlsoCollectingNextTarget;
yield return carryToContainer;
yield return Toils_Goto.MoveOffTargetBlueprint(TargetIndex.B);
Toil toil = Toils_General.Wait(Duration, TargetIndex.B);
toil.WithProgressBarToilDelay(TargetIndex.B);
EffecterDef workEffecter = WorkEffecter;
if (workEffecter != null)
{
toil.WithEffect(workEffecter, TargetIndex.B);
}
SoundDef workSustainer = WorkSustainer;
if (workSustainer != null)
{
toil.PlaySustainerOrSound(workSustainer);
}
Thing destThing = job.GetTarget(TargetIndex.B).Thing;
toil.tickIntervalAction = delegate(int delta)
{
if (pawn.IsHashIntervalTick(80, delta) && destThing is Building_Grave && graveDigEffect == null)
{
graveDigEffect = EffecterDefOf.BuryPawn.Spawn();
graveDigEffect.Trigger(destThing, destThing);
}
};
toil.tickAction = delegate
{
graveDigEffect?.EffectTick(destThing, destThing);
};
ModifyPrepareToil(toil);
yield return toil;
yield return Toils_Construct.MakeSolidThingFromBlueprintIfNecessary(TargetIndex.B, TargetIndex.C);
yield return Toils_Haul.DepositHauledThingInContainer(TargetIndex.B, TargetIndex.C);
yield return Toils_Haul.JumpToCarryToNextContainerIfPossible(carryToContainer, TargetIndex.C);
}
private void UpdateEnrouteTrackers()
{
int count = job.count;
TryReserveEnroute(base.TargetThingC, ref count);
if (base.TargetB != base.TargetC)
{
TryReserveEnroute(base.TargetThingB, ref count);
}
if (job.targetQueueB == null)
{
return;
}
foreach (LocalTargetInfo item in job.targetQueueB)
{
if (!base.TargetC.HasThing || !(item == base.TargetThingC))
{
TryReserveEnroute(item.Thing, ref count);
}
}
}
private void TryReserveEnroute(Thing thing, ref int count)
{
if (thing is IHaulEnroute container && !thing.DestroyedOrNull())
{
UpdateTracker(container, ref count);
}
}
private void UpdateTracker(IHaulEnroute container, ref int count)
{
if (!ThingToCarry.DestroyedOrNull())
{
if (job.playerForced && container.GetSpaceRemainingWithEnroute(ThingDef) == 0)
{
container.Map.enrouteManager.InterruptEnroutePawns(container, pawn);
}
int num = Mathf.Min(count, container.GetSpaceRemainingWithEnroute(ThingDef));
if (num > 0)
{
container.Map.enrouteManager.AddEnroute(container, pawn, base.TargetThingA.def, num);
}
count -= num;
}
}
}
```
---
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_PrepareCaravan_GatherItems.txt`
**相似度:** 0.5905
```csharp
public class JobDriver_PrepareCaravan_GatherItems : JobDriver
{
private int pickedUpFirstItemTicks = -1;
private int toilLoops;
private PrepareCaravanGatherState gatherState;
private const TargetIndex ToHaulInd = TargetIndex.A;
private const TargetIndex CarrierInd = TargetIndex.B;
private const int MaxTicksGatherItems = 7500;
private const int LoopBackstop = 500;
public Thing ToHaul => job.GetTarget(TargetIndex.A).Thing;
public Pawn Carrier => (Pawn)job.GetTarget(TargetIndex.B).Thing;
private List<TransferableOneWay> Transferables => ((LordJob_FormAndSendCaravan)job.lord.LordJob).transferables;
private TransferableOneWay Transferable
{
get
{
TransferableOneWay transferableOneWay = TransferableUtility.TransferableMatchingDesperate(ToHaul, Transferables, TransferAsOneMode.PodsOrCaravanPacking);
if (transferableOneWay != null)
{
return transferableOneWay;
}
throw new InvalidOperationException("Could not find any matching transferable.");
}
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return pawn.Reserve(ToHaul, job, 1, -1, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
if (gatherState == PrepareCaravanGatherState.Unset)
{
gatherState = ((pawn.IsFormingCaravan() && (!MassUtility.IsOverEncumbered(pawn) || pawn.inventory.HasAnyUnpackedCaravanItems)) ? PrepareCaravanGatherState.Haul : PrepareCaravanGatherState.Carry);
}
if (gatherState == PrepareCaravanGatherState.Carry)
{
return MakeNewToilsCarry();
}
return MakeNewToilsHaulInInventory();
}
private IEnumerable<Toil> MakeNewToilsCarry()
{
this.FailOn(() => !base.Map.lordManager.lords.Contains(job.lord));
Toil reserve = Toils_Reserve.Reserve(TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A);
yield return reserve;
bool inInventory = HaulAIUtility.IsInHaulableInventory(ToHaul);
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch, inInventory);
yield return DetermineNumToHaul();
yield return Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, inInventory);
yield return AddCarriedThingToTransferables();
yield return Toils_Haul.CheckForGetOpportunityDuplicate(reserve, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true, (Thing x) => Transferable.things.Contains(x));
Toil findCarrier = FindCarrier();
yield return findCarrier;
yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier);
yield return Toils_General.Wait(25).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier).WithProgressBarToilDelay(TargetIndex.B);
yield return PlaceTargetInCarrierInventory();
}
private IEnumerable<Toil> MakeNewToilsHaulInInventory()
{
this.FailOn(() => !base.Map.lordManager.lords.Contains(job.lord));
bool inInventory = HaulAIUtility.IsInHaulableInventory(ToHaul);
Toil reserve = Toils_Reserve.Reserve(TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A);
Toil findCarrier = FindCarrier();
yield return reserve;
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch, inInventory).JumpIf(IsFinishedCollectingItems, findCarrier);
yield return DetermineNumToHaul(findCarrier);
yield return Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, inInventory);
yield return AddCarriedThingToTransferables();
yield return Toils_General.Wait(25).WithProgressBarToilDelay(TargetIndex.B);
yield return HaulCaravanItemInInventory(reserve);
yield return findCarrier;
yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier);
yield return Toils_General.Wait(25).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier).WithProgressBarToilDelay(TargetIndex.B);
yield return AddHauledItemsToCarrier(findCarrier);
}
private Toil DetermineNumToHaul(Toil findCarrier = null)
{
Toil toil = ToilMaker.MakeToil("DetermineNumToHaul");
toil.initAction = delegate
{
int num = GatherItemsForCaravanUtility.CountLeftToTransfer(pawn, Transferable, job.lord);
if (pawn.carryTracker.CarriedThing != null)
{
num -= pawn.carryTracker.CarriedThing.stackCount;
}
if (num <= 0)
{
if (findCarrier == null || !pawn.inventory.HasAnyUnpackedCaravanItems)
{
pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
}
else
{
pawn.jobs.curDriver.JumpToToil(findCarrier);
}
}
else
{
job.count = num;
}
};
toil.defaultCompleteMode = ToilCompleteMode.Instant;
toil.atomicWithPrevious = true;
return toil;
}
private Toil AddCarriedThingToTransferables()
{
Toil toil = ToilMaker.MakeToil("AddCarriedThingToTransferables");
toil.initAction = delegate
{
TransferableOneWay transferable = Transferable;
if (!transferable.things.Contains(pawn.carryTracker.CarriedThing))
{
transferable.things.Add(pawn.carryTracker.CarriedThing);
}
};
toil.defaultCompleteMode = ToilCompleteMode.Instant;
toil.atomicWithPrevious = true;
return toil;
}
private Toil FindCarrier()
{
Toil toil = ToilMaker.MakeToil("FindCarrier");
toil.initAction = delegate
{
Pawn pawn = FindBestCarrier(onlyAnimals: true);
if (pawn == null)
{
bool flag = base.pawn.GetLord() == job.lord;
if (flag && !MassUtility.IsOverEncumbered(base.pawn))
{
pawn = base.pawn;
}
else
{
pawn = FindBestCarrier(onlyAnimals: false);
if (pawn == null)
{
if (flag)
{
pawn = base.pawn;
}
else
{
IEnumerable<Pawn> source = job.lord.ownedPawns.Where((Pawn x) => IsUsableCarrier(x, base.pawn, allowColonists: true));
if (!source.Any())
{
EndJobWith(JobCondition.Incompletable);
return;
}
pawn = source.RandomElement();
}
}
}
}
job.SetTarget(TargetIndex.B, pawn);
};
return toil;
}
private bool IsFinishedCollectingItems()
{
if (!MassUtility.IsOverEncumbered(pawn))
{
if (pickedUpFirstItemTicks > -1)
{
return Find.TickManager.TicksGame > pickedUpFirstItemTicks + 7500;
}
return false;
}
return true;
}
private Toil HaulCaravanItemInInventory(Toil reserve)
{
Toil toil = ToilMaker.MakeToil("HaulCaravanItemInInventory");
toil.initAction = delegate
{
if (pickedUpFirstItemTicks == -1)
{
pickedUpFirstItemTicks = Find.TickManager.TicksGame;
}
Transferable.AdjustTo(Mathf.Max(Transferable.CountToTransfer - pawn.carryTracker.CarriedThing.stackCount, 0));
pawn.inventory.AddHauledCaravanItem(pawn.carryTracker.CarriedThing);
if (!IsFinishedCollectingItems())
{
SetNewHaulTargetAndJumpToReserve(reserve);
}
};
return toil;
}
private void SetNewHaulTargetAndJumpToReserve(Toil reserve)
{
if (CheckToilLoopBackstop())
{
Thing thing = GatherItemsForCaravanUtility.FindThingToHaul(pawn, pawn.GetLord());
if (thing != null)
{
job.SetTarget(TargetIndex.A, thing);
pawn.jobs.curDriver.JumpToToil(reserve);
}
}
}
private Toil AddHauledItemsToCarrier(Toil findCarrier)
{
Toil toil = ToilMaker.MakeToil("AddHauledItemsToCarrier");
toil.initAction = delegate
{
if (Carrier == pawn)
{
pawn.inventory.ClearHaulingCaravanCache();
}
else
{
pawn.inventory.TransferCaravanItemsToCarrier(Carrier.inventory);
if (pawn.inventory.HasAnyUnpackedCaravanItems && CheckToilLoopBackstop())
{
pawn.jobs.curDriver.JumpToToil(findCarrier);
}
}
};
return toil;
}
private bool CheckToilLoopBackstop()
{
if (++toilLoops > 500)
{
Log.Error("Prepare caravan gather items job for pawn " + pawn.Label + " looped through toils too many times");
EndJobWith(JobCondition.Errored);
return false;
}
return true;
}
private Toil PlaceTargetInCarrierInventory()
{
Toil toil = ToilMaker.MakeToil("PlaceTargetInCarrierInventory");
toil.initAction = delegate
{
Pawn_CarryTracker carryTracker = pawn.carryTracker;
Thing carriedThing = carryTracker.CarriedThing;
if (carryTracker.innerContainer.Count == 0)
{
carryTracker.pawn.Drawer.renderer.SetAllGraphicsDirty();
}
Transferable.AdjustTo(Mathf.Max(Transferable.CountToTransfer - carriedThing.stackCount, 0));
carryTracker.innerContainer.TryTransferToContainer(carriedThing, Carrier.inventory.innerContainer, carriedThing.stackCount, out var resultingTransferredItem);
CompForbiddable compForbiddable = resultingTransferredItem?.TryGetComp<CompForbiddable>();
if (compForbiddable != null)
{
compForbiddable.Forbidden = false;
}
};
return toil;
}
public static bool IsUsableCarrier(Pawn p, Pawn forPawn, bool allowColonists)
{
if (!p.IsFormingCaravan())
{
return false;
}
if (p == forPawn)
{
return true;
}
if (p.DestroyedOrNull() || !p.Spawned || p.inventory.UnloadEverything || !forPawn.CanReach(p, PathEndMode.Touch, Danger.Deadly))
{
return false;
}
if (allowColonists && p.IsColonist)
{
return true;
}
if ((p.RaceProps.packAnimal || p.HostFaction == Faction.OfPlayer) && !p.IsBurning() && !p.Downed)
{
return !MassUtility.IsOverEncumbered(p);
}
return false;
}
private float GetCarrierScore(Pawn p)
{
float lengthHorizontal = (p.Position - pawn.Position).LengthHorizontal;
float num = MassUtility.EncumbrancePercent(p);
return 1f - num - lengthHorizontal / 10f * 0.2f;
}
private Pawn FindBestCarrier(bool onlyAnimals)
{
Lord lord = job.lord;
Pawn pawn = null;
float num = 0f;
if (lord != null)
{
for (int i = 0; i < lord.ownedPawns.Count; i++)
{
Pawn pawn2 = lord.ownedPawns[i];
if (pawn2 != base.pawn && (!onlyAnimals || pawn2.RaceProps.Animal) && IsUsableCarrier(pawn2, base.pawn, allowColonists: false))
{
float carrierScore = GetCarrierScore(pawn2);
if (pawn == null || carrierScore > num)
{
pawn = pawn2;
num = carrierScore;
}
}
}
}
return pawn;
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref pickedUpFirstItemTicks, "pickedUpFirstItemTicks", 0);
Scribe_Values.Look(ref toilLoops, "toilLoops", 0);
Scribe_Values.Look(ref gatherState, "gatherState", PrepareCaravanGatherState.Unset);
}
}
```
---
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_CarryToCryptosleepCasket.txt`
**相似度:** 0.5506
```csharp
public class JobDriver_CarryToCryptosleepCasket : JobDriver
{
private const TargetIndex TakeeInd = TargetIndex.A;
private const TargetIndex DropPodInd = TargetIndex.B;
protected Pawn Takee => (Pawn)job.GetTarget(TargetIndex.A).Thing;
protected Building_CryptosleepCasket DropPod => (Building_CryptosleepCasket)job.GetTarget(TargetIndex.B).Thing;
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
if (pawn.Reserve(Takee, job, 1, -1, null, errorOnFailed))
{
return pawn.Reserve(DropPod, job, 1, -1, null, errorOnFailed);
}
return false;
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDestroyedOrNull(TargetIndex.A);
this.FailOnDestroyedOrNull(TargetIndex.B);
this.FailOnAggroMentalState(TargetIndex.A);
this.FailOn(() => !DropPod.Accepts(Takee));
Toil goToTakee = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B)
.FailOn(() => DropPod.GetDirectlyHeldThings().Count > 0)
.FailOn(() => !pawn.CanReach(Takee, PathEndMode.OnCell, Danger.Deadly))
.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
Toil startCarryingTakee = Toils_Haul.StartCarryThing(TargetIndex.A);
Toil goToThing = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.InteractionCell);
yield return Toils_Jump.JumpIf(goToThing, () => pawn.IsCarryingPawn(Takee));
yield return goToTakee;
yield return startCarryingTakee;
yield return goToThing;
Toil toil = Toils_General.Wait(500, TargetIndex.B);
toil.FailOnCannotTouch(TargetIndex.B, PathEndMode.InteractionCell);
toil.WithProgressBarToilDelay(TargetIndex.B);
yield return toil;
Toil toil2 = ToilMaker.MakeToil("MakeNewToils");
toil2.initAction = delegate
{
DropPod.TryAcceptThing(Takee);
};
toil2.defaultCompleteMode = ToilCompleteMode.Instant;
yield return toil2;
}
public override object[] TaleParameters()
{
return new object[2] { pawn, Takee };
}
}
```
---
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_HaulToAtomizer.txt`
**相似度:** 0.5312
```csharp
public class JobDriver_HaulToAtomizer : JobDriver
{
private const TargetIndex AtomizerInd = TargetIndex.A;
private const TargetIndex WastepackInd = TargetIndex.B;
private const TargetIndex ChargerCellInd = TargetIndex.C;
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.B), job);
return pawn.Reserve(job.GetTarget(TargetIndex.A), job, 1, -1, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
AddEndCondition(() => (base.TargetThingA.TryGetComp<CompAtomizer>().SpaceLeft > 0) ? JobCondition.Ongoing : JobCondition.Succeeded);
Toil clearQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.B);
yield return clearQueue;
yield return Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.B);
yield return Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B);
yield return Toils_Reserve.Reserve(TargetIndex.B);
yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
yield return Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: false, subtractNumTakenFromJobCount: true);
yield return Toils_Haul.CheckForGetOpportunityDuplicate(clearQueue, TargetIndex.B, TargetIndex.None, takeFromValidStorage: true);
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
yield return Toils_Haul.DepositHauledThingInContainer(TargetIndex.A, TargetIndex.B);
yield return Toils_Jump.Jump(clearQueue);
}
}
```
---
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_PickupToHold.txt`
**相似度:** 0.5219
```csharp
public class JobDriver_PickupToHold : JobDriver
{
private const TargetIndex HeldItemInd = TargetIndex.A;
public static bool TryMakePreToilReservations(JobDriver driver, bool errorOnFailed)
{
driver.pawn.Map.pawnDestinationReservationManager.Reserve(driver.pawn, driver.job, driver.job.GetTarget(TargetIndex.A).Cell);
return driver.pawn.Reserve(driver.job.GetTarget(TargetIndex.A), driver.job, 1, -1, null, errorOnFailed);
}
public static IEnumerable<Toil> Toils(JobDriver driver, TargetIndex HeldItem = TargetIndex.A, bool subtractNumTakenFromJobCount = true)
{
driver.FailOn(() => !driver.GetActor().health.capacities.CapableOf(PawnCapacityDefOf.Manipulation));
driver.FailOnDestroyedOrNull(HeldItem);
driver.FailOnForbidden(HeldItem);
Toil end = Toils_General.Label();
yield return Toils_Jump.JumpIf(end, () => driver.GetActor().IsCarryingThing(driver.GetActor().CurJob.GetTarget(HeldItem).Thing));
yield return Toils_Goto.GotoThing(HeldItem, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(HeldItem);
yield return Toils_Haul.StartCarryThing(HeldItem, putRemainderInQueue: false, subtractNumTakenFromJobCount);
yield return end;
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return TryMakePreToilReservations(this, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
return Toils(this);
}
}
```