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 bool AvailableCart(Vehicle_Cart cart, Pawn pawn) { return(!cart.TryGetComp <CompMountable>().IsMounted || cart.TryGetComp <CompMountable>().Driver == pawn); }
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 bool AvailableCart(Vehicle_Cart cart, Pawn pawn) { return (!cart.TryGetComp<CompMountable>().IsMounted || cart.TryGetComp<CompMountable>().Driver == pawn); }
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 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); }