public static Job InstallJob(this Blueprint_Install install, Pawn pawn) { var miniToInstallOrBuildingToReinstall = install.MiniToInstallOrBuildingToReinstall; if (miniToInstallOrBuildingToReinstall.IsForbidden(pawn)) { return null; } if (!pawn.CanReach(miniToInstallOrBuildingToReinstall, PathEndMode.ClosestTouch, pawn.NormalMaxDanger())) { return null; } if (!pawn.CanReserve(miniToInstallOrBuildingToReinstall, 1, -1, null, false)) { return null; } return new Job(JobDefOf.HaulToContainer) { targetA = miniToInstallOrBuildingToReinstall, targetB = install, count = 1, haulMode = HaulMode.ToContainer }; }
private static Job InstallJob(Pawn pawn, Blueprint_Install install) { Thing miniToInstallOrBuildingToReinstall = install.MiniToInstallOrBuildingToReinstall; if (miniToInstallOrBuildingToReinstall.IsForbidden(pawn)) { JobFailReason.Is(ForbiddenLowerTranslated); return(null); } if (!pawn.CanReach(miniToInstallOrBuildingToReinstall, PathEndMode.ClosestTouch, pawn.NormalMaxDanger())) { JobFailReason.Is(NoPathTranslated); return(null); } if (!pawn.CanReserve(miniToInstallOrBuildingToReinstall)) { Pawn pawn2 = pawn.Map.reservationManager.FirstRespectedReserver(miniToInstallOrBuildingToReinstall, pawn); if (pawn2 != null) { JobFailReason.Is("ReservedBy".Translate(pawn2.LabelShort, pawn2)); } return(null); } Job job = JobMaker.MakeJob(JobDefOf.HaulToContainer); job.targetA = miniToInstallOrBuildingToReinstall; job.targetB = install; job.count = 1; job.haulMode = HaulMode.ToContainer; return(job); }
public override void DrawExtraSelectionOverlays() { base.DrawExtraSelectionOverlays(); Blueprint_Install blueprint_Install = InstallBlueprintUtility.ExistingBlueprintFor(this); if (blueprint_Install != null) { GenDraw.DrawLineBetween(this.TrueCenter(), blueprint_Install.TrueCenter()); } }
// Token: 0x06000012 RID: 18 RVA: 0x00002784 File Offset: 0x00000984 public static bool Prefix(Blueprint_Install __instance, ref Graphic __result) { if (__instance.MiniToInstallOrBuildingToReinstall.GetInnerIfMinified().def != ThingDefOf.Gachapon) { return(true); } if (!(__instance.MiniToInstallOrBuildingToReinstall.GetInnerIfMinified() is Building_Art_Gachapon building_Art_Gachapon)) { return(true); } __result = building_Art_Gachapon.BlueprintGraphic; return(false); }
static Job FindBedrollJob(Job fallbackJob, Pawn pawn) { if (!pawn.IsColonistPlayerControlled) { return(fallbackJob); } Log.Message(pawn + " looking for inventory beds"); MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn); if (invBed == null) { return(fallbackJob); } Log.Message(pawn + " found " + invBed); Map map = pawn.Map; Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified(); Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction) { if (RegionAndRoomQuery.RoomAtFast(c, map).isPrisonCell != pawn.IsPrisoner) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } if (c.IsForbidden(pawn)) { return(false); } for (CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(c, direction, bed.def.size).GetIterator(); !iterator.Done(); iterator.MoveNext()) { foreach (Thing t in iterator.Current.GetThingList(map)) { if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t)) { return(false); } } if (!(map.zoneManager.ZoneAt(c) is null)) { return(false); } } return(true); }; // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that Predicate <IntVec3> cellValidator = c => cellValidatorDir(c, Rot4.South) || cellValidatorDir(c, Rot4.West); Predicate <IntVec3> goodCellValidator = c => !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c); IntVec3 placePosition = IntVec3.Invalid; IntVec3 root = pawn.Position; TraverseParms trav = TraverseParms.For(pawn); if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition)) { CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition); } } } if (placePosition.IsValid) { Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West; Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction); Log.Message(pawn + " placing " + blueprint + " at " + placePosition); return(new Job(JobDefOf.PlaceBedroll, invBed, blueprint) { haulMode = HaulMode.ToContainer }); } Log.Message(pawn + " couldn't find place for " + invBed); return(fallbackJob); }
// Method from RimWorld.JobGiver_Work.TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) // I modified the line if (!workGiver.ShouldSkip(pawn)) #pragma warning disable public ThinkResult TryIssueJobPackageDrone(Pawn pawn, bool emergency) { List <WorkGiver> list = emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (!workGiver.ShouldSkip(pawn)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, null, new JobTag?(list[j].def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false); if (scanner is WorkGiver_ConstructDeliverResourcesToBlueprints) { //Preforme further checks too see if this is a reinstall attempt of its own station if (thing is Blueprint_Install) { Blueprint_Install bpthing = (Blueprint_Install)thing; Pawn_Drone pd = (Pawn_Drone)pawn; if (bpthing.MiniToInstallOrBuildingToReinstall == pd.station) { //This is a reinstall attempt - Prevent by setting thing to null thing = null; } } } } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = float.MinValue; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(intVec - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(intVec, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, null, new JobTag?(list[j].def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
//protected override Job TryGiveJob(Pawn pawn) public static void Postfix(ref Job __result, Pawn pawn) { if (__result == null) { return; } if (!pawn.IsColonistPlayerControlled) { return; } Map map = pawn.Map; if (!Settings.Get().alsoColonies&& map.IsPlayerHome) { if (!Settings.Get().alsoColoniesKnown) { Settings.Get().alsoColoniesKnown = true; Settings.Get().Write(); Find.LetterStack.ReceiveLetter("TD.UseBedrollsUpdated".Translate(), TranslatorFormattedStringExtensions.Translate("TD.UpdateNewsColonyMaps", pawn), LetterDefOf.NeutralEvent, pawn); // I don't think this really needs to be hugslibs update news or anything. alsoColoniesKnown defaults } return; } if (__result.targetA.Thing is Building_Bed ownedBed) { if (!Settings.Get().distanceCheck || (ownedBed.Position).DistanceTo(pawn.Position) < Settings.Get().distance) { return; //Have a bed that close enough, no need to get from inventory } } MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn); if (invBed == null) { return; } Log.Message($"{pawn} found {invBed}"); Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified(); Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction) { if (RegionAndRoomQuery.RoomAt(c, map).isPrisonCell != pawn.IsPrisoner) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } //Support ReplaceStuff allowing blueprints over beds if (EdificeBlocking(invBed.GetInnerIfMinified().def, c, direction, map)) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } //Each cell of bed: foreach (var pos in GenAdj.OccupiedRect(c, direction, bed.def.size)) { if (map.zoneManager.ZoneAt(pos) != null) { return(false); } foreach (Thing t in pos.GetThingList(map)) { if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t)) { return(false); } } } return(true); }; IntVec3 root = invBed.PositionHeld; // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that Predicate <IntVec3> cellValidator = delegate(IntVec3 c) { if (!cellValidatorDir(c, Rot4.South) && !cellValidatorDir(c, Rot4.West)) { return(false); } using (PawnPath path = map.pathFinder.FindPath(root, c, pawn)) { return(path.TotalCost < 500); } }; Predicate <IntVec3> goodCellValidator = c => !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c); IntVec3 placePosition = IntVec3.Invalid; TraverseParms trav = TraverseParms.For(pawn); if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition)) { CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition); } } } if (placePosition.IsValid) { Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West; Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction); Log.Message($"{pawn} placing {blueprint} at {placePosition}"); __result = new Job(JobDefOf.PlaceBedroll, invBed, blueprint) { haulMode = HaulMode.ToContainer }; } }
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); }