// Token: 0x06000077 RID: 119 RVA: 0x00004B80 File Offset: 0x00002D80 private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable) { int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def)); resTotalAvailable = 0; WorkGiver_WPConstructDeliverResources.resourcesAvailable.Clear(); WorkGiver_WPConstructDeliverResources.resourcesAvailable.Add(firstFoundResource); resTotalAvailable += firstFoundResource.stackCount; bool flag = resTotalAvailable < num; if (flag) { foreach (Thing thing in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, false)) { bool flag2 = resTotalAvailable >= num; if (flag2) { break; } bool flag3 = thing.def == firstFoundResource.def && GenAI.CanUseItemForWork(pawn, thing); if (flag3) { WorkGiver_WPConstructDeliverResources.resourcesAvailable.Add(thing); resTotalAvailable += thing.stackCount; } } } }
private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable) { int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def)); resTotalAvailable = 0; WorkGiver_ConstructDeliverResources.resourcesAvailable.Clear(); WorkGiver_ConstructDeliverResources.resourcesAvailable.Add(firstFoundResource); resTotalAvailable += firstFoundResource.stackCount; if (resTotalAvailable < num) { foreach (Thing current in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, false)) { if (resTotalAvailable >= num) { break; } if (current.def == firstFoundResource.def) { if (GenAI.CanUseItemForWork(pawn, current)) { WorkGiver_ConstructDeliverResources.resourcesAvailable.Add(current); resTotalAvailable += current.stackCount; } } } } }
private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable) { int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def)); resTotalAvailable = 0; resourcesAvailable.Clear(); resourcesAvailable.Add(firstFoundResource); resTotalAvailable += firstFoundResource.stackCount; if (resTotalAvailable >= num) { return; } foreach (Thing item in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, useCenter: false)) { if (resTotalAvailable >= num) { break; } if (item.def == firstFoundResource.def && GenAI.CanUseItemForWork(pawn, item)) { resourcesAvailable.Add(item); resTotalAvailable += item.stackCount; } } }
private static Toil JumpToCollectNextIntoHandsForBill(Toil gotoGetTargetToil, TargetIndex ind) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; if (actor.carryTracker.CarriedThing == null) { Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something."); return; } if (actor.carryTracker.Full) { return; } Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind); if (targetQueue.NullOrEmpty <LocalTargetInfo>()) { return; } for (int i = 0; i < targetQueue.Count; i++) { if (GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) { if (targetQueue[i].Thing.CanStackWith(actor.carryTracker.CarriedThing)) { if ((actor.Position - targetQueue[i].Thing.Position).LengthHorizontalSquared <= 64f) { int num = (actor.carryTracker.CarriedThing != null) ? actor.carryTracker.CarriedThing.stackCount : 0; int num2 = curJob.countQueue[i]; num2 = Mathf.Min(num2, targetQueue[i].Thing.def.stackLimit - num); num2 = Mathf.Min(num2, actor.carryTracker.AvailableStackSpace(targetQueue[i].Thing.def)); if (num2 > 0) { curJob.count = num2; curJob.SetTarget(ind, targetQueue[i].Thing); List <int> countQueue; List <int> expr_1B2 = countQueue = curJob.countQueue; int num3; int expr_1B6 = num3 = i; num3 = countQueue[num3]; expr_1B2[expr_1B6] = num3 - num2; if (curJob.countQueue[i] == 0) { curJob.countQueue.RemoveAt(i); targetQueue.RemoveAt(i); } actor.jobs.curDriver.JumpToToil(gotoGetTargetToil); return; } } } } } }; return(toil); }
private static Toil JumpToCollectNextIntoHandsForBill(Toil gotoGetTargetToil, TargetIndex ind) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; if (actor.carryTracker.CarriedThing == null) { Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something."); } else if (!actor.carryTracker.Full) { Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind); if (!targetQueue.NullOrEmpty()) { int num = 0; int a; while (true) { if (num >= targetQueue.Count) { return; } if (GenAI.CanUseItemForWork(actor, targetQueue[num].Thing) && targetQueue[num].Thing.CanStackWith(actor.carryTracker.CarriedThing) && !((float)(actor.Position - targetQueue[num].Thing.Position).LengthHorizontalSquared > 64f)) { int num2 = (actor.carryTracker.CarriedThing != null) ? actor.carryTracker.CarriedThing.stackCount : 0; a = curJob.countQueue[num]; a = Mathf.Min(a, targetQueue[num].Thing.def.stackLimit - num2); a = Mathf.Min(a, actor.carryTracker.AvailableStackSpace(targetQueue[num].Thing.def)); if (a > 0) { break; } } num++; } curJob.count = a; curJob.SetTarget(ind, targetQueue[num].Thing); List <int> countQueue; int index; (countQueue = curJob.countQueue)[index = num] = countQueue[index] - a; if (curJob.countQueue[num] <= 0) { curJob.countQueue.RemoveAt(num); targetQueue.RemoveAt(num); } actor.jobs.curDriver.JumpToToil(gotoGetTargetToil); } } }; return(toil); }
public static List <Thing> FindAvailableNearbyResources(ThingDef resourceDef, Pawn pawn, out int resourcesTotalAvailable) { float searchDistanceAfterFirst = 25f; resourcesTotalAvailable = 0; List <Thing> resourcesAvailable = new List <Thing>(); Predicate <Thing> validator = (th => th.def == resourceDef && !th.IsForbidden(pawn) && pawn.CanReserve(th)); Thing closestThing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(resourceDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator); if (closestThing == null || !pawn.Spawned) { return(null); } int num = Mathf.Min(closestThing.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(closestThing.def)); resourcesAvailable.Add(closestThing); resourcesTotalAvailable += closestThing.stackCount; if (resourcesTotalAvailable < num) { foreach (Thing current in GenRadial.RadialDistinctThingsAround(closestThing.Position, closestThing.Map, searchDistanceAfterFirst, false)) { if (resourcesTotalAvailable >= num) { break; } if (current.def == closestThing.def) { if (GenAI.CanUseItemForWork(pawn, current)) { resourcesAvailable.Add(current); resourcesTotalAvailable += current.stackCount; } } } } // Only select as much as we need. if (resourcesTotalAvailable > num) { resourcesTotalAvailable = num; } return(resourcesAvailable); }
private static Toil JumpToAlsoCollectTargetInQueue(Toil gotoGetTargetToil, TargetIndex ind) { const float MaxDist = 8; Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; if (actor.carryTracker.CarriedThing == null) { Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something."); return; } //Early-out if (actor.carryTracker.Full) { return; } Job curJob = actor.jobs.curJob; var targetQueue = curJob.GetTargetQueue(ind); if (targetQueue.NullOrEmpty()) { return; } //Find an item in the queue matching what you're carrying for (int i = 0; i < targetQueue.Count; i++) { //Can't use item - skip if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) { continue; } //Cannot stack with thing in hands - skip if (!targetQueue[i].Thing.CanStackWith(actor.carryTracker.CarriedThing)) { continue; } //Too far away - skip if ((actor.Position - targetQueue[i].Thing.Position).LengthHorizontalSquared > MaxDist * MaxDist) { continue; } //Determine num in hands int numInHands = (actor.carryTracker.CarriedThing == null) ? 0 : actor.carryTracker.CarriedThing.stackCount; //Determine num to take int numToTake = curJob.countQueue[i]; numToTake = Mathf.Min(numToTake, targetQueue[i].Thing.def.stackLimit - numInHands); numToTake = Mathf.Min(numToTake, actor.carryTracker.AvailableStackSpace(targetQueue[i].Thing.def)); //Won't take any - skip if (numToTake <= 0) { continue; } //Set me to go get it curJob.count = numToTake; curJob.SetTarget(ind, targetQueue[i].Thing); //Remove the amount to take from the num to bring list //Remove from queue if I'm going to take all curJob.countQueue[i] -= numToTake; if (curJob.countQueue[i] == 0) { curJob.countQueue.RemoveAt(i); targetQueue.RemoveAt(i); } //Jump to toil actor.jobs.curDriver.JumpToToil(gotoGetTargetToil); return; } }; return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { var ingList = job.GetTargetQueue(IngredientInd); var ingCountList = job.countQueue; // this.job.SetTarget(IngredientPlaceCellInd, this.TargetA.Thing.InteractionCell); var startToil = Toils_General.Do( () => { job.SetTarget(IngredientInd, ingList[0].Thing); job.count = ingCountList[0]; ingList.RemoveAt(0); ingCountList.RemoveAt(0); }); // 材料キューの先頭を取り出してセット yield return(startToil); // 材料の置き場所へ移動 var gotoToil = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch); yield return(gotoToil); // 材料を運ぶ yield return(Toils_Haul.StartCarryThing(IngredientInd)); // 運ぶものリストの中に同種の材料があり、まだ物を持てる場合、設備へ持っていく前に取りに行く yield return(Toils_General.Do( () => { var actor = pawn; var curJob = actor.jobs.curJob; var targetQueue = curJob.GetTargetQueue(IngredientInd); if (targetQueue.NullOrEmpty()) { return; } if (curJob.count <= 0) { return; } if (actor.carryTracker.CarriedThing == null) { Log.Error( "JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something."); return; } if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) <= 0) { return; } for (var i = 0; i < targetQueue.Count; i++) { if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } if (targetQueue[i].Thing.def != actor.carryTracker.CarriedThing.def) { continue; } curJob.SetTarget(IngredientInd, targetQueue[i].Thing); curJob.count = curJob.countQueue[i]; targetQueue.RemoveAt(i); curJob.countQueue.RemoveAt(i); actor.jobs.curDriver.JumpToToil(gotoToil); break; } })); // 運ぶ yield return(Toils_Haul.CarryHauledThingToCell(IngredientPlaceCellInd)); // 運んだものリスト(使用素材)に追加 yield return(Toils_Mizu.AddPlacedThing()); // 運んだものを置く yield return(Toils_Haul.PlaceCarriedThingInCellFacing(BillGiverInd)); // まだ材料があるならさらに運ぶ yield return(Toils_General.Do( () => { if (job.GetTargetQueue(IngredientInd).Count > 0) { pawn.jobs.curDriver.JumpToToil(startToil); } })); // レシピ実行 yield return(Toils_Recipe.DoRecipeWork()); // 水の注入完了処理 yield return(Toils_Mizu.FinishPourRecipe(BillGiverInd)); }
public static bool ResourceDeliverJobFor(WorkGiver_ConstructDeliverResources __instance, ref Job __result, Pawn pawn, IConstructible c, bool canRemoveExistingFloorUnderNearbyNeeders = true) { Blueprint_Install blueprint_Install = c as Blueprint_Install; if (blueprint_Install != null) { __result = InstallJob(pawn, blueprint_Install); return(false); } List <Thing> resourcesAvailable = new List <Thing>(); bool flag = false; ThingDefCountClass thingDefCountClass = null; List <ThingDefCountClass> list = c.MaterialsNeeded(); int count = list.Count; for (int i = 0; i < count; i++) { ThingDefCountClass need = list[i]; if (!pawn.Map.itemAvailability.ThingsAvailableAnywhere(need, pawn)) { flag = true; thingDefCountClass = need; break; } Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(need.thingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, (Thing r) => ResourceValidator(pawn, need, r)); if (foundRes != null) { resourcesAvailable.Clear(); //FindAvailableNearbyResources2(foundRes, pawn, out int resTotalAvailable, resourcesAvailable); int resTotalAvailable; int num0 = Mathf.Min(foundRes.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(foundRes.def)); resTotalAvailable = 0; resourcesAvailable.Add(foundRes); resTotalAvailable += foundRes.stackCount; if (resTotalAvailable < num0) { foreach (Thing item in GenRadial.RadialDistinctThingsAround(foundRes.Position, foundRes.Map, 5f, useCenter: false)) { if (resTotalAvailable >= num0) { break; } if (item.def == foundRes.def && GenAI.CanUseItemForWork(pawn, item)) { resourcesAvailable.Add(item); resTotalAvailable += item.stackCount; } } } int neededTotal; Job jobToMakeNeederAvailable; HashSet <Thing> hashSet = FindNearbyNeeders(pawn, need, c, resTotalAvailable, canRemoveExistingFloorUnderNearbyNeeders, out neededTotal, out jobToMakeNeederAvailable); if (jobToMakeNeederAvailable != null) { __result = jobToMakeNeederAvailable; return(false); } hashSet.Add((Thing)c); Thing thing = hashSet.MinBy((Thing nee) => IntVec3Utility.ManhattanDistanceFlat(foundRes.Position, nee.Position)); hashSet.Remove(thing); int num = 0; int num2 = 0; do { num += resourcesAvailable[num2].stackCount; num2++; }while (num < neededTotal && num2 < resourcesAvailable.Count); resourcesAvailable.RemoveRange(num2, resourcesAvailable.Count - num2); resourcesAvailable.Remove(foundRes); Job job = JobMaker.MakeJob(JobDefOf.HaulToContainer); job.targetA = foundRes; job.targetQueueA = new List <LocalTargetInfo>(); for (num2 = 0; num2 < resourcesAvailable.Count; num2++) { job.targetQueueA.Add(resourcesAvailable[num2]); } job.targetB = thing; if (hashSet.Count > 0) { job.targetQueueB = new List <LocalTargetInfo>(); foreach (Thing item in hashSet) { job.targetQueueB.Add(item); } } job.targetC = (Thing)c; job.count = neededTotal; job.haulMode = HaulMode.ToContainer; __result = job; return(false); } flag = true; thingDefCountClass = need; } if (flag) { JobFailReason.Is($"{MissingMaterialsTranslated}: {thingDefCountClass.thingDef.label}"); } __result = null; return(false); }