protected override IEnumerable<Toil> MakeNewToils()
        {
            //Set what will cause the job to fail:
            this.FailOnDestroyedOrForbidden(CorpseIndex);
            this.FailOnBurningImmobile(CorpseIndex);
            this.FailOn(() => !(pawn is Droid));

            //Reserve the corpse
            yield return Toils_Reserve.Reserve(CorpseIndex);
            //Go to the corpse
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);
            Toil toil = new Toil();
            toil.initAction = () =>
                {
                    //Check if the pawn is set to strip bodies, if yes then strip it, otherwise skip this step
                    Droid droid = (Droid)pawn;
                    CremationWorker worker = droid.work.specialist.GetWorker<CremationWorker>();
                    if (worker.StripBodies)
                    {
                        Corpse corpse = (Corpse)TargetThingA;
                        if (corpse.AnythingToStrip())
                            corpse.Strip();
                    }
                };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration = 300;
            toil.WithEffect(() => DefDatabase<EffecterDef>.GetNamed("Cremate"), CorpseIndex);
            toil.WithSustainer(() => DefDatabase<SoundDef>.GetNamed("Recipe_Cremate"));
            toil.AddFinishAction(() => TargetA.Thing.Destroy());
            toil.FailOnBurningImmobile(CorpseIndex);
            toil.FailOnDestroyedOrForbidden(CorpseIndex);
            toil.AddEndCondition(() => this.ticksLeftThisToil <= 0 ? JobCondition.Succeeded : JobCondition.Ongoing);
            yield return toil;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Set what will cause the job to fail:
            this.FailOnDestroyedOrForbidden(CorpseIndex);
            this.FailOnBurningImmobile(CorpseIndex);
            this.FailOn(() => !(pawn is Droid));

            //Reserve the corpse
            yield return(Toils_Reserve.Reserve(CorpseIndex));

            //Go to the corpse
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch));

            Toil toil = new Toil();

            toil.initAction = () =>
            {
                //Check if the pawn is set to strip bodies, if yes then strip it, otherwise skip this step
                Droid           droid  = (Droid)pawn;
                CremationWorker worker = droid.work.specialist.GetWorker <CremationWorker>();
                if (worker.StripBodies)
                {
                    Corpse corpse = (Corpse)TargetThingA;
                    if (corpse.AnythingToStrip())
                    {
                        corpse.Strip();
                    }
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = 300;
            toil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("Cremate"), CorpseIndex);
            toil.WithSustainer(() => DefDatabase <SoundDef> .GetNamed("Recipe_Cremate"));
            toil.AddFinishAction(() => TargetA.Thing.Destroy());
            toil.FailOnBurningImmobile(CorpseIndex);
            toil.FailOnDestroyedOrForbidden(CorpseIndex);
            toil.AddEndCondition(() => this.ticksLeftThisToil <= 0 ? JobCondition.Succeeded : JobCondition.Ongoing);
            yield return(toil);
        }
Example #3
0
        public static void Postfix(Toil __result, TargetIndex cellInd)
        {
            Utils.Warn(PlaceHauledThingInCell, "Starting new haul job, toils created");

            //TODO?  Make a wrapper around old initAction that doesn't put
            //  stuff down if failure happens?

            var placeStuff = __result.initAction;

            // NOTE: none of this initAtion happens if the game is being loaded while storing is going on:
            //   This means, among other things, that pawns don't get progress bars on reload
            //   I could make it happen if it ever gets to be important...
            __result.initAction = delegate
            {
//                __result.defaultCompleteMode = ToilCompleteMode.Instant;
                var actor  = __result.actor;
                var curJob = actor.jobs.curJob;
                var cell   = curJob.GetTarget(cellInd).Cell;
                Utils.Warn(PlaceHauledThingInCell, "initAction called for " + actor + "'s haul job "
                           + curJob.def.driverClass + " to " + cell + " (toil " + actor.jobs.curDriver.CurToilIndex + ")");
                //                Log.Error("Place Hauled Thing in Cell:  Toil preInit!  Putting in "+cell.ToString());
                //                actor.jobs.debugLog = true;
                if (actor.carryTracker.CarriedThing == null)
                {
                    // error as per original toil code
                    Log.Error(actor + " tried to place hauled thing in cell but is not hauling anything?");
                    return;
                }

                var             slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
                CompDeepStorage cds;
                if (!(slotGroup?.parent is ThingWithComps) ||
                    (cds = ((ThingWithComps)slotGroup?.parent)?.GetComp <CompDeepStorage>()) == null)
                {
                    Utils.Warn(PlaceHauledThingInCell, "not going into Deep Storage");
                    // Pick Up & Haul reuses Toils; I realized this meant I need to keep original placeStuff() around:
                    // Also, is it possible another mod does something weird with placeStuff?
                    //   this is a cheap "just to be on the safe side" check:
                    if (placeStuff != null)
                    {
                        placeStuff();
                    }
                    return;
                }

                var timeStoringTakes = cds.TimeStoringTakes(actor.Map, cell, actor);
                timeStoringTakes = (int)(timeStoringTakes * Settings.storingGlobalScale);
                if (timeStoringTakes <= 1 ||
                    !Settings.storingTakesTime)    //boo, hiss, but some ppl use it
                {
                    // just like vanilla
                    Utils.Warn(PlaceHauledThingInCell, "Instantaneous storing time");
                    if (placeStuff != null)
                    {
                        placeStuff();
                    }
                    return;
                }

//                __result.defaultCompleteMode = ToilCompleteMode.Delay;
                if (actor.jobs.curDriver.ticksLeftThisToil < 1) // test is probably superfluous
                {
                    actor.jobs.curDriver.ticksLeftThisToil = timeStoringTakes;
                }
                Utils.Mess(PlaceHauledThingInCell, "  Storing time set to: " + actor.jobs.curDriver.ticksLeftThisToil);
                // It'd be nice to have a progress bar for deep storage
                __result.WithProgressBar(TargetIndex.B, () => 1f -
                                         (float)__result.actor.jobs.curDriver.ticksLeftThisToil / timeStoringTakes, true);

                /***** Add some end conditions: *****/
                //TODO: .....is this even a good idea?  if the pawn is moving a lot of things at once
                //   (I'm looking at you Mehni's Pick Up and Haul), this could break the entire chain.
                // TODO: Replace this with a check MUCH earlier.  And one right before actual placement
                //    takes place.

/*                Thing t = actor.CurJob.GetTarget(TargetIndex.A).Thing;
 *              if (t != null)
 *                  __result.FailOn(() => !slotGroup.parent.Accepts(t));
 */
                //TODO: Find a way to track the end condition? Remove it?
                //  Or just make it complicated :p
//                __result.FailOn(delegate() {});
                // TODO: any other end conditions?  Fail conditions?
                // TODO: Any reservations?
            }; // changed initAction!
            __result.defaultCompleteMode = ToilCompleteMode.Delay;
            // The tickAction is only called if we are going into Deep Storage,
            //   otherwise the toil is over after initAction and no ticks happen.
            // This will still get called even on load/save, because ticks count down.
            __result.tickAction = delegate
            {
                var pawn = __result.actor;
                //Utils.Mess(PlaceHauledThingInCell,
                //           "  "+pawn+"'s ticks left: " + __result.actor.jobs.curDriver.ticksLeftThisToil);
                if (pawn.jobs.curDriver.ticksLeftThisToil <= 1) // last tick is 1, not 0
                {
                    Utils.Warn(PlaceHauledThingInCell, "  " + pawn + " hit " + pawn.jobs.curDriver.ticksLeftThisToil +
                               " ticks; about to put down " + (pawn.carryTracker.CarriedThing != null
                                                           ? "" + pawn.carryTracker.CarriedThing.stackCount +
                                                               pawn.carryTracker.CarriedThing
                                                           : "NULL ITEM"));
                    if (placeStuff != null)
                    {
                        placeStuff();
                    }
                }

                /*
                 * if (pawn.jobs.curDriver.ticksLeftThisToil%50==0) {
                 *  // TODO: fail conditions
                 *  ...etc...
                 *  pawn.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                 * }
                 */
            };

            // ToilCompleteMode.Delay is acceptable in vanilla case, as duration is 0:

//            __result.defaultDuration = 0; // changed by PreInitAction, if needed
            // This is okay: it checks the current TargetIndex.B
            __result.FailOnBurningImmobile(TargetIndex.B);

            // todo reservations (possibly?)
            // also todo, undo reservations (possibly?) (as another final action?)

            // TODO: FailOn&c, EndOn&c
            //  Other fails.....
            //    No longer allowed in that area?  <--- Very definitely TODO
            //    Um?
        } // end Postfix
Example #4
0
        public static void Postfix(Toil __result, TargetIndex cellInd)
        {
            // make the "initAction" a final action:
            //TODO::::  Make a wrapper around old initAction that doesn't put
            //  stuff down if failure happens?

//            __result.preInitActions.Add(delegate () { __result.actor.jobs.debugLog = true; });
//            __result.AddFinishAction(__result.initAction);
            // replace it with a test for Deep Storage
            //   and if it IS deep storage, set up wait:
            Action placeStuff = __result.initAction;

            __result.AddPreInitAction(delegate() {
                __result.tickAction = null;
                Pawn actor          = __result.actor;
                Job curJob          = actor.jobs.curJob;
                IntVec3 cell        = curJob.GetTarget(cellInd).Cell;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(actor + " tried to place hauled thing in cell but is not hauling anything?", false);
                    return;
                }
                SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
                ThingComp comp;
                if (slotGroup == null || !(slotGroup?.parent is ThingWithComps) ||
                    (comp = ((ThingWithComps)slotGroup.parent).TryGetComp <CompDeepStorage>()) == null)
                {
                    __result.initAction = placeStuff;
                    return;
                }
                int timeStoringTakes = ((LWM.DeepStorage.Properties)comp.props).timeStoringTakes;
                if (timeStoringTakes <= 0)   // just like vanilla
                {
                    __result.initAction = placeStuff;
                    return;
                }

                __result.initAction = null;
                __result.tickAction = delegate() {
                    if (actor.jobs.curDriver.ticksLeftThisToil == 1) // last tick is 1, not 0
                    {
                        placeStuff();
                    }
                };

                actor.jobs.curDriver.ticksLeftThisToil = timeStoringTakes;

                __result.WithProgressBar(TargetIndex.B, () => 1f -
                                         (float)__result.actor.jobs.curDriver.ticksLeftThisToil / timeStoringTakes, true);
                Thing t = actor.CurJob.GetTarget(TargetIndex.A).Thing;

                // Add some end conditions:
                if (t != null)
                {
                    __result.FailOn(() => !slotGroup.parent.Accepts(t));
                }
            }); // added pre-init action!

            // HMM...let's get rid of stuff:
            __result.initAction          = null;
            __result.atomicWithPrevious  = false;
            __result.defaultCompleteMode = ToilCompleteMode.Delay;
            __result.defaultDuration     = 0; // changed by initAction, if needed
            __result.FailOnBurningImmobile(TargetIndex.B);

            // TODO: FailOn&c, EndOn&c
            //  Other fails.....
            //    No longer allowed in that area?
            //    No longer accepts what we're puttin there?
            //    Um?
        } // end Postfix
        public static void Postfix(Toil __result, TargetIndex cellInd)
        {
            Utils.Err(PlaceHauledThingInCell, "Starting new haul job, toils created");
            //TODO?  Make a wrapper around old initAction that doesn't put
            //  stuff down if failure happens?

            SlotGroup groupAt = __result?.actor?.Map?.haulDestinationManager?.SlotGroupAt(__result.actor?.CurJob?.GetTarget(cellInd).Cell ?? IntVec3.Invalid);

            if ((groupAt?.parent as ThingWithComps)?.GetComp <CompDeepStorage>() == null)
            {
                Utils.Err(PlaceHauledThingInCell, "Not going into Deep Storage, exiting ASAP without modifying anything.");
                return;
            }

            Action placeStuff = __result.initAction;

            // NOTE: none of this PreInitAtion happens if the game is being loaded while storing is going on:
            //   This means, among other things, that pawns don't get progress bars on reload
            //   I could make it happen if it ever gets to be important...
            __result.AddPreInitAction(delegate()
            {
                Pawn actor   = __result.actor;
                Job curJob   = actor.jobs.curJob;
                IntVec3 cell = curJob.GetTarget(cellInd).Cell;
                Utils.Err(PlaceHauledThingInCell, "PreInitAction called for " + actor + "'s haul job " + curJob.def.driverClass + " to " + cell);
                //                Log.Error("Place Hauled Thing in Cell:  Toil preInit!  Putting in "+cell.ToString());
                //                actor.jobs.debugLog = true;
                if (actor.carryTracker.CarriedThing == null)
                { // error as per original toil code
                    Log.Error(actor + " tried to place hauled thing in cell but is not hauling anything?", false);
                    return;
                }
                SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
                CompDeepStorage cds;
                if (!(slotGroup?.parent is ThingWithComps) ||
                    (cds = (((ThingWithComps)slotGroup?.parent)?.GetComp <CompDeepStorage>())) == null)
                {
                    Utils.Warn(PlaceHauledThingInCell, "not going into Deep Storage");
                    return; // initAction still around, will handle
                }
                int timeStoringTakes = cds.timeStoringTakes(cell);
                if (timeStoringTakes <= 0)
                { // just like vanilla
                    Utils.Warn(PlaceHauledThingInCell, "Instantaneous storing time");
                    return;
                }
                // Remove the initAction so it doesn't happen before waiting starts:
                __result.initAction = null;
                if (actor.jobs.curDriver.ticksLeftThisToil < 1) // test is probably superfluous
                {
                    actor.jobs.curDriver.ticksLeftThisToil = timeStoringTakes;
                }
                // It'd be nice to have a progress bar for deep storage
                __result.WithProgressBar(TargetIndex.B, () => 1f -
                                         (float)__result.actor.jobs.curDriver.ticksLeftThisToil / timeStoringTakes, true);

                /***** Add some end conditions: *****/

                Thing t = actor.CurJob.GetTarget(TargetIndex.A).Thing;
                if (t != null)
                {
                    __result.FailOn(() => !slotGroup.parent.Accepts(t));
                }

                // TODO: any other end conditions?  Fail conditions?
                // TODO: Any reservations?
            }); // added pre-init action!

            // The tickAction is only called if we are going into Deep Storage,
            //   otherwise the toil is over after initAction and no ticks happen.
            // This will still get called even on load/save, because ticks count down.
            __result.tickAction = delegate()
            {
                Pawn pawn = __result.actor;
                Utils.Warn(PlaceHauledThingInCell,
                           "  " + pawn + "'s ticks left: " + __result.actor.jobs.curDriver.ticksLeftThisToil);
                if (pawn.jobs.curDriver.ticksLeftThisToil <= 1) // last tick is 1, not 0
                {
                    Utils.Err(PlaceHauledThingInCell, "Hit 0 ticks");
                    placeStuff();
                }
            };

            // ToilCompleteMode.Delay is acceptable in vanilla case, as duration is 0:
            __result.defaultCompleteMode = ToilCompleteMode.Delay;
            __result.defaultDuration     = 0; // changed by PreInitAction, if needed
            __result.FailOnBurningImmobile(TargetIndex.B);

            // todo reservations (possibly?)
            // also todo, undo reservations (possibly?) (as another final action?)

            // TODO: FailOn&c, EndOn&c
            //  Other fails.....
            //    No longer allowed in that area?  <--- Very definitely TODO
            //    Um?
        } // end Postfix