protected override IEnumerable <Toil> MakeNewToils() { Init(); yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue)); Toil cut = new Toil(); Plant plant = (Plant)Thing; CompHarvestableReagent reagent = Thing.TryGetComp <CompHarvestableReagent>(); cut.tickAction = delegate { Pawn actor = cut.actor; if (actor.skills != null) { actor.skills.Learn(DefDatabase <SkillDef> .GetNamed("Alchemy", true), xpPerTick, false); } float statValue = actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingSpeed"), true); float num = statValue; workDone += num; if (!reagent.IsSecondaryHarvest) { if (plant != null) { if (workDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingYield"), true)) { Vector3 loc = (pawn.DrawPos + plant.DrawPos) / 2f; MoteMaker.ThrowText(loc, Map, "TextMote_ReagentHarvestFailed".Translate(), 3.65f); } else { int num2 = plant.YieldNow(); if (num2 > 0) { Thing harvestedThing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null); harvestedThing.stackCount = num2; if (actor.Faction != Faction.OfPlayer) { harvestedThing.SetForbidden(true, true); } GenPlace.TryPlaceThing(harvestedThing, actor.Position, Map, ThingPlaceMode.Near, null); actor.records.Increment(DefDatabase <RecordDef> .GetNamed("ReagentsHarvested")); } } } plant.def.plant.soundHarvestFinish.PlayOneShot(actor); plant.PlantCollected(); workDone = 0f; ReadyForNextToil(); return; } } // Animal // Inanimate } else { if (workDone >= reagent.HarvestWork) { if (reagent.HarvestedThingDef != null) { if (actor.RaceProps.Humanlike && reagent.HarvestFailable && Rand.Value > actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingYield"), true)) { Vector3 loc = (pawn.DrawPos + reagent.parent.DrawPos) / 2f; MoteMaker.ThrowText(loc, Map, "TextMote_ReagentHarvestFailed".Translate(), 3.65f); } else { int num2 = reagent.YieldNow(); if (num2 > 0) { Thing harvestedThing = ThingMaker.MakeThing(reagent.HarvestedThingDef, null); harvestedThing.stackCount = num2; if (actor.Faction != Faction.OfPlayer) { harvestedThing.SetForbidden(true, true); } GenPlace.TryPlaceThing(harvestedThing, actor.Position, Map, ThingPlaceMode.Near, null); actor.records.Increment(DefDatabase <RecordDef> .GetNamed("ReagentsHarvested")); } } } if (plant != null) { plant.def.plant.soundHarvestFinish.PlayOneShot(actor); } reagent.ReagentCollected(actor); workDone = 0f; ReadyForNextToil(); return; } } }; cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); cut.defaultCompleteMode = ToilCompleteMode.Never; cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); if (!reagent.IsSecondaryHarvest) { if (plant != null) { cut.WithProgressBar(TargetIndex.A, () => workDone / plant.def.plant.harvestWork, true, -0.5f); cut.PlaySustainerOrSound(() => plant.def.plant.soundHarvesting); } // Animals } else { cut.WithProgressBar(TargetIndex.A, () => workDone / reagent.HarvestWork, true, -0.5f); if (plant != null) { cut.PlaySustainerOrSound(() => plant.def.plant.soundHarvesting); } } yield return(cut); Toil workDoneToil = WorkDoneToil(); if (workDoneToil != null) { yield return(workDoneToil); } yield return(Toils_Jump.Jump(initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { Toil toil = new Toil(); yield return(new Toil { initAction = delegate() { try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("-1 job.targetQueueB: " + target.Thing); ZLogger.Message("-1 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("-1 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("-1 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } ZLogger.Message("-1 toil.actor: " + toil.actor); ZLogger.Message("-1 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("-1 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("-1 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("-1 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("-1 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("-1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("-1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("-1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("-1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("-1 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("-1 job.targetQueueA: " + target.Thing); ZLogger.Message("-1 job.targetQueueA: " + target.Thing.Map); } } catch { } } }); AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; return((!(thing is Building) || thing.Spawned) ? JobCondition.Ongoing : JobCondition.Incompletable); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate { IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { Log.Message(this.pawn + " - 1 fail", true); return(true); } if (!billGiver.CurrentlyUsableForBills()) { Log.Message(this.pawn + " - 2 fail", true); return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); toil.initAction = delegate { if (job.targetQueueB != null && job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)job.bill; } } }; yield return(toil); yield return(new Toil { initAction = delegate() { ZLogger.Message("1 toil.actor: " + toil.actor); ZLogger.Message("1 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("1 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("1 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("1 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("1 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("1 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("1 job.targetQueueA: " + target.Thing); ZLogger.Message("1 job.targetQueueA: " + target.Thing.Map); ZLogger.Message("1 job.targetQueueA: " + target.Thing.stackCount); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("1 job.targetQueueB: " + target.Thing); ZLogger.Message("1 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("1 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("1 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); Toil extract = ExtractNextTargetFromQueue(TargetIndex.B); yield return(new Toil { initAction = delegate() { ZLogger.Message("2 toil.actor: " + toil.actor); ZLogger.Message("2 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("2 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("2 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("2 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("2 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("2 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("2 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("2 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("2 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("2 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("2 job.targetQueueA: " + target.Thing); ZLogger.Message("2 job.targetQueueA: " + target.Thing.Map); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("2 job.targetQueueB: " + target.Thing); ZLogger.Message("2 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("2 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("2 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch); yield return(new Toil { initAction = delegate() { ZLogger.Message("3 toil.actor: " + toil.actor); ZLogger.Message("3 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("3 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("3 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("3 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("3 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("3 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("3 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("3 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("3 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("3 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("3 job.targetQueueA: " + target.Thing); ZLogger.Message("3 job.targetQueueA: " + target.Thing.Map); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("3 job.targetQueueB: " + target.Thing); ZLogger.Message("3 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("3 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("3 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: true, subtractNumTakenFromJobCount: false, failIfStackCountLessThanJobCount: true)); yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget2, storageMode: false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinishRecipeAndStartStoringProduct()); if (!job.RecipeDef.products.NullOrEmpty() || !job.RecipeDef.specialProducts.NullOrEmpty()) { yield return(Toils_Reserve.Reserve(TargetIndex.B)); findPlaceTarget2 = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget2, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true)); Toil recount = new Toil(); recount.initAction = delegate { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { base.Map.resourceCounter.UpdateResourceCounts(); } }; yield return(recount); } }
protected override IEnumerable <Toil> MakeNewToils() { /* * * Toil Configurations * */ Toil prepareToSpin = new Toil(); prepareToSpin.initAction = delegate { if (Prey == null && Corpse == null) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (Prey.Dead) { this.pawn.CurJob.SetTarget(TargetIndex.A, Prey.Corpse); } }; Toil gotoBody = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); gotoBody.AddPreInitAction(new Action(delegate { this.pawn.ClearAllReservations(); this.pawn.Reserve(TargetA, this.job); //this.Map.physicalInteractionReservationManager.ReleaseAllForTarget(TargetA); //this.Map.physicalInteractionReservationManager.Reserve(this.GetActor(), TargetA); currentActivity = "Spinning Cocoon"; })); Toil spinDelay = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 500, initAction = delegate { currentActivity = "Spinning Cocoon"; } }; spinDelay.WithProgressBarToilDelay(TargetIndex.B); Toil spinBody = new Toil { initAction = delegate { //Log.Message("5"); var spinner = this.GetActor() as Spider; if (spinner != null) { Building_Cocoon newCocoon; Thing toLoad; IntVec3 newPosition; if (Prey.Dead) { toLoad = Prey.Corpse; newPosition = Prey.Corpse.Position; } else { toLoad = Prey; newPosition = Prey.Position; } if (!toLoad.Spawned) { this.EndJobWith(JobCondition.Incompletable); return; } toLoad.DeSpawn(); toLoad.holdingOwner = null; if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, newPosition, Rot4.North, this.pawn.Map).Accepted) { var cells = GenAdj.CellsAdjacent8Way(new TargetInfo(newPosition, this.pawn.Map)); foreach (IntVec3 cell in cells) { if (GenConstruct.CanPlaceBlueprintAt(CocoonDef, cell, Rot4.North, this.Map).Accepted) { newPosition = cell; break; } } } newCocoon = (Building_Cocoon)GenSpawn.Spawn(CocoonDef, newPosition, spinner.Map); //Log.Message("New Spinner: " + newCocoon.Spinner.Label); newCocoon.TryGetInnerInteractableThingOwner().TryAdd(toLoad); this.pawn?.CurJob?.SetTarget(TargetIndex.B, newCocoon); } }, defaultCompleteMode = ToilCompleteMode.Instant }; Toil pickupCocoon = Toils_Haul.StartCarryThing(TargetIndex.B); pickupCocoon.AddPreInitAction(new Action(delegate { //this.TargetB.Thing.DeSpawn(); this.pawn.CurJob.SetTarget(TargetIndex.C, TargetB.Thing); this.pawn.Reserve(TargetC, this.job); //this.pawn.Map.physicalInteractionReservationManager.Reserve(this.pawn, TargetC); })); Toil relocateCocoon = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); Toil dropCocoon = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, relocateCocoon, false).FailOn(() => !GenConstruct.CanPlaceBlueprintAt(CocoonDef, TargetC.Cell, Rot4.North, this.Map).Accepted); this.AddFinishAction(new Action(delegate { this.pawn.Map.physicalInteractionReservationManager.ReleaseAllClaimedBy(this.pawn); })); /* * * Toil Execution * */ yield return(new Toil { initAction = delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); }, atomicWithPrevious = true, defaultCompleteMode = ToilCompleteMode.Instant }); Action onHitAction = delegate { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelIndefinite() }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig);// MessageSound.SeriousAlert); } this.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; //yield return Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIf(() => Prey.Downed || Prey.Dead, prepareToSpin).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f); yield return(prepareToSpin.FailOn(() => Prey == null)); yield return(gotoBody.FailOn(() => Prey == null)); yield return(spinDelay.FailOn(() => Prey == null)); yield return(spinBody.FailOn(() => Prey == null)); //yield return pickupCocoon; //yield return relocateCocoon; //yield return dropCocoon; //float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); //yield return Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); //yield return Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A); //yield return Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f); }
protected override IEnumerable <Toil> MakeNewToils() { rotateToFace = Facing; AddEndCondition(delegate { if (ExecutionerPawn?.CurJob == null) { return(JobCondition.Incompletable); } if (ExecutionerPawn.CurJob.def == CultsDefOf.Cults_ReflectOnResult) { return(JobCondition.Succeeded); } if (ExecutionerPawn.CurJob.def != CultsDefOf.Cults_HoldSacrifice) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.EndOnDespawnedOrNull(Spot); this.EndOnDespawnedOrNull(Build); yield return(Toils_Reserve.Reserve(Spot)); //Toil 1: Go to the locations var gotoExecutioner = TargetC.HasThing ? Toils_Goto.GotoThing(Spot, PathEndMode.OnCell) : Toils_Goto.GotoCell(Spot, PathEndMode.OnCell); yield return(gotoExecutioner); //Toil 2: 'Attend' var altarToil = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = CultUtility.ritualDuration }; altarToil.AddPreTickAction(() => { pawn.GainComfortFromCellIfPossible(); pawn.rotationTracker.FaceCell(TargetB.Cell); if (report == "") { report = "Cults_AttendingSacrifice".Translate(); } if (ExecutionerPawn?.CurJob == null) { return; } if (ExecutionerPawn.CurJob.def != CultsDefOf.Cults_HoldSacrifice) { ReadyForNextToil(); } }); altarToil.JumpIf(() => ExecutionerPawn.CurJob.def == CultsDefOf.Cults_HoldSacrifice, altarToil); yield return(altarToil); //ToDo -- Add random Ia! Ia! yield return(new Toil { initAction = delegate { //Do something? Ia ia! }, defaultCompleteMode = ToilCompleteMode.Instant }); //Toil 3 Reflect on worship var reflectingTime = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = CultUtility.reflectDuration }; reflectingTime.AddPreTickAction(() => report = "Cults_ReflectingOnSacrifice".Translate()); yield return(reflectingTime); //Toil 3 Reset the altar and clear variables. yield return(new Toil { initAction = delegate { if (Altar == null) { return; } if (Altar.currentSacrificeState != Building_SacrificialAltar.SacrificeState.finished) { Altar.ChangeState(Building_SacrificialAltar.State.sacrificing, Building_SacrificialAltar.SacrificeState.finished); } }, defaultCompleteMode = ToilCompleteMode.Instant }); AddFinishAction(() => { //When the ritual is finished -- then let's give the thoughts /* * if (Altar.currentSacrificeState == Building_SacrificialAltar.SacrificeState.finished) * { * if (this.pawn == null) return; * if (Altar.sacrifice != null) * { * CultUtility.AttendSacrificeTickCheckEnd(this.pawn, Altar.sacrifice); * } * else * { * CultUtility.AttendSacrificeTickCheckEnd(this.pawn, null); * } * } */ if (TargetC.Cell.GetEdifice(pawn.Map) != null) { if (pawn.Map.reservationManager.ReservedBy(TargetC.Cell.GetEdifice(pawn.Map), pawn)) { pawn.ClearAllReservations(); // this.pawn.Map.reservationManager.Release(this.TargetC.Cell.GetEdifice(this.pawn.Map), pawn); } } else { if (pawn.Map.reservationManager.ReservedBy(TargetC.Cell.GetEdifice(pawn.Map), pawn)) { pawn.ClearAllReservations(); //this.pawn.Map.reservationManager.Release(this.job.targetC.Cell, this.pawn); } } }); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(iPrisoner); this.FailOnDestroyedOrNull(iSacrificeBuilding); this.FailOnAggroMentalState(iPrisoner); yield return(Toils_Goto.GotoThing(iPrisoner, PathEndMode.OnCell)); yield return(Toils_Haul.StartCarryThing(iPrisoner, true, false)); yield return(Toils_Goto.GotoThing(iSacrificeBuilding, SacrificeSpot.InteractionCell)); yield return(Toils_Reserve.Release(iPrisoner)); var doSacrificePrisoner = new Toil { socialMode = RandomSocialMode.Off, }; doSacrificePrisoner.initAction = () => { Sacrificer.carryTracker.TryDropCarriedThing(SacrificeSpot.InteractionCell, ThingPlaceMode.Direct, out var thing, null); Prisoner.jobs.StartJob(JobMaker.MakeJob(Defs.PrisonerWait)); }; doSacrificePrisoner.AddFailCondition(() => Prisoner.Dead); doSacrificePrisoner.defaultCompleteMode = ToilCompleteMode.Never; doSacrificePrisoner.AddPreTickAction(() => { --TicksLeft; if (TicksLeft <= 0) { ReadyForNextToil(); } }); yield return(doSacrificePrisoner.WithProgressBar(iPawn, () => (TicksMax - (float)TicksLeft) / TicksMax)); var afterSacrificePrisoner = new Toil { defaultCompleteMode = ToilCompleteMode.Instant, initAction = () => { var heartBpr = Prisoner.RaceProps.body.AllParts.Find(bpr => bpr.def.defName == "Heart"); var dInfo = new DamageInfo(Defs.HeartExtraction, 99999f, armorPenetration: 999f, hitPart: heartBpr); Prisoner.Kill(dInfo); ThoughtUtility.GiveThoughtsForPawnExecuted(Prisoner, Sacrificer, PawnExecutionKind.GenericBrutal); // Apply negative relations modifier. if (pawn.Faction != null && Prisoner.Faction != null) { Faction playerFaction = pawn.Faction; Faction prisonerFaction = Prisoner.Faction; string reason = "GoodwillChangedReason_RemovedBodyPart".Translate(heartBpr.Label); GlobalTargetInfo?LookTargets = pawn; playerFaction.TryAffectGoodwillWith(prisonerFaction, -25); } // Apply thoughts to pawns. foreach (var mapPawn in Map.mapPawns.FreeColonistsAndPrisoners) { if (mapPawn.IsPrisoner) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedFear); } else if (mapPawn.IsColonist && (mapPawn.IsRevia() || mapPawn.IsSkarnite())) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedPositive); } else if (mapPawn.IsColonist && !(mapPawn.IsCannibal() || mapPawn.IsPsychopath() || mapPawn.IsBloodlust())) { mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedNegative); } } // Spawn the product, or handle one of the other effects. // Find a good spot to spawn the product. IntVec3 spawnPos = CellFinder.FindNoWipeSpawnLocNear( Prisoner.Position, Map, Defs.Bloodstone, Rot4.Random, 6, pos => { return ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) && // F**k you Tynan. Learn your coordinates! (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1)); }); if (Map.GameConditionManager.ConditionIsActive(Defs.Eclipse)) { var missingParts = pawn.health.hediffSet.GetMissingPartsCommonAncestors(); if (missingParts.Count > 0) { var missing = missingParts.RandomElement(); pawn.health.hediffSet.hediffs.Remove(missing); var maxHp = missing.Part.def.GetMaxHealth(pawn); var injuryHediff = pawn.health.AddHediff(HediffDefOf.Cut, missing.Part, new DamageInfo(DamageDefOf.Rotting, 1.0f, 10000.00f)); var permHediffComp = injuryHediff.TryGetComp <HediffComp_GetsPermanent>(); injuryHediff.Severity = maxHp / 2.0f; permHediffComp.IsPermanent = true; } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); thing.stackCount += 2; } } else if (Map.GameConditionManager.ConditionIsActive(Defs.SolarFlare)) { var permInjuries = pawn.health.hediffSet.hediffs.Where(h => h.IsPermanent() && !(h is Hediff_MissingPart)).ToList(); if (permInjuries.Count > 0) { var randomInjury = permInjuries.RandomElement(); randomInjury.Severity -= randomInjury.Part.depth == BodyPartDepth.Inside ? 2.0f : 4.0f; } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); thing.stackCount += 1; } } else { var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map); } var bloodthirst = Sacrificer.needs.TryGetNeed <BloodthirstNeed>(); if (bloodthirst != null) { bloodthirst.CurLevel += 0.80f * Prisoner.BodySize; } TaleRecorder.RecordTale(Defs.TaleSacrificed, new[] { Sacrificer, Prisoner }); // Find a good spot to move the prisoner corpse. IntVec3 movePos = CellFinder.FindNoWipeSpawnLocNear( Prisoner.Position, Map, Prisoner.Corpse.def, Rot4.Random, 6, pos => { return ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) && // F**k you Tynan. Learn your coordinates! (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1)); }); Prisoner.Corpse.Position = movePos; } }; yield return(afterSacrificePrisoner); }
protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate() { var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A); this.FailOn <JobDriver_DoBill>(delegate() { if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver)) { return(false); } if (this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } return(false); }); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); var tableThing = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach; var refuelableComp = tableThing.GetComp <CompRefuelable>(); //I think you should check this for Null, but i'm not sure where are you using it. var toil = new Toil { initAction = delegate() { this.job.bill.Notify_DoBillStarted(this.pawn); this.workCycleProgress = this.job.bill.recipe.workAmount; }, tickAction = delegate() { this.workCycleProgress -= this.pawn.GetStatValue(StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel)) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); } if (!(this.workCycleProgress <= 0f)) { return; } var workSkill = this.job.bill.recipe.workSkill; if (workSkill != null) { SkillRecord skill = this.pawn.skills.GetSkill(workSkill); skill?.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false); } GenSpawn.Spawn(tableThing.GetAlienBloodByRecipe(this.job.bill.recipe), tableThing.InteractionCell, tableThing.Map, 0); Toils_Reserve.Release(TargetIndex.A); this.pawn.GainComfortFromCellIfPossible(false); this.job.bill.Notify_IterationCompleted(this.pawn, null); this.ReadyForNextToil(); }, defaultCompleteMode = ToilCompleteMode.Never }; toil.WithEffect(() => this.job.bill.recipe.effectWorking, TargetIndex.A); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(TargetIndex.A, delegate() { return(PurpleIvyUtils.GetPercentageFromPartWhole (this.job.bill.recipe.workAmount - this.workCycleProgress, (int)this.job.bill.recipe.workAmount) / 100f); }, false, 0.5f); toil.FailOn <Toil>(delegate() { return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver && !billGiver.CurrentlyUsableForBills())); }); yield return(toil); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnDestroyedOrNull(TargetIndex.B); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, false)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(new Toil { initAction = delegate { Thing straitjacket = null; this.pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out straitjacket, null); Pawn pawnToForceIntoStraitjacket = (Pawn)TargetA.Thing; if (pawnToForceIntoStraitjacket != null) { if (!pawnToForceIntoStraitjacket.InAggroMentalState) { GenClamor.DoClamor(pawn, 10f, ClamorDefOf.Harm); if (!CheckAcceptStraitJacket(pawnToForceIntoStraitjacket, this.pawn)) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); } } } }, defaultCompleteMode = ToilCompleteMode.Instant }); Toil toil2 = new Toil(); toil2.defaultCompleteMode = ToilCompleteMode.Delay; toil2.defaultDuration = 500; toil2.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); toil2.initAction = delegate { Pawn pawnToForceIntoStraitjacket = (Pawn)TargetA.Thing; if (pawnToForceIntoStraitjacket != null) { if (!pawnToForceIntoStraitjacket.InAggroMentalState) { PawnUtility.ForceWait(pawnToForceIntoStraitjacket, toil2.defaultDuration, this.pawn); } } }; yield return(toil2); yield return(new Toil { initAction = delegate { Takee.apparel.Wear(Straitjacket); Takee.outfits.forcedHandler.SetForced(Straitjacket, true); Hediff pawnJacketHediff = Takee.health.hediffSet.GetFirstHediffOfDef(StraitjacketDefOf.ROM_RestainedByStraitjacket); if (pawnJacketHediff == null) { pawnJacketHediff = HediffMaker.MakeHediff(StraitjacketDefOf.ROM_RestainedByStraitjacket, Takee); Takee.health.AddHediff(pawnJacketHediff); } }, defaultCompleteMode = ToilCompleteMode.Instant }); yield break; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOn(() => !base.Patient.InBed() || !base.Patient.Awake()); if (base.Chair != null) { this.FailOnDespawnedNullOrForbidden(TargetIndex.B); } if (base.Chair != null) { this.$current = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell); if (!this.$disposing) { this.$PC = 1; } return(true); } this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); if (!this.$disposing) { this.$PC = 2; } return(true); case 1u: break; case 2u: break; case 3u: { Toil waitAndTalk = new Toil(); waitAndTalk.tickAction = delegate() { base.Patient.needs.joy.GainJoy(this.job.def.joyGainRate * 0.000144f, this.job.def.joyKind); if (this.pawn.IsHashIntervalTick(320)) { InteractionDef intDef = (Rand.Value >= 0.8f) ? InteractionDefOf.DeepTalk : InteractionDefOf.Chitchat; this.pawn.interactions.TryInteractWith(base.Patient, intDef); } this.pawn.rotationTracker.FaceCell(base.Patient.Position); this.pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.None, 1f, null); if (this.pawn.needs.joy.CurLevelPercentage > 0.9999f && base.Patient.needs.joy.CurLevelPercentage > 0.9999f) { this.pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true); } }; waitAndTalk.handlingFacing = true; waitAndTalk.socialMode = RandomSocialMode.Off; waitAndTalk.defaultCompleteMode = ToilCompleteMode.Delay; waitAndTalk.defaultDuration = this.job.def.joyDuration; this.$current = waitAndTalk; if (!this.$disposing) { this.$PC = 4; } return(true); } case 4u: this.$PC = -1; return(false); default: return(false); } this.$current = Toils_Interpersonal.WaitToBeAbleToInteract(this.pawn); if (!this.$disposing) { this.$PC = 3; } return(true); }
protected override IEnumerable <Toil> MakeNewToils() { this.Init(); yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, (this.RequiredDesignation == null) ? null : new Func <Thing, bool>((Thing t) => this.$this.Map.designationManager.DesignationOn(t, this.$this.RequiredDesignation) != null)); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true)); Toil gotoThing = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue); if (this.RequiredDesignation != null) { gotoThing.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation); } yield return(gotoThing); Toil cut = new Toil(); cut.tickAction = delegate { Pawn actor = cut.actor; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Plants, this.$this.xpPerTick, false); } float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); float num = statValue; Plant plant = this.$this.Plant; num *= Mathf.Lerp(3.3f, 1f, plant.Growth); this.$this.workDone += num; if (this.$this.workDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true)) { Vector3 loc = (this.$this.pawn.DrawPos + plant.DrawPos) / 2f; MoteMaker.ThrowText(loc, this.$this.Map, "TextMote_HarvestFailed".Translate(), 3.65f); } else { int num2 = plant.YieldNow(); if (num2 > 0) { Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null); thing.stackCount = num2; if (actor.Faction != Faction.OfPlayer) { thing.SetForbidden(true, true); } GenPlace.TryPlaceThing(thing, actor.Position, this.$this.Map, ThingPlaceMode.Near, null, null); actor.records.Increment(RecordDefOf.PlantsHarvested); } } } plant.def.plant.soundHarvestFinish.PlayOneShot(actor); plant.PlantCollected(); this.$this.workDone = 0f; this.$this.ReadyForNextToil(); return; } }; cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); if (this.RequiredDesignation != null) { cut.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation); } cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); cut.defaultCompleteMode = ToilCompleteMode.Never; cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); cut.WithProgressBar(TargetIndex.A, () => this.$this.workDone / this.$this.Plant.def.plant.harvestWork, true, -0.5f); cut.PlaySustainerOrSound(() => this.$this.Plant.def.plant.soundHarvesting); cut.activeSkill = (() => SkillDefOf.Plants); yield return(cut); Toil plantWorkDoneToil = this.PlantWorkDoneToil(); if (plantWorkDoneToil != null) { yield return(plantWorkDoneToil); } yield return(Toils_Jump.Jump(initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate() { IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } if (project == null) { Log.Error("[HumanResources] Tried to document a null project."); TryMakePreToilReservations(true); return(true); } if (!techComp.homework.Contains(project)) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate() { if (job.targetQueueB != null && job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)job.bill; } } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); extract = null; getToHaulTarget = null; findPlaceTarget = null; yield return(gotoBillGiver); yield return(MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinishRecipeAndStartStoringProduct()); if (!job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>()) { yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false)); findPlaceTarget = Toils_Haul.CarryHauledThingToContainer(); yield return(findPlaceTarget); Toil prepare = Toils_General.Wait(250); prepare.WithProgressBarToilDelay(TargetIndex.B, false, -0.5f); yield return(prepare); yield return(new Toil { initAction = delegate { Building_BookStore shelf = (Building_BookStore)job.GetTarget(TargetIndex.B).Thing; CurToil.FailOn(() => shelf == null); Thing book = pawn.carryTracker.CarriedThing; if (pawn.carryTracker.CarriedThing == null) { Log.Error($"[HumanResources] {pawn} tried to place a book on shelf but is not hauling anything."); return; } if (shelf.Accepts(book)) { bool flag = false; if (book.holdingOwner != null) { book.holdingOwner.TryTransferToContainer(book, shelf.TryGetInnerInteractableThingOwner(), book.stackCount, true); flag = true; } else { flag = shelf.TryGetInnerInteractableThingOwner().TryAdd(book, true); } pawn.carryTracker.innerContainer.Remove(book); } else { Log.Error($"[HumanResources] {pawn} tried to place a book in {shelf}, but it won't accept it."); return; } pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); } }); } yield break; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); if (base.HasChair) { this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable); } if (base.HasDrink) { this.FailOnDestroyedNullOrForbidden(TargetIndex.C); this.$current = Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C); if (!this.$disposing) { this.$PC = 1; } return(true); } break; case 1u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: break; case 3u: chew = new Toil(); chew.tickAction = delegate() { this.pawn.rotationTracker.FaceCell(base.ClosestGatherSpotParentCell); this.pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.GoToNextToil, 1f, null); }; chew.handlingFacing = true; chew.defaultCompleteMode = ToilCompleteMode.Delay; chew.defaultDuration = this.job.def.joyDuration; chew.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.pawn); }); chew.socialMode = RandomSocialMode.SuperActive; Toils_Ingest.AddIngestionEffects(chew, this.pawn, TargetIndex.C, TargetIndex.None); this.$current = chew; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: if (base.HasDrink) { this.$current = Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.C); if (!this.$disposing) { this.$PC = 5; } return(true); } goto IL_1D9; case 5u: goto IL_1D9; default: return(false); } this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell); if (!this.$disposing) { this.$PC = 3; } return(true); IL_1D9: this.$PC = -1; return(false); }
public static IEnumerable <Toil> MakeFeedToils(JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition) { yield return(Toils_Reserve.Reserve(TargetIndex.A)); Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoToil); Toil grappleToil = new Toil() { initAction = delegate { MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); workLeft = JobDriver_Feed.BaseFeedTime; Pawn victim = (Pawn)TargetA.Thing; if (victim != null) { if (victim.InAggroMentalState || victim.Faction != actor.Faction) { if (!JecsTools.GrappleUtility.CanGrapple(actor, victim)) { thisDriver.EndJobWith(JobCondition.Incompletable); } } GenClamor.DoClamor(actor, 10f, ClamorDefOf.Harm); if (!AllowFeeding(actor, victim)) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); } if (actor?.VampComp()?.Bloodline?.bloodlineHediff?.CompProps <HediffCompProperties_VerbGiver>()?.verbs is List <VerbProperties> verbProps) { if (actor?.VerbTracker?.AllVerbs is List <Verb> verbs) { if (verbs.Find(x => verbProps.Contains(x.verbProps)) is Verb_MeleeAttack v) { victim.TakeDamage(new DamageInfo(v.verbProps.meleeDamageDef, v.verbProps.meleeDamageBaseAmount, v.verbProps.meleeArmorPenetrationBase, -1, actor)); } } } victim.stances.stunner.StunFor((int)BaseFeedTime, actor); } } }; yield return(grappleToil); Toil feedToil = new Toil() { tickAction = delegate { Pawn victim = (Pawn)TargetA.Thing; if (victim == null || !victim.Spawned || victim.Dead) { thisDriver.ReadyForNextToil(); } workLeft--; if (workLeft <= 0f) { if (actor?.VampComp() is CompVampire v && v.IsVampire && actor.Faction == Faction.OfPlayer) { MoteMaker.ThrowText(actor.DrawPos, actor.Map, "XP +" + 15); v.XP += 15; } workLeft = BaseFeedTime; MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); effect(); if ((victim.HostileTo(actor.Faction) || victim.IsPrisoner) && !JecsTools.GrappleUtility.CanGrapple(actor, victim)) { thisDriver.EndJobWith(JobCondition.Incompletable); } if (!stopCondition(actor, victim)) { thisDriver.ReadyForNextToil(); } else { if (victim != null && !victim.Dead) { victim.stances.stunner.StunFor((int)BaseFeedTime, actor); PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor); } } } },
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); Toil gotoTurret = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); Toil loadIfNeeded = new Toil(); loadIfNeeded.initAction = delegate { Pawn actor3 = loadIfNeeded.actor; Building obj = (Building)actor3.CurJob.targetA.Thing; Building_TurretGun building_TurretGun2 = obj as Building_TurretGun; if (!GunNeedsLoading(obj)) { JumpToToil(gotoTurret); } else { Thing thing = FindAmmoForTurret(pawn, building_TurretGun2); if (thing == null) { if (actor3.Faction == Faction.OfPlayer) { Messages.Message("MessageOutOfNearbyShellsFor".Translate(actor3.LabelShort, building_TurretGun2.Label, actor3.Named("PAWN"), building_TurretGun2.Named("GUN")).CapitalizeFirst(), building_TurretGun2, MessageTypeDefOf.NegativeEvent); } actor3.jobs.EndCurrentJob(JobCondition.Incompletable); } actor3.CurJob.targetB = thing; actor3.CurJob.count = 1; } }; yield return(loadIfNeeded); yield return(Toils_Reserve.Reserve(TargetIndex.B, 10, 1)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); Toil toil = new Toil(); toil.initAction = delegate { Pawn actor2 = loadIfNeeded.actor; Building_TurretGun building_TurretGun = ((Building)actor2.CurJob.targetA.Thing) as Building_TurretGun; SoundDefOf.Artillery_ShellLoaded.PlayOneShot(new TargetInfo(building_TurretGun.Position, building_TurretGun.Map)); building_TurretGun.gun.TryGetComp <CompChangeableProjectile>().LoadShell(actor2.CurJob.targetB.Thing.def, 1); actor2.carryTracker.innerContainer.ClearAndDestroyContents(); }; yield return(toil); yield return(gotoTurret); Toil man = new Toil(); man.tickAction = delegate { Pawn actor = man.actor; Building building = (Building)actor.CurJob.targetA.Thing; if (GunNeedsLoading(building)) { JumpToToil(loadIfNeeded); } else { building.GetComp <CompMannable>().ManForATick(actor); man.actor.rotationTracker.FaceCell(building.Position); } }; man.handlingFacing = true; man.defaultCompleteMode = ToilCompleteMode.Never; man.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell); yield return(man); }
protected override IEnumerable <Toil> MakeNewToils() { var upgrade = TargetThingA.FirstUpgradeableComp(); if (upgrade == null) { EndJobWith(JobCondition.Incompletable); yield break; } AddFailCondition(() => { var comp = TargetThingA.FirstUpgradeableComp(); return(comp == null || !comp.parent.Spawned || !comp.WantsWork); }); this.FailOnDestroyedNullOrForbidden(TargetIndex.A); var gotoUpgradeable = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); var lookForIngredient = new Toil { initAction = () => { var missingIngredient = upgrade.TryGetNextMissingIngredient(); job.count = missingIngredient.Count; if (missingIngredient.Count > 0) { bool SearchPredicate(Thing thing) => !thing.IsForbidden(pawn) && pawn.CanReserve(thing); var t = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(missingIngredient.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 999, SearchPredicate); if (t == null) { EndJobWith(JobCondition.Incompletable); } else { job.SetTarget(TargetIndex.B, t); } } else { JumpToToil(gotoUpgradeable); } } }; yield return(lookForIngredient); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, job.count)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch).FailOnDestroyedNullOrForbidden(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B)); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.InteractionCell)); yield return(new Toil { initAction = () => { if (pawn.carryTracker.CarriedThing != null) { pawn.carryTracker.innerContainer.TryTransferToContainer(pawn.carryTracker.CarriedThing, upgrade.GetDirectlyHeldThings(), pawn.carryTracker.CarriedThing.stackCount); pawn.Map.reservationManager.ReleaseAllForTarget(TargetThingB); job.SetTarget(TargetIndex.B, null); JumpToToil(lookForIngredient); } } }); yield return(gotoUpgradeable); yield return(new Toil { tickAction = () => { upgrade.DoWork(GetActor().GetStatValue(StatDefOf.ConstructionSpeed)); if (upgrade.Complete) { EndJobWith(JobCondition.Succeeded); } }, defaultCompleteMode = ToilCompleteMode.Never }.WithEffect(EffecterDefOf.ConstructMetal, TargetIndex.A) .WithProgressBar(TargetIndex.A, () => upgrade.WorkProgress)); } }
public override IEnumerable <Toil> MakeNewToils() { var ZTracker = ZUtils.ZTracker; if (pawn.Map == this.job.targetA.Thing.Map && pawn.Map == ZTracker.jobTracker[pawn].targetDest.Map) { ZLogger.Message("pawn map and thing map and dest map are same, yield breaking in JobDriver_HaulThingToDest"); yield break; } yield return(new Toil { initAction = delegate() { this.savedThing = this.job.targetA.Thing; } }); Toil reserveItem = Toils_Reserve.Reserve(TargetIndex.A); ZLogger.Message($"JobDriver HaulThingToDest1 About to call findRouteWithStairs, with pawn {GetActor()}, dest { TargetA.Thing}, instance {this}"); Log.Message("3 - pawn.Map: " + pawn.Map + " - dest: " + new TargetInfo(TargetA.Thing).Map, true); foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), new TargetInfo(TargetA.Thing).Map, this)) { yield return(toil); } yield return(new Toil { initAction = delegate() { ZLogger.Message("JobDriver_HaulThingToDest 1: " + pawn + " trying to reserve: " + TargetA, true); } }); Toil toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch); yield return(reserveItem.FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(new Toil { initAction = delegate() { ZLogger.Message("JobDriver_HaulThingToDest 1: " + pawn + " reserved: " + TargetA, true); } }); yield return(toilGoto); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true).FailOnDestroyedNullOrForbidden(TargetIndex.A)); if (job.haulOpportunisticDuplicates) { yield return(new Toil { initAction = delegate() { ZLogger.Message("2: " + pawn + " trying to reserve other things: " + TargetA, true); } }); yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveItem, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true)); yield return(new Toil { initAction = delegate() { ZLogger.Message("2: " + pawn + " reserved other things: " + TargetA, true); } }); } yield return(new Toil { initAction = delegate() { try { if (ZTracker.jobTracker.ContainsKey(pawn)) { if (ZTracker.jobTracker[pawn].mainJob.targetA.Thing != null && ZTracker.jobTracker[pawn].mainJob.targetA.Thing == this.savedThing && ZTracker.jobTracker[pawn].mainJob.targetA.Thing != TargetA.Thing) { ZTracker.jobTracker[pawn].mainJob.targetA = new LocalTargetInfo(TargetA.Thing); } else if (ZTracker.jobTracker[pawn].mainJob.targetB.Thing != null && ZTracker.jobTracker[pawn].mainJob.targetB.Thing == this.savedThing && ZTracker.jobTracker[pawn].mainJob.targetB.Thing != TargetA.Thing) { ZTracker.jobTracker[pawn].mainJob.targetB = new LocalTargetInfo(TargetA.Thing); } try { for (int i = ZTracker.jobTracker[pawn].mainJob.targetQueueA.Count - 1; i >= 0; i--) { var target = ZTracker.jobTracker[pawn].mainJob.targetQueueA[i]; if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing) { ZTracker.jobTracker[pawn].mainJob.targetQueueA[i] = new LocalTargetInfo(TargetA.Thing); } } } catch { } try { for (int i = ZTracker.jobTracker[pawn].mainJob.targetQueueB.Count - 1; i >= 0; i--) { var target = ZTracker.jobTracker[pawn].mainJob.targetQueueB[i]; if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing) { if (ZTracker.jobTracker[pawn].mainJob.targetQueueB[i].Thing.stackCount == 0) { ZTracker.jobTracker[pawn].mainJob.targetQueueB[i] = new LocalTargetInfo(TargetA.Thing); ZTracker.jobTracker[pawn].mainJob.countQueue[i] = TargetA.Thing.stackCount; break; } else { if (ZTracker.jobTracker[pawn].mainJob.targetQueueB .Where(x => x.Thing == TargetA.Thing).Count() == 0) { var newTarget = new LocalTargetInfo(TargetA.Thing); ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.Add(newTarget); ZTracker.jobTracker[this.pawn].mainJob.countQueue.Add(newTarget.Thing.stackCount); int ind = ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.FirstIndexOf(x => x.Thing == this.savedThing); ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.RemoveAt(ind); ZTracker.jobTracker[this.pawn].mainJob.countQueue.RemoveAt(ind); break; } } } } } catch { } } } catch (Exception ex) { Log.Error("Z-Tracker produced an error in JobDriver_HaulThingToStairs class. Report about it to devs. Error: " + ex); } } }); ZLogger.Message($"JobDriver HaulThingToDest 2About to call findRouteWithStairs, with pawn {GetActor()}, dest {ZTracker.jobTracker[pawn].targetDest}, instance {this}"); Log.Message("4 - pawn.Map: " + pawn.Map + " - dest: " + ZTracker.jobTracker[pawn].targetDest.Map, true); foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), ZTracker.jobTracker[pawn].targetDest.Map, this)) { yield return(toil); } }
protected override IEnumerable <Toil> MakeNewToils() { var consumeThingList = new List <Thing>(); var ingList = this.job.GetTargetQueue(IngredientInd); var ingCountList = this.job.countQueue; //this.job.SetTarget(IngredientPlaceCellInd, this.TargetA.Thing.InteractionCell); var startToil = Toils_General.Do(() => { this.job.SetTarget(IngredientInd, ingList[0].Thing); this.job.count = ingCountList[0]; ingList.RemoveAt(0); ingCountList.RemoveAt(0); }); // 材料キューの先頭を取り出してセット yield return(startToil); // 材料の置き場所へ移動 var gotoToil = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch); yield return(gotoToil); // 材料を運ぶ yield return(Toils_Haul.StartCarryThing(IngredientInd)); // 運ぶものリストの中に同種の材料があり、まだ物を持てる場合、設備へ持っていく前に取りに行く yield return(Toils_General.Do(() => { Pawn actor = this.pawn; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(IngredientInd); if (targetQueue.NullOrEmpty <LocalTargetInfo>()) { return; } if (curJob.count <= 0) { return; } if (actor.carryTracker.CarriedThing == null) { Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something."); return; } if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) <= 0) { return; } for (int i = 0; i < targetQueue.Count; i++) { if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (targetQueue[i].Thing.def == actor.carryTracker.CarriedThing.def) { curJob.SetTarget(IngredientInd, targetQueue[i].Thing); curJob.count = curJob.countQueue[i]; targetQueue.RemoveAt(i); curJob.countQueue.RemoveAt(i); actor.jobs.curDriver.JumpToToil(gotoToil); break; } } })); // 運ぶ yield return(Toils_Haul.CarryHauledThingToCell(IngredientPlaceCellInd)); // 運んだものリスト(使用素材)に追加 yield return(Toils_Mizu.AddPlacedThing()); // 運んだものを置く yield return(Toils_Haul.PlaceCarriedThingInCellFacing(BillGiverInd)); // まだ材料があるならさらに運ぶ yield return(Toils_General.Do(() => { if (this.job.GetTargetQueue(IngredientInd).Count > 0) { this.pawn.jobs.curDriver.JumpToToil(startToil); } })); // レシピ実行 yield return(Toils_Recipe.DoRecipeWork()); // 水の注入完了処理 yield return(Toils_Mizu.FinishPourRecipe(BillGiverInd, IngredientInd)); }
private IEnumerable <Toil> Clipboard() { yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); yield return(Toils_Reserve.ReserveQueue(TargetIndex.A)); Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); Toil checkNextQueuedTarget = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, checkNextQueuedTarget)); Toil cut = new Toil() { tickAction = delegate { Pawn actor = GetActor(); if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Growing, 0.11f); } float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); float num = statValue; workDone += num; if (workDone >= Duration) { if (Plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && Plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true)) { Vector3 loc = (pawn.DrawPos + Plant.DrawPos) / 2f; MoteMaker.ThrowText(loc, Map, "TextMote_HarvestFailed".Translate(), 3.65f); } else { Thing thing = Plant.CollectSecondaryThing(); if (actor.Faction != Faction.OfPlayer) { thing.SetForbidden(true, true); } GenPlace.TryPlaceThing(thing, actor.Position, Map, ThingPlaceMode.Near); actor.records.Increment(RecordDefOf.PlantsHarvested); // If there is a SeedsPlease seed, try to drop it if (Plant.seedDef != null) { int stack = Rand.RangeInclusive(-1, 1); if (pawn.skills != null) { stack += GenMath.RoundRandom(pawn.skills.GetSkill(SkillDefOf.Growing).Level / 8f); } if (stack > 0) { Thing seed = ThingMaker.MakeThing(Plant.seedDef); seed.stackCount = stack; GenPlace.TryPlaceThing(seed, pawn.Position, pawn.Map, ThingPlaceMode.Near); } } } } Plant.def.plant.soundHarvestFinish.PlayOneShot(actor); workDone = 0f; ReadyForNextToil(); return; } } }; cut.FailOn(() => !Plant.Sec_HarvestableNow); cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); cut.defaultCompleteMode = ToilCompleteMode.Never; cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); cut.WithProgressBar(TargetIndex.A, () => workDone / Duration, true, -0.5f); cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting); yield return(cut); yield return(checkNextQueuedTarget); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { //Set fail conditions this.FailOnDestroyedNullOrForbidden(HaulableInd); this.FailOnBurningImmobile(CellInd); //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(HaulableInd); } //Reserve target storage cell, if it is a storage bool targetIsStorage = StoreUtility.GetSlotGroup(pawn.jobs.curJob.GetTarget(CellInd).Cell, Map) != null; if (targetIsStorage) { yield return(Toils_Reserve.Reserve(CellInd, 1)); } //Reserve thing to be stored Toil reserveTargetA = Toils_Reserve.Reserve(HaulableInd, 1); yield return(reserveTargetA); // Goto object //Toil toilGoto = null; //toilGoto = Toils_Goto.GotoThing(HaulableInd, 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(HaulableInd).Thing; // IntVec3 destLoc = actor.jobs.curJob.GetTarget(CellInd).Cell; // if (!destLoc.IsValidStorageFor(Map, haulThing)) // return true; // } // return false; // }); //yield return toilGoto; yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(HaulableInd)); // Start hauling to yield return(Toils_Haul.StartCarryThing(HaulableInd, false, false)); if (this.job.haulOpportunisticDuplicates) { yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, HaulableInd, CellInd)); } Toil carryToCell = Toils_Haul.CarryHauledThingToCell(CellInd); yield return(carryToCell); // start work on target yield return(Toils_WaitWithSoundAndEffect(180, "Interact_ConstructMetal", "ConstructMetal", CellInd)); yield return(Toils_TryToAttachToWeaponBase(pawn, HaulableInd, CellInd)); }
public override IEnumerable <Toil> MakeNewToils() { var ZTracker = ZUtils.ZTracker; yield return(new Toil { initAction = delegate() { if (pawn.Map == this.job.targetA.Thing?.Map && pawn.Map == ZTracker.jobTracker[pawn].targetDest.Map) { ZLogger.Message("pawn map and thing map and dest map are same, yield breaking in JobDriver_HaulThingToDest"); this.EndJobWith(JobCondition.InterruptForced); } this.savedThing = this.job.targetA.Thing; } }); Toil reserveItem = Toils_Reserve.Reserve(TargetIndex.A); if (TargetA.Thing?.Map != null) { foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), new TargetInfo(TargetA.Thing).Map, this)) { yield return(toil); } } Toil toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch); yield return(reserveItem.FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(toilGoto); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true).FailOnDestroyedNullOrForbidden(TargetIndex.A)); if (job.haulOpportunisticDuplicates) { yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveItem, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true)); } yield return(Toils_Haul.JumpIfAlsoCollectingNextTargetInQueue(toilGoto, TargetIndex.A)); yield return(new Toil { initAction = delegate() { if (ZTracker.jobTracker.TryGetValue(pawn, out JobTracker jobTracker)) { if (jobTracker.mainJob.targetA.Thing != null && jobTracker.mainJob.targetA.Thing == this.savedThing && jobTracker.mainJob.targetA.Thing != TargetA.Thing) { jobTracker.mainJob.targetA = new LocalTargetInfo(TargetA.Thing); } else if (jobTracker.mainJob.targetB.Thing != null && jobTracker.mainJob.targetB.Thing == this.savedThing && jobTracker.mainJob.targetB.Thing != TargetA.Thing) { jobTracker.mainJob.targetB = new LocalTargetInfo(TargetA.Thing); } if (jobTracker.mainJob.targetQueueA != null) { for (int i = jobTracker.mainJob.targetQueueA.Count - 1; i >= 0; i--) { var target = jobTracker.mainJob.targetQueueA[i]; if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing) { jobTracker.mainJob.targetQueueA[i] = new LocalTargetInfo(TargetA.Thing); } } } if (jobTracker.mainJob.targetQueueB != null) { for (int i = jobTracker.mainJob.targetQueueB.Count - 1; i >= 0; i--) { var target = jobTracker.mainJob.targetQueueB[i]; if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing) { if (jobTracker.mainJob.targetQueueB[i].Thing.stackCount == 0) { jobTracker.mainJob.targetQueueB[i] = new LocalTargetInfo(TargetA.Thing); jobTracker.mainJob.countQueue[i] = TargetA.Thing.stackCount; break; } else if (!jobTracker.mainJob.targetQueueB.Any(x => x.Thing == TargetA.Thing)) { var newTarget = new LocalTargetInfo(TargetA.Thing); jobTracker.mainJob.targetQueueB.Add(newTarget); jobTracker.mainJob.countQueue.Add(newTarget.Thing.stackCount); int ind = jobTracker.mainJob.targetQueueB.FirstIndexOf(x => x.Thing == this.savedThing); jobTracker.mainJob.targetQueueB.RemoveAt(ind); jobTracker.mainJob.countQueue.RemoveAt(ind); break; } } } } } } });
// Token: 0x06000035 RID: 53 RVA: 0x00003DB8 File Offset: 0x00001FB8 protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); Toil build = new Toil(); build.initAction = delegate() { IntVec3 root = build.actor.Position; Region region = build.actor.GetRegion(RegionType.Set_Passable); bool flag = region == null; if (!flag) { RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null || r.door.Open, delegate(Region r) { List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int i = 0; i < list.Count; i++) { Pawn pawn = list[i] as Pawn; float num = Mathf.Clamp01(pawn.health.capacities.GetLevel(PawnCapacityDefOf.Hearing)); bool flag2 = num > 0f && pawn.Position.InHorDistOf(root, 15f * num); if (flag2) { pawn.HearClamor(build.actor, ClamorDefOf.Construction); } } return(false); }, 15, RegionType.Set_Passable); } }; build.tickAction = delegate() { Pawn actor = build.actor; Frame frame = this.Frame; float num = 1f; float value = actor.records.GetValue(RecordDefOf.ThingsConstructed); float num2 = value / 20f; bool flag = num2 < 1f; if (flag) { num2 = 1f; } bool flag2 = frame.Stuff != null; if (flag2) { num *= frame.Stuff.GetStatValueAbstract(StatDefOf.ConstructionSpeedFactor, null); } float workToBuild = frame.WorkToBuild; bool flag3 = actor.Faction == Faction.OfPlayer && actor.RaceProps.Animal; if (flag3) { bool flag4 = Rand.Value < 1f - Mathf.Pow(num2, num / workToBuild); if (flag4) { frame.FailConstruction(actor); this.ReadyForNextToil(); return; } } bool flag5 = frame.def.entityDefToBuild is TerrainDef; if (flag5) { this.Map.snowGrid.SetDepth(frame.Position, 0f); } frame.workDone += num; bool flag6 = frame.workDone >= workToBuild; if (flag6) { frame.CompleteConstruction(actor); this.ReadyForNextToil(); } }; build.WithEffect(() => ((Frame)build.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing).ConstructionEffect, TargetIndex.A); build.FailOnDespawnedNullOrForbidden(TargetIndex.A); build.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); build.defaultCompleteMode = ToilCompleteMode.Delay; build.defaultDuration = 5000; build.activeSkill = (() => SkillDefOf.Construction); yield return(build); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { Bill bill = job.bill; AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate() { IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); AddFinishAction(delegate() { if (pawn.equipment.Primary != null && !practice) { if (job.GetTarget(TargetIndex.C).IsValid) { Equip(TargetIndex.C, false); } else { ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing; pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false); } } }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); if (!practice) { yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(new Toil { initAction = delegate() { Equip(TargetIndex.B, true); }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); } Thing currentWeapon = practice ? pawn.equipment.Primary : job.targetB.Thing; yield return(gotoBillGiver); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); yield return(Train(currentWeapon).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinalizeTraining()); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { //Bill giver destroyed (only in bill using phase! Not in carry phase) this.AddEndCondition(() => { var targ = this.GetActor().jobs.curJob.GetTarget(ConstructorInd).Thing; if (targ == null || (targ is Building && !targ.Spawned)) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(ConstructorInd); //Bill giver, or product burning in carry phase //Reserve the workbench and the ingredients yield return(Toils_Reserve.Reserve(ConstructorInd)); //yield return Toils_Logging("Reserving done.", false); //-- DEBUG -- //This toil is yielded later Toil gotoBillGiver = Toils_Goto.GotoThing(IngredientInd, PathEndMode.InteractionCell); //Jump over ingredient gathering if there are no ingredients needed yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(IngredientInd).NullOrEmpty())); //Gather ingredients { //Extract an ingredient into IngredientInd target Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientInd); yield return(extract); //Reserve the the ingredient yield return(Toils_Reserve.Reserve(IngredientInd) .FailOnDespawnedNullOrForbidden(IngredientInd)); //Get to ingredient and pick it up //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. var getToHaulTarget = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch) .FailOnDespawnedNullOrForbidden(IngredientInd) .FailOnSomeonePhysicallyInteracting(IngredientInd); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(IngredientInd)); //Jump to pick up more in this run if we're collecting from multiple stacks at once yield return(JumpToCollectNextIntoHands(getToHaulTarget, ConstructorInd)); //Carry ingredient to the bill giver yield return(Toils_Goto.GotoThing(ConstructorInd, PathEndMode.InteractionCell) .FailOnDestroyedOrNull(ConstructorInd)); //Place ingredient on the appropriate cell Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(ConstructorInd, IngredientInd, IngredientPlaceCellInd); yield return(findPlaceTarget); yield return(Toils_FillThingIntoConstructor(this.pawn)); //yield return Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellInd, // nextToilOnPlaceFailOrIncomplete: findPlaceTarget, // storageMode: false); //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientInd, extract)); } yield return(gotoBillGiver); }
protected override IEnumerable <Toil> MakeNewToils() { //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils is called"); float partner_ability = xxx.get_sex_ability(Partner); // More/less hearts based on partner ability. if (partner_ability < 0.8f) { tick_interval += 100; } else if (partner_ability > 2.0f) { tick_interval -= 25; } // More/less hearts based on opinion. if (pawn.relations.OpinionOf(Partner) < 0) { tick_interval += 50; } else if (pawn.relations.OpinionOf(Partner) > 60) { tick_interval -= 25; } if (Partner.CurJob.def == xxx.casual_sex) { this.FailOnDespawnedOrNull(ipartner); this.FailOn(() => !Partner.health.capacities.CanBeAwake); this.FailOn(() => pawn.Drafted); this.KeepLyingDown(ibed); yield return(Toils_Reserve.Reserve(ipartner, 1, 0)); yield return(Toils_Reserve.Reserve(ibed, Bed.SleepingSlotsCount, 0)); Toil get_loved = Toils_LayDown.LayDown(ibed, true, false, false, false); get_loved.FailOn(() => Partner.CurJob == null || Partner.CurJob.def != xxx.casual_sex); get_loved.defaultCompleteMode = ToilCompleteMode.Never; get_loved.AddPreTickAction(delegate { if (pawn.IsHashIntervalTick(tick_interval)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); xxx.sexTick(pawn, Partner); } }); get_loved.socialMode = RandomSocialMode.Off; yield return(get_loved); } else if (Partner.CurJob.def == xxx.whore_is_serving_visitors) { this.FailOnDespawnedOrNull(ipartner); this.FailOn(() => !Partner.health.capacities.CanBeAwake || Partner.CurJob == null); yield return(Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell)); yield return(Toils_Reserve.Reserve(ipartner, 1, 0)); Toil get_loved = new Toil(); get_loved.FailOn(() => (Partner.CurJob.def != xxx.whore_is_serving_visitors)); get_loved.defaultCompleteMode = ToilCompleteMode.Never; get_loved.initAction = delegate { //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils - w***e section is called"); }; get_loved.AddPreTickAction(delegate { if (pawn.IsHashIntervalTick(tick_interval)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); xxx.sexTick(pawn, Partner); } }); get_loved.socialMode = RandomSocialMode.Off; yield return(get_loved); } else if (Partner.CurJob.def == xxx.bestialityForFemale) { this.FailOnDespawnedOrNull(ipartner); this.FailOn(() => !Partner.health.capacities.CanBeAwake || Partner.CurJob == null); yield return(Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell)); yield return(Toils_Reserve.Reserve(ipartner, 1, 0)); Toil get_loved = new Toil(); get_loved.FailOn(() => (Partner.CurJob.def != xxx.bestialityForFemale)); get_loved.defaultCompleteMode = ToilCompleteMode.Never; get_loved.initAction = delegate { //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils - bestialityForFemale section is called"); }; get_loved.AddPreTickAction(delegate { if (pawn.IsHashIntervalTick(tick_interval)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); xxx.sexTick(pawn, Partner); } }); get_loved.socialMode = RandomSocialMode.Off; yield return(get_loved); } }
protected override IEnumerable <Toil> MakeNewToils() { const float baseFishingDuration = 1600f; const float catchSuccessRateOnPier = 0.90f; const float skillGainPerTick = 0.15f; int fishingDuration = (int)baseFishingDuration; Building_FishingPier fishingPier = this.TargetThingA as Building_FishingPier; Passion passion = Passion.None; int thrownCornCount = 0; int nextCornThrowTick = 0; this.FailOnBurningImmobile(fishingPierIndex); // Drawing. this.rotateToFace = TargetIndex.B; this.pawn.CurJob.SetTarget(TargetIndex.C, fishingPier.riverCell); TargetIndex riverCellIndex = TargetIndex.C; // Compute fishing duration. float fishingSkillLevel = 0f; fishingSkillLevel = this.pawn.skills.AverageOfRelevantSkillsFor(WorkTypeDefOf.Hunting); float fishingSkillDurationFactor = fishingSkillLevel / 20f; fishingDuration = (int)(baseFishingDuration * (1.5f - fishingSkillDurationFactor)); yield return(Toils_Goto.GotoThing(fishingPierIndex, fishingPier.riverCell).FailOn(FishingForbiddenOrPierDestroyedOrNoFish)); Toil attractfishesToil = new Toil() { tickAction = () => { if (fishingPier.allowUsingCorn == false) { this.ReadyForNextToil(); return; } if (Find.TickManager.TicksGame >= nextCornThrowTick) { nextCornThrowTick = Find.TickManager.TicksGame + 3 * GenTicks.TicksPerRealSecond; // Look for corn in inventory. Thing corn = null; foreach (Thing thing in this.pawn.inventory.innerContainer) { if (thing.def == Util_FishIndustry.RawCornDef) { corn = thing; break; } } if ((corn == null) || (thrownCornCount >= cornCountToAttractFishes)) { fishingDuration -= Mathf.CeilToInt((float)fishingDuration * 0.75f * ((float)thrownCornCount / (float)cornCountToAttractFishes)); this.ReadyForNextToil(); return; } // Throw corn grains. thrownCornCount++; this.pawn.inventory.innerContainer.Take(corn, 1); for (int cornGrainIndex = 0; cornGrainIndex < 5; cornGrainIndex++) { if (!this.pawn.Position.ShouldSpawnMotesAt(this.pawn.Map) || this.pawn.Map.moteCounter.Saturated) { break; } float speed = Rand.Range(1.5f, 3f); Vector3 targetPosition = this.pawn.Position.ToVector3Shifted() + new Vector3(0f, 0f, 2f).RotatedBy(fishingPier.Rotation.AsAngle) + Vector3Utility.RandomHorizontalOffset(1.5f); targetPosition.y = this.pawn.DrawPos.y; MoteThrown moteThrown = (MoteThrown)ThingMaker.MakeThing(ThingDefOf.Mote_Stone, null); moteThrown.Scale = 0.2f; moteThrown.rotationRate = (float)Rand.Range(-300, 300); moteThrown.exactPosition = this.pawn.DrawPos; moteThrown.SetVelocity((targetPosition - moteThrown.exactPosition).AngleFlat(), speed); moteThrown.airTimeLeft = (float)Mathf.RoundToInt((moteThrown.exactPosition - targetPosition).MagnitudeHorizontal() / speed); GenSpawn.Spawn(moteThrown, this.pawn.Position, this.pawn.Map); MoteMaker.MakeWaterSplash(targetPosition, this.pawn.Map, 1.8f, 0.5f); } } }, defaultDuration = fishingDuration, defaultCompleteMode = ToilCompleteMode.Delay }; yield return(attractfishesToil.FailOn(FishingForbiddenOrPierDestroyedOrNoFish)); Toil fishToil = new Toil() { initAction = () => { ThingDef moteDef = null; if (fishingPier.Rotation == Rot4.North) { moteDef = Util_FishIndustry.MoteFishingRodNorthDef; } else if (fishingPier.Rotation == Rot4.East) { moteDef = Util_FishIndustry.MoteFishingRodEastDef; } else if (fishingPier.Rotation == Rot4.South) { moteDef = Util_FishIndustry.MoteFishingRodSouthDef; } else { moteDef = Util_FishIndustry.MoteFishingRodWestDef; } this.fishingRodMote = (Mote)ThingMaker.MakeThing(moteDef, null); this.fishingRodMote.exactPosition = fishingPier.fishingSpotCell.ToVector3Shifted(); this.fishingRodMote.Scale = 1f; GenSpawn.Spawn(this.fishingRodMote, fishingPier.fishingSpotCell, this.Map); }, tickAction = () => { if (passion == Passion.Minor) { this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMinor, JoyKindDefOf.Work); } else if (passion == Passion.Major) { this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMajor, JoyKindDefOf.Work); } this.pawn.skills.Learn(SkillDefOf.Shooting, skillGainPerTick); if (this.fishingRodMote != null) { this.fishingRodMote.Maintain(); } }, defaultDuration = fishingDuration, defaultCompleteMode = ToilCompleteMode.Delay }; yield return(fishToil.WithProgressBarToilDelay(riverCellIndex).FailOn(FishingForbiddenOrPierDestroyedOrNoFish)); Toil catchFishToil = new Toil() { initAction = () => { Thing fishingCatch = null; bool catchIsSuccessful = (Rand.Value <= catchSuccessRateOnPier); if (catchIsSuccessful == false) { MoteMaker.ThrowMetaIcon(this.pawn.Position, this.Map, ThingDefOf.Mote_IncapIcon); this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); return; } float catchSelectorValue = Rand.Value; if (catchSelectorValue < 0.02) { float bonusCatchValue = Rand.Value; if (bonusCatchValue < 0.01f) { // Really small chance to find a sunken treasure!!! fishingCatch = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position, this.Map); fishingCatch.stackCount = Rand.RangeInclusive(58, 289); Thing treasureSilver = GenSpawn.Spawn(ThingDefOf.Silver, fishingPier.middleCell, this.Map); treasureSilver.stackCount = Rand.RangeInclusive(237, 2154); Find.LetterStack.ReceiveLetter("FishIndustry.LetterLabelSunkenTreasure".Translate(), "FishIndustry.SunkenTreasure".Translate(this.pawn.Name.ToStringShort.CapitalizeFirst()), LetterDefOf.PositiveEvent, this.pawn); } else if (bonusCatchValue < 0.02f) { // Really small chance to find a complete power armor set + sniper or charge rifle. Thing powerArmor = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmor"), this.pawn.Position, this.Map); fishingCatch = powerArmor; // Used to carry the power armor. Thing powerArmorHelmet = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmorHelmet"), this.pawn.Position, this.Map); Thing rifle = null; if (Rand.Value < 0.5f) { rifle = GenSpawn.Spawn(ThingDef.Named("Gun_ChargeRifle"), this.pawn.Position, this.Map); } else { rifle = GenSpawn.Spawn(ThingDef.Named("Gun_SniperRifle"), this.pawn.Position, this.Map); } CompQuality qualityComp = powerArmor.TryGetComp <CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } qualityComp = powerArmorHelmet.TryGetComp <CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } qualityComp = rifle.TryGetComp <CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } Faction faction = Find.FactionManager.FirstFactionOfDef(FactionDefOf.SpacerHostile); Pawn deadMarine = PawnGenerator.GeneratePawn(PawnKindDefOf.SpaceSoldier, faction); HealthUtility.DamageUntilDead(deadMarine); Corpse corpse = deadMarine.ParentHolder as Corpse; CompRottable rotComp = corpse.TryGetComp <CompRottable>(); if (rotComp != null) { rotComp.RotProgress = 20f * GenDate.TicksPerDay; // 20 days so the corpse is dessicated. } GenSpawn.Spawn(corpse, fishingPier.bankCell, this.Map); // TODO: set it as a translatble string. string eventText = this.pawn.Name.ToStringShort.CapitalizeFirst() + " has cought a dead body while fishing!\n\n'This is really disgusting but look at his gear! This guy was probably a MiningCo. security member. I wonder what happend to him...'\n"; Find.LetterStack.ReceiveLetter("Dead marine", eventText, LetterDefOf.PositiveEvent, this.pawn); } else { // Find a small amount of gold. fishingCatch = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position, this.Map); fishingCatch.stackCount = Rand.RangeInclusive(1, 7); } } else if (catchSelectorValue < 0.04) { // Find oysters. fishingCatch = GenSpawn.Spawn(Util_FishIndustry.OysterDef, this.pawn.Position, this.Map); fishingCatch.stackCount = Rand.RangeInclusive(2, 9); } else { // Catch a fish. IntVec3 fishSpot = fishingPier.aquaticCells.RandomElement(); bool fishSpotIsOcean = (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDefOf.WaterOceanShallow) || (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDefOf.WaterOceanDeep); bool fishSpotIsMarshy = (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDef.Named("Marsh")); PawnKindDef caugthFishDef = null; if (fishSpotIsOcean) { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome) where fishSpecies.livesInOcean select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality); } else if (fishSpotIsMarshy) { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome) where fishSpecies.livesInMarsh select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality); } else { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome) where fishSpecies.livesInRiver select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality); } Pawn caughtFish = PawnGenerator.GeneratePawn(caugthFishDef); ExecutionUtility.DoExecutionByCut(this.pawn, caughtFish); Corpse corpse = caughtFish.ParentHolder as Corpse; GenSpawn.Spawn(corpse, this.pawn.Position, this.Map); fishingCatch = corpse; fishingCatch.SetForbidden(false); if (caughtFish.BodySize >= 0.1f) { fishingPier.fishStock--; } } IntVec3 storageCell; if (StoreUtility.TryFindBestBetterStoreCellFor(fishingCatch, this.pawn, this.Map, StoragePriority.Unstored, this.pawn.Faction, out storageCell, true)) { this.pawn.Reserve(fishingCatch, this.job); this.pawn.Reserve(storageCell, this.job); this.pawn.CurJob.SetTarget(TargetIndex.B, storageCell); this.pawn.CurJob.SetTarget(TargetIndex.A, fishingCatch); this.pawn.CurJob.count = 9999; this.pawn.CurJob.haulMode = HaulMode.ToCellStorage; } else { this.pawn.jobs.EndCurrentJob(JobCondition.Succeeded); } } }; yield return(catchFishToil); yield return(Toils_Haul.StartCarryThing(TargetIndex.A)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); }
// Token: 0x0600006A RID: 106 RVA: 0x000045B4 File Offset: 0x000027B4 protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOn(delegate() { bool flag4 = !WorkGiver_WPTend.GoodLayingStatusForTend(this.Deliveree, this.pawn); bool result; if (flag4) { result = true; } else { bool flag5 = this.MedicineUsed != null; if (flag5) { bool flag6 = this.Deliveree.playerSettings == null; if (flag6) { return(true); } bool flag7 = !this.Deliveree.playerSettings.medCare.AllowsMedicine(this.MedicineUsed.def); if (flag7) { return(true); } } result = (this.pawn == this.Deliveree && (this.pawn.playerSettings == null || !this.pawn.playerSettings.selfTend)); } return(result); }); base.AddEndCondition(delegate { bool flag4 = HealthAIUtility.ShouldBeTendedNowByPlayer(this.Deliveree); JobCondition result; if (flag4) { result = JobCondition.Ongoing; } else { result = JobCondition.Succeeded; } return(result); }); this.FailOnAggroMentalState(TargetIndex.A); Toil reserveMedicine = null; bool flag = this.usesMedicine; if (flag) { reserveMedicine = Toils_Tend.ReserveMedicine(TargetIndex.B, this.Deliveree).FailOnDespawnedNullOrForbidden(TargetIndex.B); yield return(reserveMedicine); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B)); yield return(Toils_WPTend.PickupMedicine(TargetIndex.B, this.Deliveree).FailOnDestroyedOrNull(TargetIndex.B)); yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveMedicine, TargetIndex.B, TargetIndex.None, true, null)); } PathEndMode interactionCell = (this.Deliveree != this.pawn) ? PathEndMode.OnCell : PathEndMode.InteractionCell; Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, interactionCell); yield return(gotoToil); Toil toil = Toils_General.Wait((int)(1f / this.pawn.GetStatValue(StatDefOf.MedicalTendSpeed, true) * 600f), TargetIndex.None).FailOnCannotTouch(TargetIndex.A, interactionCell).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f).PlaySustainerOrSound(SoundDefOf.Interact_Tend); bool flag2 = this.pawn == this.Deliveree && this.pawn.Faction != Faction.OfPlayer; if (flag2) { toil.tickAction = delegate() { bool flag4 = this.pawn.IsHashIntervalTick(100) && !this.pawn.Position.Fogged(this.pawn.Map); if (flag4) { MoteMaker.ThrowMetaIcon(this.pawn.Position, this.pawn.Map, ThingDefOf.Mote_HealingCross); } }; } yield return(toil); yield return(Toils_WPTend.FinalizeTend(this.Deliveree)); bool flag3 = this.usesMedicine; if (flag3) { yield return(new Toil { initAction = delegate() { bool flag4 = this.MedicineUsed.DestroyedOrNull(); if (flag4) { Thing thing = HealthAIUtility.FindBestMedicine(this.pawn, this.Deliveree); bool flag5 = thing != null; if (flag5) { this.job.targetB = thing; this.JumpToToil(reserveMedicine); } } } }); } yield return(Toils_Jump.Jump(gotoToil)); yield break; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnThingMissingDesignation(TargetIndex.A, this.Designation); this.FailOnForbidden(TargetIndex.A); this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: { Toil doWork = new Toil().FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); doWork.initAction = delegate() { this.totalNeededWork = this.TotalNeededWork; this.workLeft = this.totalNeededWork; }; doWork.tickAction = delegate() { this.workLeft -= this.pawn.GetStatValue(StatDefOf.ConstructionSpeed, true); this.TickAction(); if (this.workLeft <= 0f) { doWork.actor.jobs.curDriver.ReadyForNextToil(); } }; doWork.defaultCompleteMode = ToilCompleteMode.Never; doWork.WithProgressBar(TargetIndex.A, () => 1f - this.workLeft / this.totalNeededWork, false, -0.5f); doWork.activeSkill = (() => SkillDefOf.Construction); this.$current = doWork; if (!this.$disposing) { this.$PC = 2; } return(true); } case 2u: { Toil finalize = new Toil(); finalize.initAction = delegate() { this.FinishedRemoving(); base.Map.designationManager.RemoveAllDesignationsOn(base.Target, false); }; finalize.defaultCompleteMode = ToilCompleteMode.Instant; this.$current = finalize; if (!this.$disposing) { this.$PC = 3; } return(true); } case 3u: this.$PC = -1; break; } return(false); }
static IEnumerable <Toil> DoMakeToils(JobDriver_DoBill_Access __instance) { //normal scenario __instance.AddEndCondition(delegate { Thing thing = __instance.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); __instance.FailOnBurningImmobile(TargetIndex.A); __instance.FailOn(delegate() { if (__instance.job.GetTarget(TargetIndex.A).Thing is Filth) { return(false); } IBillGiver billGiver = __instance.job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (__instance.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate() { if (__instance.job.targetQueueB != null && __instance.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = __instance.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)__instance.job.bill; } } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); //hauling patch if (Settings.adv_haul_all_ings && __instance.pawn.Faction == Faction.OfPlayer) { Toil checklist = new Toil(); checklist.initAction = delegate() { Pawn actor = checklist.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (targetQueue.NullOrEmpty()) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { foreach (var target in (targetQueue)) { if (target == null || target.Thing.DestroyedOrNull()) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); break; } } } }; yield return(checklist); Toil extract = new Toil(); extract.initAction = delegate() { Pawn actor = extract.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (!curJob.countQueue.NullOrEmpty()) { if (curJob.countQueue[0] > targetQueue[0].Thing.stackCount) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { curJob.SetTarget(TargetIndex.B, targetQueue[0]); targetQueue.RemoveAt(0); curJob.count = curJob.countQueue[0]; curJob.countQueue.RemoveAt(0); } } }; Toil PickUpThing; List <LocalTargetInfo> L = __instance.job.GetTargetQueue(TargetIndex.B); if (L.Count < 2 && (L.Count == 0 || L[0].Thing.def.stackLimit < 2)) { PickUpThing = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true); } else { PickUpThing = new Toil(); PickUpThing.initAction = delegate() { Pawn actor = PickUpThing.actor; Job curJob = actor.jobs.curJob; Thing thing = curJob.GetTarget(TargetIndex.B).Thing; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); bool InventorySpawned = thing.ParentHolder == actor.inventory; if (InventorySpawned || !Toils_Haul.ErrorCheckForCarry(actor, thing)) { if (thing.stackCount < curJob.count) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { Thing splitThing = thing.SplitOff(curJob.count); if (splitThing.ParentHolder != actor.inventory && !actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, false)) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } if (!splitThing.Destroyed && splitThing.stackCount != 0) { targetQueue.Add(splitThing); if (!InventorySpawned) { CompUnloadChecker CUC = splitThing.TryGetComp <CompUnloadChecker>(); if (CUC != null) { CUC.ShouldUnload = true; } } } if (splitThing != thing && actor.Map.reservationManager.ReservedBy(thing, actor, curJob)) { actor.Map.reservationManager.Release(thing, actor, curJob); } } } }; } Toil TakeToHands = new Toil(); TakeToHands.initAction = delegate() { Pawn actor = TakeToHands.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (!targetQueue.NullOrEmpty() && targetQueue[0].Thing.ParentHolder != actor.carryTracker) { actor.inventory.innerContainer.TryTransferToContainer(targetQueue[0].Thing, actor.carryTracker.innerContainer); actor.Reserve(targetQueue[0], curJob); curJob.SetTarget(TargetIndex.B, targetQueue[0]); targetQueue.RemoveAt(0); } }; yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(Toils_Jump.JumpIf(PickUpThing, () => __instance.job.GetTarget(TargetIndex.B).Thing.ParentHolder == __instance.pawn.inventory)); yield return(getToHaulTarget); yield return(PickUpThing); yield return(Toils_Jump.JumpIf(extract, () => !__instance.job.countQueue.NullOrEmpty())); yield return(TakeToHands); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, TakeToHands)); } else { Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(JobDriver_DoBill_Access.JumpToCollectNextIntoHandsForBillCrutch(getToHaulTarget, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); } yield return(gotoBillGiver); //one line from normal scenario //cleaning patch if (Settings.adv_cleaning && !Utility.IncapableOfCleaning(__instance.pawn)) { Toil returnToBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); Toil FilthList = new Toil(); FilthList.initAction = delegate() { Job curJob = FilthList.actor.jobs.curJob; if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty()) { LocalTargetInfo A = curJob.GetTarget(TargetIndex.A); DoCleanComp comp; if (!Settings.clean_gizmo || (comp = A.Thing?.TryGetComp <DoCleanComp>()) != null && comp.Active) { IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num); Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor); FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob); } curJob.targetQueueA.Add(A); } }; yield return(FilthList); yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty())); Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null); yield return(CleanFilthList); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true)); yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty())); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList)); Toil clean = new Toil(); clean.initAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; __instance.billStartTick = 0; __instance.ticksSpentDoingRecipeWork = 0; __instance.workLeft = filth.def.filth.cleaningWorkToReduceThickness * filth.thickness; }; clean.tickAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; __instance.billStartTick += 1; __instance.ticksSpentDoingRecipeWork += 1; if (__instance.billStartTick > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); __instance.billStartTick = 0; if (filth.Destroyed) { clean.actor.records.Increment(RecordDefOf.MessesCleaned); __instance.ReadyForNextToil(); return; } } }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A); clean.WithProgressBar(TargetIndex.A, () => __instance.ticksSpentDoingRecipeWork / __instance.workLeft, true, -0.5f); clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList); clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList); yield return(clean); yield return(Toils_Jump.Jump(CleanFilthList)); yield return(returnToBillGiver); } //continuation of normal scenario yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct()); if (!__instance.job.RecipeDef.products.NullOrEmpty() || !__instance.job.RecipeDef.specialProducts.NullOrEmpty()) { yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); Toil recount = new Toil(); recount.initAction = delegate() { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { __instance.MapCrutch().resourceCounter.UpdateResourceCounts(); } }; yield return(recount); } yield break; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOnBurningImmobile(TargetIndex.A); base.AddEndCondition(() => (base.Barrel.SpaceLeftForWort > 0) ? JobCondition.Ongoing : JobCondition.Succeeded); this.$current = Toils_General.DoAtomic(delegate { this.job.count = base.Barrel.SpaceLeftForWort; }); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: reserveWort = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); this.$current = reserveWort; if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: this.$current = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.B, false, true, false).FailOnDestroyedNullOrForbidden(TargetIndex.B); if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$current = Toils_Haul.CheckForGetOpportunityDuplicate(reserveWort, TargetIndex.B, TargetIndex.None, true, null); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$current = Toils_General.Wait(200, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.B).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: { Toil finalize = new Toil(); finalize.initAction = delegate() { base.Barrel.AddWort(base.Wort); }; finalize.defaultCompleteMode = ToilCompleteMode.Instant; this.$current = finalize; if (!this.$disposing) { this.$PC = 8; } return(true); } case 8u: this.$PC = -1; break; } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { if (fishCaught == null) { this.EndJobWith(JobCondition.Incompletable); fishingZone.someoneFishing = false; } this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOnBurningImmobile(TargetIndex.A); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch)); this.pawn.rotationTracker.FaceTarget(base.TargetA); Toil fishToil = new Toil(); fishToil.tickAction = delegate() { this.pawn.skills.Learn(SkillDefOf.Animals, skillGainperTick); if (fishingZone != null) { if (!fishingZone.isZoneBigEnough) { this.EndJobWith(JobCondition.Incompletable); fishingZone.someoneFishing = false; } } }; Rot4 pawnRotation = pawn.Rotation; IntVec3 facingCell = pawnRotation.FacingCell; if (facingCell == new IntVec3(0, 0, 1)) { //Log.Message("Looking north"); fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectNorth"), () => this.TargetA.Cell + new IntVec3(0, 0, 1)); } else if (facingCell == new IntVec3(1, 0, 0)) { // Log.Message("Looking east"); fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectEast"), () => this.TargetA.Cell + new IntVec3(1, 0, 0)); } else if (facingCell == new IntVec3(0, 0, -1)) { // Log.Message("Looking south"); fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectSouth"), () => this.TargetA.Cell + new IntVec3(0, 0, -1)); } else if (facingCell == new IntVec3(-1, 0, 0)) { // Log.Message("Looking west"); fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectWest"), () => this.TargetA.Cell + new IntVec3(-1, 0, 0)); } fishToil.defaultCompleteMode = ToilCompleteMode.Delay; switch (sizeAtBeginning) { case FishSizeCategory.Small: fishToil.defaultDuration = (int)(-150 * fishingSkill + smallFishDurationFactor * 1.5); break; case FishSizeCategory.Medium: fishToil.defaultDuration = (int)(-300 * fishingSkill + mediumFishDurationFactor * 1.5); break; case FishSizeCategory.Large: fishToil.defaultDuration = (int)(-450 * fishingSkill + largeFishDurationFactor * 1.5); break; default: fishToil.defaultDuration = mediumFishDurationFactor; break; } //Log.Message(fishToil.defaultDuration.ToString()); fishToil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); yield return(fishToil.WithProgressBarToilDelay(TargetIndex.A, true)); yield return(new Toil { initAction = delegate { Thing newFish = ThingMaker.MakeThing(fishCaught); newFish.stackCount = fishAmountWithSkill; GenSpawn.Spawn(newFish, this.TargetA.Cell - GenAdj.CardinalDirections[0], this.Map); StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(newFish); IntVec3 c; if (StoreUtility.TryFindBestBetterStoreCellFor(newFish, this.pawn, this.Map, currentPriority, this.pawn.Faction, out c, true)) { this.job.SetTarget(TargetIndex.C, c); this.job.SetTarget(TargetIndex.B, newFish); this.job.count = newFish.stackCount; fishingZone.someoneFishing = false; } else { this.EndJobWith(JobCondition.Incompletable); fishingZone.someoneFishing = false; } }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, false, false)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, true)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { base.AddFinishAction(delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); }); Toil prepareToEatCorpse = new Toil(); prepareToEatCorpse.initAction = delegate() { Pawn actor = prepareToEatCorpse.actor; Corpse corpse = this.Corpse; if (corpse == null) { Pawn prey = this.Prey; if (prey == null) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } corpse = prey.Corpse; if (corpse == null || !corpse.Spawned) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } } if (actor.Faction == Faction.OfPlayer) { corpse.SetForbidden(false, false); } else { corpse.SetForbidden(true, false); } actor.CurJob.SetTarget(TargetIndex.A, corpse); }; yield return(Toils_General.DoAtomic(delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); })); Action onHitAction = delegate() { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelIndefinite() }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true); } this.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f)); yield return(prepareToEatCorpse); Toil gotoCorpse = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoCorpse); float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); yield return(Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A)); yield return(Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f)); yield break; }