public override string GetReport() { Vehicle_Cart cart = TargetThingA as Vehicle_Cart; IntVec3 destLoc = new IntVec3(-1000, -1000, -1000); string destName = null; SlotGroup destGroup = null; if (pawn.jobs.curJob.targetB != null) { destLoc = pawn.jobs.curJob.targetB.Cell; destGroup = StoreUtility.GetSlotGroup(destLoc); } if (destGroup != null) { destName = destGroup.parent.SlotYielderLabel(); } string repString; if (destName != null) { repString = "ReportDismountingOn".Translate(cart.LabelCap, destName); } else { repString = "ReportDismounting".Translate(cart.LabelCap); } return(repString); }
public static Toil CheckDuplicates(Toil jumpToil, TargetIndex CarrierInd, TargetIndex HaulableInd) { Toil toil = new Toil(); toil.initAction = () => { IntVec3 storeCell = IntVec3.Invalid; Pawn actor = toil.GetActor(); TargetInfo target = toil.actor.jobs.curJob.GetTarget(HaulableInd); if (target.Thing.def.stackLimit <= 1) { return; } List <TargetInfo> targetQueue = toil.actor.jobs.curJob.GetTargetQueue(HaulableInd); if (!targetQueue.NullOrEmpty() && target.Thing.def.defName == targetQueue.First().Thing.def.defName) { toil.actor.jobs.curJob.SetTarget(HaulableInd, targetQueue.First()); Find.Reservations.Reserve(actor, targetQueue.First()); targetQueue.RemoveAt(0); toil.actor.jobs.curDriver.JumpToToil(jumpToil); return; } Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack; if (cart == null && backpack == null) { Log.Error(actor.LabelCap + " Report: Don't have Carrier"); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); return; } int curItemCount = (cart != null ? cart.storage.Count : actor.inventory.container.Count) + targetQueue.Count; int curItemStack = (cart != null ? cart.storage.TotalStackCount : actor.inventory.container.TotalStackCount) + targetQueue.Sum(item => item.Thing.stackCount); int maxItem = cart != null ? cart.MaxItem : backpack.MaxItem; int maxStack = cart != null ? cart.MaxStack : backpack.MaxStack; if (curItemCount >= maxItem || curItemStack >= maxStack) { return; } //Check target's nearby Thing thing = GenClosest.ClosestThing_Global_Reachable(actor.Position, ListerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.Touch, TraverseParms.For(actor, Danger.Some), NearbyCell, item => !targetQueue.Contains(item) && item.def.defName == target.Thing.def.defName && !FireUtility.IsBurning(item) && Find.Reservations.CanReserve(actor, item)); if (thing != null) { toil.actor.jobs.curJob.SetTarget(HaulableInd, thing); Find.Reservations.Reserve(actor, thing); toil.actor.jobs.curDriver.JumpToToil(jumpToil); return; } }; return(toil); }
public static Toil CheckNeedStorageCell(Toil jumpToil, TargetIndex CarrierInd, TargetIndex StoreCellInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack; if (cart == null && backpack == null) { Log.Error(actor.LabelCap + " Report: Don't have Carrier"); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } ThingContainer container = cart != null ? cart.storage : actor.inventory.container; if (container.Count == 0) { return; } IntVec3 cell = ToolsForHaulUtility.FindStorageCell(actor, container.First()); if (cell != IntVec3.Invalid) { toil.actor.jobs.curJob.SetTarget(StoreCellInd, cell); Find.Reservations.Reserve(actor, cell); toil.actor.jobs.curDriver.JumpToToil(jumpToil); } }; return(toil); }
public override Job JobOnThing(Pawn pawn, Thing t) { Vehicle_Cart cart = t as Vehicle_Cart; if (cart == null) { return((Job)null); } if (cart.IsForbidden(pawn.Faction) || !ReservationUtility.CanReserveAndReach(pawn, cart, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(pawn))) { return((Job)null); } if (FireUtility.IsBurning(cart)) { JobFailReason.Is(ToolsForHaulUtility.BurningLowerTrans); return((Job)null); } if (ListerHaulables.ThingsPotentiallyNeedingHauling().Count == 0 && cart.storage.Count == 0) { JobFailReason.Is(ToolsForHaulUtility.NoHaulable); return((Job)null); } if (Find.SlotGroupManager.AllGroupsListInPriorityOrder.Count == 0) { JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans); return((Job)null); } if (ToolsForHaulUtility.AvailableAnimalCart(cart) || ToolsForHaulUtility.AvailableCart(cart, pawn)) { return(ToolsForHaulUtility.HaulWithTools(pawn, cart)); } JobFailReason.Is(ToolsForHaulUtility.NoAvailableCart); return((Job)null); }
public static bool AvailableAnimalCart(Vehicle_Cart cart) { Pawn Driver = (cart.TryGetComp<CompMountable>().IsMounted) ? cart.TryGetComp<CompMountable>().Driver : null; if (Driver == null) return false; return Driver.RaceProps.Animal && PawnUtility.CasualInterruptibleNow(Driver) && Driver.needs.food.CurCategory < HungerCategory.Starving && Driver.needs.rest.CurCategory < RestCategory.VeryTired && !Driver.health.ShouldBeTreatedNow; }
public static bool AvailableAnimalCart(Vehicle_Cart cart) { Pawn Driver = (cart.TryGetComp <CompMountable>().IsMounted) ? cart.TryGetComp <CompMountable>().Driver : null; if (Driver == null) { return(false); } return(Driver.RaceProps.Animal && PawnUtility.CasualInterruptibleNow(Driver) && Driver.needs.food.CurCategory < HungerCategory.Starving && Driver.needs.rest.CurCategory < RestCategory.VeryTired && !Driver.health.ShouldBeTendedNow); }
public static Toil DropTheCarriedInCell(TargetIndex StoreCellInd, ThingPlaceMode placeMode, TargetIndex CarrierInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Vehicle_Cart carrier = actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; if (carrier.storage.Count <= 0) { return; } toil.actor.jobs.curJob.SetTarget(TargetIndex.A, carrier.storage.First()); Thing dropThing = toil.actor.jobs.curJob.targetA.Thing; IntVec3 destLoc = actor.jobs.curJob.GetTarget(StoreCellInd).Cell; Thing dummy; if (destLoc.GetStorable() == null) { Find.DesignationManager.RemoveAllDesignationsOn(dropThing); carrier.storage.TryDrop(dropThing, destLoc, placeMode, out dummy); } //Check cell queue is adjacent List <TargetInfo> cells = curJob.GetTargetQueue(StoreCellInd); for (int i = 0; i < cells.Count && i < carrier.storage.Count; i++) { if (destLoc.AdjacentTo8Way(cells[i].Cell) && cells[i].Cell.GetStorable() == null) { Find.DesignationManager.RemoveAllDesignationsOn(carrier.storage[i]); carrier.storage.TryDrop(carrier.storage[i], cells[i].Cell, ThingPlaceMode.Direct, out dummy); cells.RemoveAt(i); i--; } } //Check item queue is valid storage for adjacent cell foreach (IntVec3 adjCell in GenAdj.CellsAdjacent8Way(destLoc)) { if (carrier.storage.Count > 0 && adjCell.GetStorable() == null && StoreUtility.IsValidStorageFor(adjCell, carrier.storage.First())) { Find.DesignationManager.RemoveAllDesignationsOn(carrier.storage.First()); carrier.storage.TryDrop(carrier.storage.First(), adjCell, ThingPlaceMode.Direct, out dummy); } } }; toil.FailOnDestroyedOrNull(CarrierInd); return(toil); }
protected override bool TryFindGoodExitDest(Pawn pawn, out IntVec3 spot) { using (List <Thing> .Enumerator enumerator = ToolsForHaulUtility.Cart().GetEnumerator()) { while (enumerator.MoveNext()) { Vehicle_Cart vehicle_Cart = (Vehicle_Cart)enumerator.Current; if (vehicle_Cart.mountableComp.IsMounted && !vehicle_Cart.mountableComp.Driver.RaceProps.Animal && vehicle_Cart.mountableComp.Driver.ThingID == pawn.ThingID) { vehicle_Cart.despawnAtEdge = true; } } } return(ExitUtility.TryFindRandomExitSpot(pawn, ref spot, 1)); }
public static Job DismountInBase(Pawn pawn, Vehicle_Cart cart) { Job job = new Job(jobDefDismountInBase); job.targetA = cart; job.targetB = FindStorageCell(pawn, cart); if (job.targetB != IntVec3.Invalid) { Trace.AppendLine("DismountInBase Job is issued"); Trace.LogMessage(); return job; } JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart); Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return (Job)null; }
protected override IEnumerable <Toil> MakeNewToils() { /// //Set fail conditions /// this.FailOnDestroyedOrNull(CartInd); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items if (!TargetThingA.IsForbidden(pawn.Faction)) { this.FailOnForbidden(CartInd); } Vehicle_Cart cart = TargetThingA as Vehicle_Cart; /// //Define Toil /// Toil toilGoToCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.Reserve(StoreCellInd)); //JumpIf already mounted yield return(Toils_Jump.JumpIf(toilGoToCell, () => { return (cart.GetComp <CompMountable>().Driver == pawn) ? true : false; })); //Mount on Target yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(CartInd)); yield return(Toils_Cart.MountOn(CartInd)); //Dismount yield return(toilGoToCell); yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd)); }
public static Job DismountInBase(Pawn pawn, Vehicle_Cart cart) { Job job = new Job(jobDefDismountInBase); job.targetA = cart; job.targetB = FindStorageCell(pawn, cart); if (job.targetB != IntVec3.Invalid) { Trace.AppendLine("DismountInBase Job is issued"); Trace.LogMessage(); return(job); } JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart); Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return((Job)null); }
public static Toil DismountAt(TargetIndex CartInd, TargetIndex StoreCellInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } cart.GetComp <CompMountable>().DismountAt(toil.actor.jobs.curJob.GetTarget(StoreCellInd).Cell); }; return(toil); }
public static Toil CallAnimalCart(TargetIndex CartInd, TargetIndex Ind) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } Job job = new Job(jobDefStandby, toil.actor.jobs.curJob.GetTarget(Ind), defaultWaitWorker); cart.mountableComp.Driver.jobs.StartJob(job, JobCondition.InterruptForced); }; return(toil); }
public HeadLights(IntVec3 position, Rot4 orientation, Vehicle_Cart vehicleCart) { Position = position; Orientation = orientation; //TODO move the colors to xml along with the angleModulus + targetDistance ColorCellIndexCache = new List <GlowGridCache>(); //FloodBlockers = new List<FloodBlocker>(); //Color = new Color32(191, 63, 191, 1); //Color = new Color32(254, 255, 179, 0); Color = new Color32(210, 210, 140, 0); innerArray = Find.EdificeGrid.InnerArray; targetDistance = 20; angleModulus = 4; //0 is 90 and the higher you go the more narrow the angle. //angle 45 is every two tiles? - actually its 90 because left side is 0->45 and then right is 45<-0 }
public static Toil ReleaseAnimalCart(TargetIndex CartInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } if (cart.mountableComp.IsMounted && cart.mountableComp.Driver.CurJob.def == jobDefStandby) { cart.mountableComp.Driver.jobs.curDriver.EndJobWith(JobCondition.Succeeded); } }; return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { /// //Set fail conditions /// this.FailOnDestroyed(MountableInd); this.FailOnDowned(DriverInd); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items if (!TargetThingA.IsForbidden(pawn.Faction)) { this.FailOnForbidden(MountableInd); } /// //Define Toil /// Toil toilMakeStandby = new Toil(); toilMakeStandby.initAction = () => { Pawn driver = CurJob.GetTarget(DriverInd).Thing as Pawn; driver.jobs.StartJob(new Job(DefDatabase <JobDef> .GetNamed("Standby"), driver.Position, 2400 + (int)((pawn.Position - driver.Position).LengthHorizontal * 120)), JobCondition.InterruptForced); }; Toil toilGoto = null; toilGoto = Toils_Goto.GotoThing(MountableInd, PathEndMode.ClosestTouch) .FailOn(() => { //Note we don't fail on losing hauling designation //Because that's a special case anyway //While hauling to cell storage, ensure storage dest is still valid Pawn actor = toilGoto.actor; Job curJob = actor.jobs.curJob; if (curJob.haulMode == HaulMode.ToCellStorage) { Thing haulThing = curJob.GetTarget(MountableInd).Thing; IntVec3 destLoc = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell; if (!destLoc.IsValidStorageFor(haulThing)) { return(true); } } return(false); }); Toil toilMountOn = new Toil(); toilMountOn.initAction = () => { Pawn driver = TargetB.Thing as Pawn; if (driver != null && TargetThingA.TryGetComp <CompMountable>() != null) { TargetThingA.TryGetComp <CompMountable>().MountOn(driver); } else { Log.Error(GetActor().LabelCap + ": Try make mount without target B Driver"); EndJobWith(JobCondition.Errored); } }; Toil toilEnd = new Toil(); toilEnd.initAction = () => { Vehicle_Cart cart = CurJob.GetTarget(MountableInd).Thing as Vehicle_Cart; Vehicle_Saddle saddle = CurJob.GetTarget(MountableInd).Thing as Vehicle_Saddle; if (cart == null || saddle == null) { Log.Error(GetActor().LabelCap + ": MakeMount get TargetA not cart or saddle."); EndJobWith(JobCondition.Errored); return; } if (cart.mountableComp.IsMounted && cart.mountableComp.Driver.CurJob.def == DefDatabase <JobDef> .GetNamed("Standby")) { cart.mountableComp.Driver.jobs.curDriver.EndJobWith(JobCondition.Succeeded); } EndJobWith(JobCondition.Succeeded); }; /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(MountableInd)); yield return(Toils_Reserve.Reserve(DriverInd)); yield return(toilMakeStandby); yield return(toilGoto); yield return(Toils_Haul.StartCarryThing(MountableInd)); yield return(Toils_Haul.CarryHauledThingToCell(DriverInd)); yield return(toilMountOn); yield return(toilEnd); }
public static bool AvailableCart(Vehicle_Cart cart, Pawn pawn) { return(!cart.TryGetComp <CompMountable>().IsMounted || cart.TryGetComp <CompMountable>().Driver == pawn); }
public static Toil WaitAnimalCart(TargetIndex CartInd, TargetIndex HaulableInd) { Toil toil = new Toil(); int tickTime = 0; toil.initAction = () => { Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } tickTime = 0; if (cart.mountableComp.IsMounted) { //Worker is arrival and Animal cart is coming if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && !actor.Position.AdjacentTo8WayOrInside(cart)) { tickTime = 0; } //Worker is arrival and Animal cart is arrival else if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && actor.Position.AdjacentTo8WayOrInside(cart)) { toil.actor.jobs.curDriver.ReadyForNextToil(); } //Worker is arrival but Animal cart is missing else { Job job = new Job(jobDefStandby, actor.jobs.curJob.GetTarget(HaulableInd), defaultWaitWorker); cart.mountableComp.Driver.jobs.StartJob(job, JobCondition.InterruptForced); } } else { toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } }; toil.tickAction = () => { Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } if (Find.TickManager.TicksGame % tickCheckInterval == 0) { if (cart.mountableComp.IsMounted) { //Animal cart is arrival if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && actor.Position.AdjacentTo8WayOrInside(cart)) { toil.actor.jobs.curDriver.ReadyForNextToil(); } //Animal cart would never come. Imcompletable. else if (cart.mountableComp.Driver.CurJob.def != jobDefStandby || tickTime >= defaultWaitWorker) { toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } } else { toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } } }; toil.defaultCompleteMode = ToilCompleteMode.Never; return(toil); }
public static Job HaulWithTools(Pawn pawn, Vehicle_Cart cart = null) { Trace.stopWatchStart(); //Job Setting JobDef jobDef; TargetInfo targetC; int maxItem; int thresholdItem; int reservedMaxItem; IEnumerable <Thing> remainingItems; bool ShouldDrop; Thing lastItem = ToolsForHaulUtility.TryGetBackpackLastItem(pawn); if (cart == null) { Apparel_Backpack backpack = ToolsForHaulUtility.TryGetBackpack(pawn); jobDef = jobDefHaulWithBackpack; targetC = backpack; maxItem = backpack.MaxItem; thresholdItem = (int)Math.Ceiling(maxItem * 0.5); reservedMaxItem = pawn.inventory.container.Count; remainingItems = pawn.inventory.container; ShouldDrop = true; if (lastItem != null) { for (int i = 0; i < pawn.inventory.container.Count; i++) { if (pawn.inventory.container[i] == lastItem && (reservedMaxItem - (i + 1)) <= 0) { ShouldDrop = false; break; } } } } else { jobDef = (cart.TryGetComp <CompMountable>().IsMounted&& cart.TryGetComp <CompMountable>().Driver.RaceProps.Animal)? jobDefHaulWithAnimalCart : jobDefHaulWithCart; targetC = cart; maxItem = cart.MaxItem; thresholdItem = (int)Math.Ceiling(maxItem * 0.5); reservedMaxItem = cart.storage.Count; remainingItems = cart.storage; ShouldDrop = (reservedMaxItem > 0) ? true : false; } Job job = new Job(jobDef); job.targetQueueA = new List <TargetInfo>(); job.targetQueueB = new List <TargetInfo>(); job.targetC = targetC; Trace.AppendLine(pawn.LabelCap + " In HaulWithTools: " + jobDef.defName + "\n" + "MaxItem: " + maxItem + " reservedMaxItem: " + reservedMaxItem); //Drop remaining item if (ShouldDrop) { Trace.AppendLine("Start Drop remaining item"); bool startDrop = false; for (int i = 0; i < remainingItems.Count(); i++) { if (cart == null && startDrop == false) { if (remainingItems.ElementAt(i) == lastItem) { startDrop = true; } else { continue; } } IntVec3 storageCell = FindStorageCell(pawn, remainingItems.ElementAt(i), job.targetQueueB); if (storageCell == IntVec3.Invalid) { break; } job.targetQueueB.Add(storageCell); } if (!job.targetQueueB.NullOrEmpty()) { Trace.AppendLine("Droping Job is issued"); Trace.LogMessage(); return(job); } if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage()) { Trace.AppendLine("In DismountInBase"); return(DismountInBase(pawn, cart)); } JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans); Trace.AppendLine("End Drop remaining item"); Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return((Job)null); } //Collect item Trace.AppendLine("Start Collect item"); IntVec3 searchPos = (cart != null) ? cart.Position : pawn.Position; bool flag1 = false; foreach (SlotGroup slotGroup in Find.SlotGroupManager.AllGroupsListInPriorityOrder) { Trace.AppendLine("Start searching slotGroup"); if (slotGroup.CellsList.Count() - slotGroup.HeldThings.Count() < maxItem) { continue; } //Counting valid items Trace.AppendLine("Start Counting valid items"); int thingsCount = ListerHaulables.ThingsPotentiallyNeedingHauling().Count(item => slotGroup.Settings.AllowedToAccept(item)); //Finding valid items Trace.AppendLine("Start Finding valid items"); if (thingsCount > thresholdItem) { //ClosestThing_Global_Reachable Configuration Predicate <Thing> predicate = item => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) && ((cart != null && cart.allowances.Allows(item)) || cart == null) && slotGroup.Settings.AllowedToAccept(item) && pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn)); //&& !(item is UnfinishedThing && ((UnfinishedThing)item).BoundBill != null) //&& (item.def.IsNutritionSource && !SocialProperness.IsSociallyProper(item, pawn, false, false)); Thing thing = GenClosest.ClosestThing_Global_Reachable(searchPos, ListerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.ClosestTouch, TraverseParms.For(TraverseMode.ByPawn, DangerUtility.NormalMaxDanger(pawn)), 9999, predicate); if (thing == null) { continue; } IntVec3 center = thing.Position; //Enqueue items in valid distance Trace.AppendLine("Start Enqueuing items in valid distance"); foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) && ((cart != null && cart.allowances.Allows(item)) || cart == null) && slotGroup.Settings.AllowedToAccept(item) && pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn)) && center.DistanceToSquared(item.Position) <= ValidDistance)) { job.targetQueueA.Add(item); if (reservedMaxItem + job.targetQueueA.Count >= maxItem) { break; } } //Find storage cell Trace.AppendLine("Start Finding storage cell"); if (reservedMaxItem + job.targetQueueA.Count > thresholdItem) { List <IntVec3> availableCells = new List <IntVec3>(); foreach (IntVec3 cell in slotGroup.CellsList.Where(cell => ReservationUtility.CanReserve(pawn, cell) && cell.Standable() && cell.GetStorable() == null)) { job.targetQueueB.Add(cell); if (job.targetQueueB.Count >= job.targetQueueA.Count) { break; } } flag1 = true; break; } else { job.targetQueueA.Clear(); } } if (flag1) { break; } } Trace.AppendLine("Elapsed Time"); Trace.stopWatchStop(); //Check job is valid if (!job.targetQueueA.NullOrEmpty() && reservedMaxItem + job.targetQueueA.Count > thresholdItem && !job.targetQueueB.NullOrEmpty()) { Trace.AppendLine("Hauling Job is issued"); Trace.LogMessage(); return(job); } if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage()) { Trace.AppendLine("In DismountInBase: "); return(DismountInBase(pawn, cart)); } if (job.targetQueueA.NullOrEmpty()) { JobFailReason.Is(ToolsForHaulUtility.NoHaulable); } else if (reservedMaxItem + job.targetQueueA.Count <= thresholdItem) { JobFailReason.Is(ToolsForHaulUtility.TooLittleHaulable); } else if (job.targetQueueB.NullOrEmpty()) { JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans); } Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return((Job)null); }
protected override void FillTab() { float fieldHeight = 30.0f; Vehicle_Cart cart = this.SelThing as Vehicle_Cart; ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.PrisonerTab, KnowledgeAmount.GuiFrame); Text.Font = GameFont.Small; Rect innerRect1 = GenUI.ContractedBy(new Rect(0.0f, 0.0f, this.size.x, this.size.y), 10f); GUI.BeginGroup(innerRect1); Rect mountedRect = new Rect(0.0f, 30.0f, innerRect1.width, fieldHeight); float mountedRectY = mountedRect.y; Widgets.ListSeparator(ref mountedRectY, innerRect1.width, txtDriver.Translate()); mountedRect.y += fieldHeight; Rect thingIconRect = new Rect(mountedRect.x, mountedRect.y, 30f, fieldHeight); Rect thingLabelRect = new Rect(mountedRect.x + 35f, mountedRect.y + 5.0f, innerRect1.width - 35f, fieldHeight); Rect thingButtonRect = new Rect(mountedRect.x, mountedRect.y, innerRect1.width, fieldHeight); if (cart.mountableComp.IsMounted) { Pawn driver = cart.mountableComp.Driver; Widgets.ThingIcon(thingIconRect, driver); Widgets.Label(thingLabelRect, driver.Label); if (Event.current.button == 1 && Widgets.InvisibleButton(thingButtonRect)) { List <FloatMenuOption> options = new List <FloatMenuOption>(); FloatMenuOption dismount = new FloatMenuOption(txtDismount.Translate(driver.LabelBase), () => { cart.mountableComp.Dismount(); }); options.Add(dismount); Find.WindowStack.Add(new FloatMenu(options)); } thingIconRect.y += fieldHeight; thingLabelRect.y += fieldHeight; } Rect storageRect = new Rect(0.0f, thingIconRect.y, innerRect1.width, fieldHeight); float storageRectY = storageRect.y; Widgets.ListSeparator(ref storageRectY, innerRect1.width, txtStorage.Translate()); storageRect.y += fieldHeight; thingIconRect.y = storageRect.y; thingLabelRect.y = storageRect.y; thingButtonRect.y = storageRect.y; foreach (var thing in cart.storage) { if ((thing.ThingID.IndexOf("Human_Corpse") <= -1) ? false : true) { Widgets.DrawTextureFitted(thingIconRect, ContentFinder <Texture2D> .Get("Things/Pawn/IconHuman_Corpse"), 1.0f); } else if ((thing.ThingID.IndexOf("Corpse") <= -1) ? false : true) { Corpse corpse = thing as Corpse; Widgets.ThingIcon(thingIconRect, corpse.innerPawn.def); } else { Widgets.ThingIcon(thingIconRect, thing); } Widgets.Label(thingLabelRect, thing.Label.Translate()); if (Event.current.button == 1 && Widgets.InvisibleButton(thingButtonRect)) { List <FloatMenuOption> options = new List <FloatMenuOption>(); options.Add(new FloatMenuOption(Translator.Translate("ThingInfo"), () => { Find.WindowStack.Add((Window) new Dialog_InfoCard(thing)); })); options.Add(new FloatMenuOption(Translator.Translate("DropThing"), () => { Thing dummy; cart.storage.TryDrop(thing, cart.Position, ThingPlaceMode.Near, out dummy); })); Find.WindowStack.Add((Window) new FloatMenu(options, thing.LabelCap, false, false)); } thingIconRect.y += fieldHeight; thingLabelRect.y += fieldHeight; } if (Widgets.TextButton(new Rect(180f, 400f, 100f, 30f), "Drop All")) { cart.storage.TryDropAll(cart.Position, ThingPlaceMode.Near); } GUI.EndGroup(); }
public static bool AvailableCart(Vehicle_Cart cart, Pawn pawn) { return (!cart.TryGetComp<CompMountable>().IsMounted || cart.TryGetComp<CompMountable>().Driver == pawn); }
public static Toil CollectInCarrier(TargetIndex CarrierInd, TargetIndex HaulableInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Thing haulThing = curJob.GetTarget(HaulableInd).Thing; Vehicle_Cart carrier = curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; //Check haulThing is human_corpse. If other race has apparel, It need to change Find.DesignationManager.RemoveAllDesignationsOn(haulThing); if ((haulThing.ThingID.IndexOf("Human_Corpse") <= -1) ? false : true) { Corpse corpse = (Corpse)haulThing; var wornApparel = corpse.innerPawn.apparel.WornApparel; //Drop wornApparel. wornApparel cannot Add to container directly because it will be duplicated. corpse.innerPawn.apparel.DropAll(corpse.innerPawn.Position, false); //Transfer in container foreach (Thing apparel in wornApparel) { if (carrier.storage.TryAdd(apparel)) { apparel.holder = carrier.GetContainer(); apparel.holder.owner = carrier; } } } //Collecting TargetIndex ind if (carrier.storage.TryAdd(haulThing)) { haulThing.holder = carrier.GetContainer(); haulThing.holder.owner = carrier; } List <TargetInfo> thingList = curJob.GetTargetQueue(HaulableInd); for (int i = 0; i < thingList.Count; i++) { if (actor.Position.AdjacentTo8Way(thingList[i].Thing.Position)) { if (carrier.storage.TryAdd(thingList[i].Thing)) { thingList[i].Thing.holder = carrier.GetContainer(); thingList[i].Thing.holder.owner = carrier; } thingList.RemoveAt(i); i--; } } }; toil.FailOn(() => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Thing haulThing = curJob.GetTarget(HaulableInd).Thing; Vehicle_Cart carrier = curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; if (!carrier.storage.CanAcceptAnyOf(haulThing) && actor.Position.IsAdjacentTo8WayOrInside(haulThing.Position, haulThing.Rotation, haulThing.RotatedSize)) { return(true); } return(false); }); toil.FailOnDestroyedOrNull(CarrierInd); return(toil); }
private void ImpactSomething() { if (def.projectile.flyOverhead) { RoofDef roofDef = Find.RoofGrid.RoofAt(Position); if (roofDef != null) { if (roofDef.isThickRoof) { def.projectile.soundHitThickRoof.PlayOneShot(Position); Destroy(); return; } if (Position.GetEdifice() == null || Position.GetEdifice().def.Fillage != FillCategory.Full) { RoofCollapserImmediate.DropRoofInCells(Position); } } } if (assignedTarget != null) { Pawn pawn = assignedTarget as Pawn; if (pawn != null && pawn.GetPosture() != PawnPosture.Standing && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f && Rand.Value > 0.2f) { Impact(null); return; } Impact(assignedTarget); return; } else { cellThingsFiltered.Clear(); List <Thing> thingList = Position.GetThingList(); for (int i = 0; i < thingList.Count; i++) { Pawn pawn2 = thingList[i] as Pawn; if (pawn2 != null) { cellThingsFiltered.Add(pawn2); } Vehicle_Cart cart = thingList[i] as Vehicle_Cart; if (cart != null) { cellThingsFiltered.Add(cart); } } if (cellThingsFiltered.Count > 0) { Impact(cellThingsFiltered.RandomElement()); return; } cellThingsFiltered.Clear(); for (int j = 0; j < thingList.Count; j++) { Thing thing = thingList[j]; if (thing.def.fillPercent > 0f || thing.def.passability != Traversability.Standable) { cellThingsFiltered.Add(thing); } } if (cellThingsFiltered.Count > 0) { Impact(cellThingsFiltered.RandomElement()); return; } Impact(null); return; } }
protected override IEnumerable <Toil> MakeNewToils() { Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart; /// //Set fail conditions /// this.FailOnDestroyedOrNull(CartInd); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items if (!TargetThingA.IsForbidden(pawn.Faction)) { this.FailOnForbidden(CartInd); } /// //Define Toil /// Toil findStoreCellForCart = Toils_Cart.FindStoreCellForCart(CartInd); Toil checkCartEmpty = Toils_Jump.JumpIf(findStoreCellForCart, () => cart.storage.Count <= 0); Toil checkStoreCellEmpty = Toils_Jump.JumpIf(findStoreCellForCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); //JumpIf already mounted yield return(Toils_Jump.JumpIf(checkHaulableEmpty, () => { return (cart.GetComp <CompMountable>().Driver == pawn) ? true : false; })); //Mount on Target yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(CartInd)); yield return(Toils_Cart.MountOn(CartInd)); //JumpIf checkStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(HaulableInd); yield return(gotoThing); yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd)); yield return(Toils_Collect.CheckDuplicates(gotoThing, CartInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf findStoreCellForCart yield return(checkStoreCellEmpty); //Drop TargetQueue { yield return(checkCartEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil gotoCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch); yield return(gotoCell); yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(gotoCell, CartInd, StoreCellInd)); } yield return(findStoreCellForCart); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.OnCell)); yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd)); }
protected override IEnumerable <Toil> MakeNewToils() { Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart; Job jobNew = new Job(); /// //Set fail conditions /// this.FailOnDestroyed(CartInd); this.FailOn(() => !cart.mountableComp.IsMounted); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items if (!TargetThingA.IsForbidden(pawn.Faction)) { this.FailOnForbidden(CartInd); } /// //Define Toil /// Toil releaseAnimalCart = Toils_Cart.ReleaseAnimalCart(CartInd); Toil checkCartEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => cart.storage.Count <= 0); Toil checkStoreCellEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.Touch) .FailOn(() => cart.Destroyed || !cart.TryGetComp <CompMountable>().IsMounted)); //JumpIf toilCheckStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil callAnimalCartForCollect = Toils_Cart.CallAnimalCart(CartInd, HaulableInd) .FailOnDestroyed(HaulableInd); yield return(callAnimalCartForCollect); yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyed(HaulableInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd)); yield return(Toils_Collect.CheckDuplicates(callAnimalCartForCollect, CartInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf releaseAnimalCart yield return(checkStoreCellEmpty); //Drop TargetQueue { yield return(checkCartEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil callAnimalCartForDrop = Toils_Cart.CallAnimalCart(CartInd, StoreCellInd); yield return(callAnimalCartForDrop); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch) .FailOnBurningImmobile(StoreCellInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(callAnimalCartForDrop, CartInd, StoreCellInd)); } yield return(releaseAnimalCart); }
/// <summary> /// Selects the appropriate vehicle by worktype /// </summary> /// <param name="pawn"></param> /// <param name="worktype"></param> /// <returns></returns> public static Thing GetRightVehicle(Pawn pawn, WorkTypeDef worktype, Thing t = null) { Thing cart = null; if (worktype.Equals(WorkTypeDefOf.Hunting)) { bool skip = false; IOrderedEnumerable <Thing> orderedEnumerable = ToolsForHaulUtility.CartTurret.OrderBy(x => pawn.Position.DistanceToSquared(x.Position)); foreach (Thing thing in orderedEnumerable) { Vehicle_Turret vehicleTurret = (Vehicle_Turret)thing; if (vehicleTurret == null) { continue; } if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleTurret)) { continue; } if (!vehicleTurret.IsCurrentlyMotorized()) { continue; } if (vehicleTurret.vehicleComp.tankLeaking) { continue; } cart = vehicleTurret; skip = true; break; } if (!skip) { IOrderedEnumerable <Thing> orderedEnumerable2 = ToolsForHaulUtility.Cart.OrderBy(x => pawn.Position.DistanceToSquared(x.Position)); foreach (Thing thing in orderedEnumerable2) { Vehicle_Cart vehicleCart = (Vehicle_Cart)thing; if (vehicleCart == null) { continue; } if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart)) { continue; } if (!vehicleCart.IsCurrentlyMotorized()) { continue; } if (vehicleCart.vehicleComp.tankLeaking) { continue; } cart = vehicleCart; break; } } } if (worktype.Equals(WorkTypeDefOf.Hauling)) { IOrderedEnumerable <Thing> orderedEnumerable2 = ToolsForHaulUtility.Cart.OrderByDescending(x => (x as Vehicle_Cart).MaxItem).ThenBy(x => pawn.Position.DistanceToSquared(x.Position)); foreach (Thing thing in orderedEnumerable2) { Vehicle_Cart vehicleCart = (Vehicle_Cart)thing; if (vehicleCart == null) { continue; } if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart)) { continue; } if (vehicleCart.vehicleComp.tankLeaking) { continue; } cart = vehicleCart; break; } } if (worktype.Equals(WorkTypeDefOf.Construction)) { IOrderedEnumerable <Thing> orderedEnumerable2 = ToolsForHaulUtility.Cart.OrderBy(x => pawn.Position.DistanceToSquared(x.Position)).ThenByDescending(x => (x as Vehicle_Cart).VehicleSpeed); foreach (Thing thing in orderedEnumerable2) { Vehicle_Cart vehicleCart = (Vehicle_Cart)thing; if (vehicleCart == null) { continue; } if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart)) { continue; } if (!vehicleCart.IsCurrentlyMotorized()) { continue; } if (vehicleCart.vehicleComp.tankLeaking) { continue; } cart = vehicleCart; break; } } return(cart); }
public static Job HaulWithTools(Pawn pawn, Vehicle_Cart cart = null) { Trace.stopWatchStart(); //Job Setting JobDef jobDef; TargetInfo targetC; int maxItem; int thresholdItem; int reservedMaxItem; IEnumerable<Thing> remainingItems; bool ShouldDrop; Thing lastItem = ToolsForHaulUtility.TryGetBackpackLastItem(pawn); if (cart == null) { Apparel_Backpack backpack = ToolsForHaulUtility.TryGetBackpack(pawn); jobDef = jobDefHaulWithBackpack; targetC = backpack; maxItem = backpack.MaxItem; thresholdItem = (int)Math.Ceiling(maxItem * 0.5); reservedMaxItem = pawn.inventory.container.Count; remainingItems = pawn.inventory.container; ShouldDrop = true; if (lastItem != null) for (int i = 0; i < pawn.inventory.container.Count; i++) if (pawn.inventory.container[i] == lastItem && (reservedMaxItem - (i + 1)) <= 0) { ShouldDrop = false; break; } } else { jobDef = (cart.TryGetComp<CompMountable>().IsMounted && cart.TryGetComp<CompMountable>().Driver.RaceProps.Animal)? jobDefHaulWithAnimalCart : jobDefHaulWithCart; targetC = cart; maxItem = cart.MaxItem; thresholdItem = (int)Math.Ceiling(maxItem * 0.5); reservedMaxItem = cart.storage.Count; remainingItems = cart.storage; ShouldDrop = (reservedMaxItem > 0) ? true : false; } Job job = new Job(jobDef); job.targetQueueA = new List<TargetInfo>(); job.targetQueueB = new List<TargetInfo>(); job.targetC = targetC; Trace.AppendLine(pawn.LabelCap + " In HaulWithTools: " + jobDef.defName + "\n" + "MaxItem: " + maxItem + " reservedMaxItem: " + reservedMaxItem); //Drop remaining item if (ShouldDrop) { Trace.AppendLine("Start Drop remaining item"); bool startDrop = false; for (int i = 0; i < remainingItems.Count(); i++) { if (cart == null && startDrop == false) if (remainingItems.ElementAt(i) == lastItem) startDrop = true; else continue; IntVec3 storageCell = FindStorageCell(pawn, remainingItems.ElementAt(i), job.targetQueueB); if (storageCell == IntVec3.Invalid) break; job.targetQueueB.Add(storageCell); } if (!job.targetQueueB.NullOrEmpty()) { Trace.AppendLine("Droping Job is issued"); Trace.LogMessage(); return job; } if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage()) { Trace.AppendLine("In DismountInBase"); return DismountInBase(pawn, cart); } JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans); Trace.AppendLine("End Drop remaining item"); Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return (Job)null; } //Collect item Trace.AppendLine("Start Collect item"); IntVec3 searchPos = (cart != null) ? cart.Position : pawn.Position; bool flag1 = false; foreach (SlotGroup slotGroup in Find.SlotGroupManager.AllGroupsListInPriorityOrder) { Trace.AppendLine("Start searching slotGroup"); if (slotGroup.CellsList.Count() - slotGroup.HeldThings.Count() < maxItem) continue; //Counting valid items Trace.AppendLine("Start Counting valid items"); int thingsCount = ListerHaulables.ThingsPotentiallyNeedingHauling().Count(item => slotGroup.Settings.AllowedToAccept(item)); //Finding valid items Trace.AppendLine("Start Finding valid items"); if (thingsCount > thresholdItem) { //ClosestThing_Global_Reachable Configuration Predicate<Thing> predicate = item => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) && ((cart != null && cart.allowances.Allows(item)) || cart == null) && slotGroup.Settings.AllowedToAccept(item) && pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn)); //&& !(item is UnfinishedThing && ((UnfinishedThing)item).BoundBill != null) //&& (item.def.IsNutritionSource && !SocialProperness.IsSociallyProper(item, pawn, false, false)); Thing thing = GenClosest.ClosestThing_Global_Reachable(searchPos, ListerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.ClosestTouch, TraverseParms.For(TraverseMode.ByPawn, DangerUtility.NormalMaxDanger(pawn)), 9999, predicate); if (thing == null) continue; IntVec3 center = thing.Position; //Enqueue items in valid distance Trace.AppendLine("Start Enqueuing items in valid distance"); foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) && ((cart != null && cart.allowances.Allows(item)) || cart == null) && slotGroup.Settings.AllowedToAccept(item) && pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn)) && center.DistanceToSquared(item.Position) <= ValidDistance)) { job.targetQueueA.Add(item); if (reservedMaxItem + job.targetQueueA.Count >= maxItem) break; } //Find storage cell Trace.AppendLine("Start Finding storage cell"); if (reservedMaxItem + job.targetQueueA.Count > thresholdItem) { List<IntVec3> availableCells = new List<IntVec3>(); foreach (IntVec3 cell in slotGroup.CellsList.Where(cell => ReservationUtility.CanReserve(pawn, cell) && cell.Standable() && cell.GetStorable() == null)) { job.targetQueueB.Add(cell); if (job.targetQueueB.Count >= job.targetQueueA.Count) break; } flag1 = true; break; } else job.targetQueueA.Clear(); } if (flag1) break; } Trace.AppendLine("Elapsed Time"); Trace.stopWatchStop(); //Check job is valid if (!job.targetQueueA.NullOrEmpty() && reservedMaxItem + job.targetQueueA.Count > thresholdItem && !job.targetQueueB.NullOrEmpty()) { Trace.AppendLine("Hauling Job is issued"); Trace.LogMessage(); return job; } if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage()) { Trace.AppendLine("In DismountInBase: "); return DismountInBase(pawn, cart); } if (job.targetQueueA.NullOrEmpty()) JobFailReason.Is(ToolsForHaulUtility.NoHaulable); else if (reservedMaxItem + job.targetQueueA.Count <= thresholdItem) JobFailReason.Is(ToolsForHaulUtility.TooLittleHaulable); else if (job.targetQueueB.NullOrEmpty()) JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans); Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason); Trace.LogMessage(); return (Job)null; }
public static Toil FindStoreCellForCart(TargetIndex CartInd) { const int NearbyCell = 8; const int RegionCellOffset = 16; IntVec3 invalid = new IntVec3(0, 0, 0); #if DEBUG StringBuilder stringBuilder = new StringBuilder(); #endif Toil toil = new Toil(); toil.initAction = () => { IntVec3 storeCell = IntVec3.Invalid; Pawn actor = toil.GetActor(); Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart; if (cart == null) { Log.Error(actor.LabelCap + " Report: Cart is invalid."); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } //Find Valid Storage foreach (IntVec3 cell in GenRadial.RadialCellsAround(cart.Position, NearbyCell, false)) { if (cell.IsValidStorageFor(cart) && ReservationUtility.CanReserveAndReach(actor, cell, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(actor))) { storeCell = cell; #if DEBUG stringBuilder.AppendLine("Found cell: " + storeCell); #endif } } if (storeCell == IntVec3.Invalid) { //Regionwise Flood-fill cellFinder int regionInd = 0; List <Region> regions = new List <Region>(); regions.Add(cart.Position.GetRegion()); #if DEBUG stringBuilder.AppendLine(actor.LabelCap + " Report"); #endif bool flag1 = false; while (regionInd < regions.Count) { #if DEBUG stringBuilder.AppendLine("Region id: " + regions[regionInd].id); #endif if (regions[regionInd].extentsClose.Center.InHorDistOf(cart.Position, NearbyCell + RegionCellOffset)) { IntVec3 foundCell = IntVec3.Invalid; IntVec3 distCell = (regionInd > 0)? regions[regionInd - 1].extentsClose.Center : cart.Position; float distFoundCell = float.MaxValue; foreach (IntVec3 cell in regions[regionInd].Cells) { //Find best cell for placing cart if (cell.GetEdifice() == null && cell.GetZone() == null && cell.Standable() && !GenAdj.CellsAdjacentCardinal(cell, Rot4.North, IntVec2.One).Any(cardinal => cardinal.GetEdifice() is Building_Door) && ReservationUtility.CanReserveAndReach(actor, cell, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(actor))) { if (distCell.DistanceToSquared(cell) < distFoundCell) { foundCell = cell; distFoundCell = distCell.DistanceToSquared(cell); flag1 = true; } } } if (flag1 == true) { storeCell = foundCell; #if DEBUG stringBuilder.AppendLine("Found cell: " + storeCell); #endif break; } foreach (RegionLink link in regions[regionInd].links) { if (regions.Contains(link.RegionA) == false) { regions.Add(link.RegionA); } if (regions.Contains(link.RegionB) == false) { regions.Add(link.RegionB); } } } regionInd++; } } //Log.Message(stringBuilder.ToString()); /* * //Home Area * if (storeCell == IntVec3.Invalid) * foreach (IntVec3 cell in Find.AreaHome.ActiveCells.Where(cell => (cell.GetZone() == null || cell.IsValidStorageFor(cart)) && cell.Standable() && cell.GetEdifice() == null)) * if (cell.DistanceToSquared(cart.Position) < NearbyCell) * storeCell = cell; */ ReservationUtility.Reserve(actor, storeCell); toil.actor.jobs.curJob.targetB = (storeCell != invalid && storeCell != IntVec3.Invalid) ? storeCell : cart.Position; }; return(toil); }