コード例 #1
0
        /// <summary>Makes the new toils.</summary>
        /// <returns></returns>
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.B);
            this.FailOnAggroMentalState(TargetIndex.A);
            this.FailOn(() => !this.MutagenicChamber.Accepts(this.Takee));
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOn(() => this.MutagenicChamber.GetDirectlyHeldThings().Count > 0).FailOn(() => !this.Takee.Downed).FailOn(() => !this.pawn.CanReach(this.Takee, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(Toils_General.Wait(60).WithProgressBarToilDelay(TargetIndex.A));

            Toil toil2 = new Toil();

            toil2.initAction = delegate
            {
                Thing thing = job.targetA.Thing;
                base.Map.designationManager.DesignationOn(thing, DesignationDefOf.Strip)?.Delete();
                (thing as IStrippable)?.Strip();
                pawn.records.Increment(RecordDefOf.BodiesStripped);
            };
            toil2.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(toil2);

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false));

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

            Toil prepare = Toils_General.Wait(500, TargetIndex.None);

            prepare.FailOnCannotTouch(TargetIndex.B, PathEndMode.InteractionCell);
            prepare.WithProgressBarToilDelay(TargetIndex.B, false, -0.5f);
            yield return(prepare);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    Takee?.Strip();
                    this.MutagenicChamber.TryAcceptThing(this.Takee, true);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield break;
        }
コード例 #2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Reserve the takee
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

            //Reserve the bed
            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1));

            //Claim the bed for the takee
            Toil claimBed = new Toil();

            claimBed.initAction = () =>
            {
                if (Takee.ownership != null && Takee.ownership.OwnedBed != DropBed && !DropBed.Medical)
                {
                    Takee.ownership.ClaimBedIfNonMedical((Building_Bed)DropBed);
                }
            };
            yield return(claimBed);

            Func <bool> ownershipFail = () =>
            {
                if (DropBed.Medical)
                {
                    if (DropBed.AnyUnownedSleepingSlot &&
                        DropBed.CurOccupants != Takee)
                    {
                        return(true);
                    }
                }
                else if (DropBed.owners != null && !DropBed.owners.Contains(Takee))
                {
                    return(true);
                }
                return(false);
            };

            //Goto takee
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch)
                         .FailOnDestroyedNullOrForbidden(TargetIndex.A)
                         .FailOnDestroyedNullOrForbidden(TargetIndex.B)
                         .FailOn(ownershipFail)                                                              //Abandon if takee loses bed ownership
                         .FailOn(() => this.job.def == JobDefOf.Arrest && !Takee.CanBeArrestedBy(this.pawn)) //Abandon arrest if takee is not of a team who is willing to be arrested
                         .FailOn(() => !pawn.CanReach(DropBed, PathEndMode.OnCell, Danger.Deadly)));

            //.FailOn(()=>!pawn.CanReach( DropBed, PathEndMode.OnCell, Danger.Deadly ) ); // From Alpha 8

            //Make unconscious if needed
            Toil makeUnconscious = new Toil();

            makeUnconscious.initAction = () =>
            {
                //Log.Error("Applying Anesthetic");
                //Takee.healthTracker.ApplyAnesthetic(); Does not work with AIPawn

                Takee.health.forceIncap = true;
                Takee.health.AddHediff(HediffDefOf.Anesthetic, null, null);
                Takee.health.forceIncap = false;
            };
            yield return(makeUnconscious);

            //Start carrying the takee
            yield return(Toils_Haul.StartCarryThing(TargetIndex.A));

            //Change takee to prisoner if necessary
            Toil makePrisoner = new Toil();

            makePrisoner.initAction = () =>
            {
                if (this.job.def == JobDefOf.Arrest || this.job.def == JobDefOf.Capture || this.job.def == JobDefOf.TakeWoundedPrisonerToBed)
                {
                    if (Takee.HostFaction != Faction.OfPlayer)
                    {
                        Takee.guest.SetGuestStatus(Faction.OfPlayer, true);
                    }
                }
            };
            yield return(makePrisoner);

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch)
                         .FailOnDestroyedNullOrForbidden(TargetIndex.A));

            //Note no failure conditions here
            //Because otherwise it's easy to get wardens to drop prisoners in arbitrary places.
            //I'd rather they just go to wherever they were going.
            // if( DropBed.owner != Takee )
            //	return true;
            //return !Toils.CanInteractStandard(DropBed);


            //Unreserve bed so takee can use it
            yield return(Toils_Reserve.Release(TargetIndex.B));


            //Drop in or near bed
            Toil tuckIntoBed = new Toil();

            tuckIntoBed.initAction = () =>
            {
                //Note: We don't stop the task if the bed is destroyed or changes ownership
                //because then the wardens drop prisoners at random points and they escape
                //So we have to handle some ugly cases here

                //note this may use the position of a destroyed bed
                IntVec3 dropPos = DropBed.Position;

                Thing unused;
                pawn.carryTracker.TryDropCarriedThing(dropPos, ThingPlaceMode.Direct, out unused);

                //Should we tuck them into bed?
                if ((Takee.Downed || Takee.health.HasHediffsNeedingTend(false) || ((HealthAIUtility.ShouldSeekMedicalRest(Takee) || HealthAIUtility.ShouldBeTendedNow(Takee)) && DropBed.Medical)) &&
                    !DropBed.Destroyed &&
                    (DropBed.owners.Contains(Takee) || (DropBed.Medical && DropBed.AnyUnoccupiedSleepingSlot))      //They could have lost ownership and the last toil would continue
                    )
                {
                    Takee.jobs.Notify_TuckedIntoBed(DropBed);
                }

                if (Takee.IsPrisonerOfColony)
                {
                    LessonAutoActivator.TeachOpportunity(ConceptDefOf.PrisonerTab, Takee, OpportunityType.GoodToKnow);
                }
            };
            tuckIntoBed.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(tuckIntoBed);
        }
コード例 #3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.B);
            this.FailOnAggroMentalStateAndHostile(TargetIndex.A);
            this.FailOn(delegate
            {
                if (job.def.makeTargetPrisoner)
                {
                    if (!DropBed.ForPrisoners)
                    {
                        return(true);
                    }
                }
                else if (DropBed.ForPrisoners != Takee.IsPrisoner)
                {
                    return(true);
                }
                return(false);
            });
            yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.B, TargetIndex.A));

            base.AddFinishAction(delegate
            {
                if (job.def.makeTargetPrisoner && Takee.ownership.OwnedBed == DropBed && Takee.Position != RestUtility.GetBedSleepingSlotPosFor(Takee, DropBed))
                {
                    Takee.ownership.UnclaimBed();
                }
            });
            yield return(Toils_Goto.GotoThing(
                             TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOn(() =>
                                                                                                                                                                         job.def == JobDefOf.Arrest && Takee.CanBeArrestedBy(pawn)).FailOn(() =>
                                                                                                                                                                                                                                           pawn.CanReach(DropBed, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)).FailOn(() => job.def == JobDefOf.Rescue && !Takee.Downed).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(new Toil
            {
                initAction = delegate
                {
                    if (job.def.makeTargetPrisoner)
                    {
                        Pawn pawn = (Pawn)job.targetA.Thing;
                        Lord lord = pawn.GetLord();
                        if (lord != null)
                        {
                            lord.Notify_PawnAttemptArrested(pawn);
                        }
                        GenClamor.DoClamor(pawn, 10f, ClamorDefOf.Harm);
                        if (job.def == JobDefOf.Arrest && !pawn.CheckAcceptArrest(pawn))
                        {
                            pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        }
                    }
                }
            });

            Toil startCarrying = Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false).FailOnNonMedicalBedNotOwned(TargetIndex.B, TargetIndex.A);

            startCarrying.AddPreInitAction(new Action(CheckMakeTakeeGuest));
            yield return(startCarrying);

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch));

            yield return(new Toil
            {
                initAction = delegate
                {
                    CheckMakeTakeePrisoner();
                    if (Takee.playerSettings == null)
                    {
                        Takee.playerSettings = new Pawn_PlayerSettings(Takee);
                    }
                }
            });

            yield return(Toils_Reserve.Release(TargetIndex.B));

            yield return(new Toil
            {
                initAction = delegate
                {
                    IntVec3 position = DropBed.Position;
                    Thing thing;
                    pawn.carryTracker.TryDropCarriedThing(position, ThingPlaceMode.Direct, out thing, null);
                    //if (!DropBed.Destroyed && (DropBed.owners.Contains(Takee) || (DropBed.Medical && DropBed.AnyUnoccupiedSleepingSlot) || Takee.ownership == null))
                    if (!DropBed.Destroyed && (DropBed.OwnersForReading.Contains(Takee) || (DropBed.Medical && DropBed.AnyUnoccupiedSleepingSlot) || Takee.ownership == null))
                    {
                        Takee.jobs.Notify_TuckedIntoBed(DropBed);
                        if (Takee.RaceProps.Humanlike && job.def != JobDefOf.Arrest && !Takee.IsPrisonerOfColony)
                        {
                            Takee.relations.Notify_RescuedBy(pawn);
                        }
                        Takee.mindState.Notify_TuckedIntoBed();
                    }
                    if (Takee.IsPrisonerOfColony)
                    {
                        LessonAutoActivator.TeachOpportunity(ConceptDefOf.PrisonerTab, Takee, OpportunityType.GoodToKnow);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
コード例 #4
0
 private void CheckMakeTakeeGuest()
 {
     if (!job.def.makeTargetPrisoner && Takee.Faction != Faction.OfPlayer && Takee.HostFaction != Faction.OfPlayer && Takee.guest != null && !Takee.IsWildMan())
     {
         Takee.guest.SetGuestStatus(Faction.OfPlayer, false);
     }
 }