示例#1
0
        public override bool TryMakePreToilReservations(bool errorOnFailed)
        {
            Pawn            pawn           = base.pawn;
            LocalTargetInfo target         = base.job.GetTarget(TargetIndex.B);
            Job             job            = base.job;
            bool            errorOnFailed2 = errorOnFailed;
            bool            result         = false;

            if (!target.Cell.IsValidStorageFor(pawn.Map, pawn.carryTracker.CarriedThing))
            {
                StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(TargetThingA);
                if (!StoreUtility.TryFindBestBetterStorageFor(TargetThingA, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
                {
                    return(false);
                }
            }


            if (pawn.Reserve(target, job, 1, -1, null, errorOnFailed2))
            {
                pawn           = base.pawn;
                target         = base.job.GetTarget(TargetIndex.A);
                job            = base.job;
                errorOnFailed2 = errorOnFailed;
                result         = pawn.Reserve(target, job, 1, -1, null, errorOnFailed2);
            }
            Log.Message("Make Reservation result: " + result);
            return(result);
        }
        public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority  currentPriority = StoreUtility.CurrentStoragePriorityOf(t);
            IntVec3          storeCell;
            IHaulDestination haulDestination;
            Job result;

            if (!StoreUtility.TryFindBestBetterStorageFor(t, p, p.Map, currentPriority, p.Faction, out storeCell, out haulDestination, true))
            {
                JobFailReason.Is(HaulAIUtility.NoEmptyPlaceLowerTrans, null);
                result = null;
            }
            else if (haulDestination is ISlotGroupParent)
            {
                result = HaulAIUtility.HaulToCellStorageJob(p, t, storeCell, false);
            }
            else
            {
                Thing thing = haulDestination as Thing;
                if (thing != null && thing.TryGetInnerInteractableThingOwner() != null)
                {
                    result = HaulAIUtility.HaulToContainerJob(p, t, thing);
                }
                else
                {
                    Log.Error("Don't know how to handle HaulToStorageJob for storage " + haulDestination.ToStringSafe <IHaulDestination>() + ". thing=" + t.ToStringSafe <Thing>(), false);
                    result = null;
                }
            }
            return(result);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.A);
            yield return(Toils_Reserve.Reserve(TargetIndex.A));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_General.WaitWith(TargetIndex.A, 200, true));

            yield return(new Toil()
            {
                initAction = delegate()
                {
                    Building_GrowerBase grower = TargetThingA as Building_GrowerBase;
                    if (grower != null)
                    {
                        Pawn actor = GetActor();
                        Thing product = grower.ExtractProduct(actor);
                        if (!product.Spawned)
                        {
                            GenPlace.TryPlaceThing(product, grower.InteractionCell, grower.Map, ThingPlaceMode.Near);
                        }

                        if (product is Pawn)
                        {
                            EndJobWith(JobCondition.Succeeded);
                        }
                        else
                        {
                            //job.SetTarget(TargetIndex.B, product);
                            IntVec3 storeCell;
                            IHaulDestination haulDestination;
                            if (StoreUtility.TryFindBestBetterStorageFor(product, actor, product.Map, StoragePriority.Unstored, actor.Faction, out storeCell, out haulDestination, false))
                            {
                                if (storeCell.IsValid || haulDestination != null)
                                {
                                    actor.jobs.StartJob(HaulAIUtility.HaulToStorageJob(actor, product), JobCondition.Succeeded);
                                }
                            }
                        }
                    }
                }
            });
        }
        /// <inheritdoc/>
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            if (pawn?.inventory?.innerContainer == null)
            {
                return(ThinkResult.NoJob);
            }

            if (!pawn.UseLoadout(out CompAwesomeInventoryLoadout comp))
            {
                return(ThinkResult.NoJob);
            }

            foreach (Thing thing in pawn.inventory.innerContainer)
            {
                if (thing is Apparel apparel)
                {
                    bool extra = true;
                    CompAwesomeInventoryLoadout.ThingGroupSelectorPool pool = comp.FindPotentialThingGroupSelectors(thing, comp.Loadout);
                    if (pool.OrderedSelectorTuples.Any())
                    {
                        foreach (var tuple in pool.OrderedSelectorTuples)
                        {
                            if (!(comp.InventoryMargins[tuple.Item2] > 0))
                            {
                                extra = false;
                                break;
                            }
                        }
                    }

                    if (extra)
                    {
                        if (StoreUtility.TryFindBestBetterStorageFor(apparel, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(apparel), pawn.Faction, out _, out _))
                        {
                            UnloadApparelJob job = new UnloadApparelJob(thing);
                            return(new ThinkResult(job, this, JobTag.UnloadingOwnInventory));
                        }
                    }
                }
            }

            return(ThinkResult.NoJob);
        }
示例#5
0
        public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(t);

            if (!StoreUtility.TryFindBestBetterStorageFor(t, p, p.Map, currentPriority, p.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
            {
                JobFailReason.Is(NoEmptyPlaceLowerTrans);
                return(null);
            }
            if (haulDestination is ISlotGroupParent)
            {
                return(HaulToCellStorageJob(p, t, foundCell, fitInStoreCell: false));
            }
            Thing thing = haulDestination as Thing;

            if (thing != null && thing.TryGetInnerInteractableThingOwner() != null)
            {
                return(HaulToContainerJob(p, t, thing));
            }
            Log.Error("Don't know how to handle HaulToStorageJob for storage " + haulDestination.ToStringSafe() + ". thing=" + t.ToStringSafe());
            return(null);
        }
        /// <summary>
        /// Make reservation for job targets before doing the job.
        /// </summary>
        /// <param name="errorOnFailed"> If true, log result as error if failed to make a reservation. </param>
        /// <returns> Returns true if a reservation is made. </returns>
        public override bool TryMakePreToilReservations(bool errorOnFailed)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(TargetThingA);

            if (!StoreUtility.TryFindBestBetterStorageFor(TargetThingA, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
            {
                JobFailReason.Is(UIText.NoEmptyPlaceLower);
                Messages.Message(
                    UIText.NoEmptyPlaceLower.TranslateSimple()
                    , new TargetInfo(this.pawn.PositionHeld, this.pawn.MapHeld), MessageTypeDefOf.NeutralEvent);
                return(false);
            }

            this.Init(foundCell, haulDestination);

            if (pawn.Reserve(TargetB, this.job, 1, -1, null, errorOnFailed))
            {
                return(pawn.Reserve(TargetA, this.job, 1, -1, null, errorOnFailed));
            }

            return(false);
        }
        private Toil Collect()
        {
            return(new Toil()
            {
                initAction = delegate
                {
                    // Increment the record for how many cells this pawn has mined since this counts as mining
                    // TODO: B19 - change to quarry m3
                    pawn.records.Increment(RecordDefOf.CellsMined);

                    // Start with None to act as a fallback. Rubble will be returned with this parameter
                    ResourceRequest req = ResourceRequest.None;

                    // Use the mineModeToggle to determine the request
                    req = (ResourceRequest)(((int)Quarry.mineModeToggle) + 1);

                    MoteType mote = MoteType.None;
                    int stackCount = 1;

                    // Get the resource from the quarry
                    ThingDef def = Quarry.GiveResources(req, out mote, out bool singleSpawn, out bool eventTriggered);
                    // If something went wrong, bail out
                    if (def == null || def.thingClass == null)
                    {
                        Log.Warning("Quarry:: Tried to quarry mineable ore, but the ore given was null.");
                        mote = MoteType.None;
                        singleSpawn = true;
                        // This shouldn't happen at all, but if it does let's add a little reward instead of just giving rubble
                        def = ThingDefOf.ChunkSlagSteel;
                    }

                    Thing haulableResult = ThingMaker.MakeThing(def);
                    if (!singleSpawn && def != ThingDefOf.ComponentIndustrial)
                    {
                        int sub = (int)(def.BaseMarketValue / 2f);
                        sub = Mathf.Clamp(sub, 0, 10);

                        stackCount += Mathf.Min(Rand.RangeInclusive(15 - sub, 40 - (sub * 2)), def.stackLimit - 1);
                    }

                    if (def == ThingDefOf.ComponentIndustrial)
                    {
                        stackCount += Random.Range(0, 1);
                    }

                    haulableResult.stackCount = stackCount;

                    if (stackCount >= 30)
                    {
                        mote = MoteType.LargeVein;
                    }

                    bool usesQuality = false;
                    // Adjust quality for items that use it
                    if (haulableResult.TryGetComp <CompQuality>() != null)
                    {
                        usesQuality = true;
                        haulableResult.TryGetComp <CompQuality>().SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider);
                    }
                    // Adjust hitpoints, this was just mined from under the ground after all
                    if (def.useHitPoints && !def.thingCategories.Contains(QuarryDefOf.StoneChunks) && def != ThingDefOf.ComponentIndustrial)
                    {
                        float minHpThresh = 0.25f;
                        if (usesQuality)
                        {
                            minHpThresh = Mathf.Clamp((float)haulableResult.TryGetComp <CompQuality>().Quality / 10f, 0.1f, 0.7f);
                        }
                        int hp = Mathf.RoundToInt(Rand.Range(minHpThresh, 1f) * haulableResult.MaxHitPoints);
                        hp = Mathf.Max(1, hp);
                        haulableResult.HitPoints = hp;
                    }

                    // Place the resource near the pawn
                    GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near);

                    // If the resource had a mote, throw it
                    if (mote == MoteType.LargeVein)
                    {
                        MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f);
                    }
                    else if (mote == MoteType.Failure)
                    {
                        MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f);
                    }

                    // If the sinkhole event was triggered, damage the pawn and end this job
                    // Even if the sinkhole doesn't incapacitate the pawn, they will probably want to seek medical attention
                    if (eventTriggered)
                    {
                        NamedArgument pawnName = new NamedArgument(0, pawn.NameShortColored);
                        Messages.Message("QRY_MessageSinkhole".Translate(pawnName), pawn, MessageTypeDefOf.NegativeEvent);
                        DamageInfo dInfo = new DamageInfo(DamageDefOf.Crush, 9, category: DamageInfo.SourceCategory.Collapse);
                        dInfo.SetBodyRegion(BodyPartHeight.Bottom, BodyPartDepth.Inside);
                        pawn.TakeDamage(dInfo);

                        EndJobWith(JobCondition.Succeeded);
                    }
                    else
                    {
                        // Prevent the colonists from trying to haul rubble, which just makes them visit the platform
                        if (def == ThingDefOf.Filth_RubbleRock)
                        {
                            EndJobWith(JobCondition.Succeeded);
                        }
                        else
                        {
                            // If this is a chunk or slag, mark it as haulable if allowed to
                            if (def.designateHaulable && Quarry.autoHaul)
                            {
                                Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul));
                            }

                            // Try to find a suitable storage spot for the resource, removing it from the quarry
                            // If there are no platforms with free space, or if the resource is a chunk, try to haul it to a storage area
                            if (Quarry.autoHaul)
                            {
                                if (!def.thingCategories.Contains(QuarryDefOf.StoneChunks) && Quarry.HasConnectedPlatform && Quarry.TryFindBestPlatformCell(haulableResult, pawn, Map, pawn.Faction, out IntVec3 c))
                                {
                                    job.SetTarget(TargetIndex.B, haulableResult);
                                    job.count = haulableResult.stackCount;
                                    job.SetTarget(TargetIndex.C, c);
                                }
                                else
                                {
                                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(haulableResult);
                                    Job result;
                                    if (!StoreUtility.TryFindBestBetterStorageFor(haulableResult, pawn, Map, currentPriority, pawn.Faction, out c, out IHaulDestination haulDestination, true))
                                    {
                                        JobFailReason.Is("NoEmptyPlaceLower".Translate(), null);
                                    }
                                    else if (haulDestination is ISlotGroupParent)
                                    {
                                        result = HaulAIUtility.HaulToCellStorageJob(pawn, haulableResult, c, false);
                                    }
                                    else
                                    {
                                        job.SetTarget(TargetIndex.B, haulableResult);
                                        job.count = haulableResult.stackCount;
                                        job.SetTarget(TargetIndex.C, c);
                                    }
                                }
                            }
示例#8
0
 private bool HasNoHaulDestination(Thing t)
 {
     return(!StoreUtility.TryFindBestBetterStorageFor(t, null, t.Map, StoreUtility.CurrentStoragePriorityOf(t),
                                                      Faction.OfPlayer, out IntVec3 _, out IHaulDestination _));
 }
示例#9
0
        // Token: 0x0600005B RID: 91 RVA: 0x00004104 File Offset: 0x00002304
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var   toilSwapback    = new Toil();
            var   toilReturnStock = new Toil();
            var   toilDrop        = new Toil();
            var   toilDropHome    = new Toil();
            Thing resultingThing  = null;
            var   FETakeBack      = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
            var   FETBSwapType    = (FETakeBack as FireWardenData)?.FWSwapType;
            var   DebugMsg        = "";

            toilSwapback.initAction = delegate
            {
                if (!FWHasFE(pawn) || resultingThing == null)
                {
                    return;
                }

                if (FWDebug)
                {
                    DebugMsg = pawn.Label + " in toil Swapback";
                    Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
                }

                if (job.GetTarget(TargetIndex.B) != null)
                {
                    var RemoveThing    = job.GetTarget(TargetIndex.B).Thing;
                    var invGearToEquip = (ThingWithComps)RemoveThing;
                    if (pawn.inventory.innerContainer.Contains(RemoveThing) && pawn.equipment.Primary != invGearToEquip)
                    {
                        pawn.inventory.innerContainer.Remove(RemoveThing);
                        pawn.equipment.MakeRoomFor(invGearToEquip);
                        pawn.equipment.AddEquipment(invGearToEquip);
                    }
                }

                FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                FEResetVars(FETakeBack);
                FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
            };
            toilSwapback.AddFailCondition(() => FETBSwapType != "ER");
            toilSwapback.FailOnDespawnedOrNull(TargetIndex.A);
            toilSwapback.FailOnDespawnedOrNull(TargetIndex.B);
            toilSwapback.defaultCompleteMode = ToilCompleteMode.Delay;
            yield return(toilSwapback);

            if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.defName != FEDefName ||
                (pawn.equipment.Primary as FireWardenData)?.FWSwapType != "ER" ||
                ((FireWardenData)pawn.equipment.Primary).FWPawnID != pawn.thingIDNumber)
            {
                yield break;
            }

            var currentPriority = StoreUtility.CurrentStoragePriorityOf(job.GetTarget(TargetIndex.A).Thing);
            var dumpAtHome      = false;

            if (Controller.Settings.ReturnToSpot)
            {
                dumpAtHome = true;
            }
            else
            {
                if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
                {
                    pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
                    pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
                }

                if (!StoreUtility.TryFindBestBetterStorageFor(job.GetTarget(TargetIndex.A).Thing, pawn, pawn.Map,
                                                              currentPriority, pawn.Faction, out _, out var haulDestination))
                {
                    dumpAtHome = true;
                }
                else
                {
                    toilReturnStock.initAction = delegate
                    {
                        if (FWDebug)
                        {
                            DebugMsg = pawn.Label + " in toil ReturnStock";
                            Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
                        }

                        if (pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing)
                        {
                            return;
                        }

                        var destCell = haulDestination.Position;
                        pawn.Map.pawnDestinationReservationManager.Reserve(pawn, job, destCell);
                        pawn.pather.StartPath(destCell, PathEndMode.ClosestTouch);
                    };
                    toilReturnStock.AddFailCondition(() => FETBSwapType != "ER");
                    toilReturnStock.FailOnDespawnedOrNull(TargetIndex.A);
                    toilReturnStock.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                    yield return(toilReturnStock);

                    toilDrop.initAction = delegate
                    {
                        if (!((haulDestination.Position - pawn.Position).LengthHorizontal <= 2f))
                        {
                            return;
                        }

                        if (pawn.carryTracker.CarriedThing == job.GetTarget(TargetIndex.A).Thing)
                        {
                            if (!pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near,
                                                                       out resultingThing))
                            {
                                return;
                            }

                            dumpAtHome = false;
                            if (job.GetTarget(TargetIndex.B) != null)
                            {
                                return;
                            }

                            FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                            FEResetVars(FETakeBack);
                            FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                            pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                        }
                        else
                        {
                            dumpAtHome = true;
                        }
                    };
                    toilSwapback.AddFailCondition(() => FETBSwapType != "ER");
                    toilDrop.FailOnDespawnedOrNull(TargetIndex.A);
                    toilDrop.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                    yield return(toilDrop);
                }
            }

            if (!dumpAtHome)
            {
                yield break;
            }

            var ReturnCell = pawn.Position;

//            if (false)
//            {
//                /*
//                            {
//                                toilReturnHome.initAction = delegate
//                                {
//                                    if (FWDebug)
//                                    {
//                                        DebugMsg = pawn.Label + " in toil ReturnHome";
//                                        Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
//                                    }
//                                    if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
//                                    {
//                                        pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
//                                        pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
//                                    }
//
//                                    if (pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing)
//                                    {
//                                        return;
//                                    }
//
//                                    pawn.Map.pawnDestinationReservationManager.Reserve(pawn, job, ReturnCell);
//                                    pawn.pather.StartPath(ReturnCell, PathEndMode.ClosestTouch);
//                                };
//                                toilReturnHome.AddFailCondition(() => FETBSwapType != "ER");
//                                toilReturnHome.FailOnDespawnedOrNull(TargetIndex.A);
//                                toilReturnHome.defaultCompleteMode = ToilCompleteMode.PatherArrival;
//                                yield return toilReturnHome;
//                            }
//                */
//            }
            if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
            {
                pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
                pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
            }

            toilDropHome.initAction = delegate
            {
                if (!((ReturnCell - pawn.Position).LengthHorizontal <= 2f) ||
                    pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing ||
                    !pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out resultingThing) ||
                    job.GetTarget(TargetIndex.B) != null)
                {
                    return;
                }

                FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                FEResetVars(FETakeBack);
                FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
            };
            toilDropHome.AddFailCondition(() => FETBSwapType != "ER");
            toilDropHome.FailOnDespawnedOrNull(TargetIndex.A);
            toilDropHome.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
            yield return(toilDropHome);
        }