protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (this.pawn.meleeVerbs.TryMeleeAttack(thing, this.job.verbToUse, false)) { if (this.pawn.CurJob == null || this.pawn.jobs.curDriver != this) { return; } this.numMeleeAttacksMade++; if (thing.GetType() == typeof(Pawn)) { Pawn targetPawn = thing as Pawn; targetPawn.health.AddHediff(HediffDef.Named("GR_ChickenRimPox")); HealthUtility.AdjustSeverity(targetPawn, HediffDef.Named("GR_ChickenRimPox"), 0.3f); } if (this.numMeleeAttacksMade >= 1) { this.EndJobWith(JobCondition.Succeeded); pawn.drafter.Drafted = false; return; } } }).FailOnDespawnedOrNull(TargetIndex.A)); }
// Token: 0x06003B77 RID: 15223 RVA: 0x001BFC0C File Offset: 0x001BE00C protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.DoAtomic(delegate { Pawn pawn = this.job.targetA.Thing as Pawn; if (pawn != null && pawn.Downed && this.pawn.mindState.duty != null && this.pawn.mindState.duty.attackDownedIfStarving && this.pawn.Starving()) { this.job.killIncappedTarget = true; } })); yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (this.pawn.meleeVerbs.TryMeleeAttack(thing, this.job.verbToUse, false)) { if (this.pawn.CurJob == null || this.pawn.jobs.curDriver != this) { return; } this.numMeleeAttacksMade++; if (this.numMeleeAttacksMade >= this.job.maxNumMeleeAttacks) { base.EndJobWith(JobCondition.Succeeded); return; } } }).FailOnDespawnedOrNull(TargetIndex.A)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.DoAtomic(delegate { Pawn pawn = job.targetA.Thing as Pawn; //if (pawn != null && pawn.Downed && base.pawn.mindState.duty != null && base.pawn.mindState.duty.attackDownedIfStarving && base.pawn.Starving()) //{ job.killIncappedTarget = true; //} })); yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { Thing thing = job.GetTarget(TargetIndex.A).Thing; Pawn p; //if (job.reactingToMeleeThreat && (p = (thing as Pawn)) != null && !p.Awake()) //{ // EndJobWith(JobCondition.InterruptForced); //} InteractionUtility.TryGetRandomVerbForSocialFight(base.pawn, out Verb verb); if (BeatDecider.shouldStopBeating(base.pawn, base.TargetA.Thing as Pawn)) { EndJobWith(JobCondition.Succeeded); } else { pawn.meleeVerbs.TryMeleeAttack(thing, verb); } }).FailOnDespawnedOrNull(TargetIndex.A));
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Reserve.Reserve(TargetIndex.A)); void onHitAction() { Pawn prey = Prey; bool surpriseAttack = firstHit && !prey.IsColonist; Job tjob = prey.CurJob; if (pawn.needs.food.CurLevelPercentage < 1 && !prey.Dead && pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { float new_food = pawn.needs.food.CurLevelPercentage + 0.5f; if (new_food > 1) { new_food = 1; } pawn.needs.food.CurLevelPercentage = new_food; if (prey.Dead) { return; } prey.stances.stunner.StunFor(700, pawn); IEnumerable <Hediff> visibleDiffs = prey.health.hediffSet.hediffs; List <Hediff> toremove = new List <Hediff>(); foreach (Hediff h in visibleDiffs) { if ((h.source == pawn.def || (h.def == HediffDefOf.MissingBodyPart && h.ageTicks < 100)) && h.def != HediffDefOf.BloodLoss) { toremove.Add(h); } } foreach (Hediff h in toremove) { prey.health.RemoveHediff(h); } prey.jobs.StartJob(tjob, JobCondition.InterruptForced); } else { if (Math.Abs(pawn.needs.food.CurLevelPercentage - 1) < float.Epsilon) { pawn.jobs.curDriver.ReadyForNextToil(); } } firstHit = false; } yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction)); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (this.pawn.meleeVerbs.TryMeleeAttack(thing, this.job.verbToUse, false)) { if (this.pawn.CurJob == null || this.pawn.jobs.curDriver != this) { return; } this.numMeleeAttacksMade++; if (this.numMeleeAttacksMade >= this.job.maxNumMeleeAttacks) { this.EndJobWith(JobCondition.Succeeded); return; } } }).FailOnDespawnedOrNull(TargetIndex.A)); }
protected override IEnumerable <Toil> MakeNewToils() { base.AddFinishAction(delegate { this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); }); Toil prepareToEatCorpse = new Toil(); prepareToEatCorpse.initAction = delegate { Pawn actor = prepareToEatCorpse.actor; Corpse corpse = this.$this.Corpse; if (corpse == null) { Pawn prey = this.$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.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); })); Action onHitAction = delegate { Pawn prey = this.$this.Prey; bool surpriseAttack = this.$this.firstHit && !prey.IsColonist; if (this.$this.pawn.meleeVerbs.TryMeleeAttack(prey, this.$this.job.verbToUse, surpriseAttack)) { if (!this.$this.notifiedPlayerAttacked && PawnUtility.ShouldSendNotificationAbout(prey)) { this.$this.notifiedPlayerAttacked = true; Messages.Message("MessageAttackedByPredator".Translate(prey.LabelShort, this.$this.pawn.LabelIndefinite(), prey.Named("PREY"), this.$this.pawn.Named("PREDATOR")).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true); } this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); this.$this.firstHit = false; } }; Toil followAndAttack = Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.$this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.$this.startTick + 5000 && (float)(this.$this.job.GetTarget(TargetIndex.A).Cell - this.$this.pawn.Position).LengthHorizontalSquared > 4f); followAndAttack.AddPreTickAction(new Action(this.CheckWarnPlayer)); yield return(followAndAttack); 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.$this.pawn.needs.food.CurLevelPercentage < 0.9f)); }
public override IEnumerable <Toil> MakeNewToils() { this.FailOn(delegate { if (!job.ignoreDesignations) { Pawn victim = Victim; if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } } return(false); }); yield return(Toils_Reserve.Reserve(VictimInd, 1)); var init = new Toil(); init.initAction = delegate { jobStartTick = Find.TickManager.TicksGame; }; yield return(init); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); var comp = (pawn.equipment != null && pawn.equipment.Primary != null) ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null; var startCollectCorpse = StartCollectCorpseToil(); var gotoCastPos = GotoCastPosition(VictimInd, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > jobStartTick + MaxHuntTicks); yield return(gotoCastPos); //var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(VictimInd, gotoCastPos); var moveIfCannotHit = Toils_Jump.JumpIf(gotoCastPos, delegate { var verb = pawn.CurJob.verbToUse; var optimalRange = GetOptimalHuntRange(pawn, Victim); if (pawn.Position.DistanceTo(Victim.Position) > optimalRange) { return(true); } return(!verb.CanHitTarget(Victim)); }); yield return(moveIfCannotHit); yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(VictimInd, startCollectCorpse)); var startExecuteDowned = Toils_Goto.GotoThing(VictimInd, PathEndMode.Touch).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse); yield return(Toils_Jump.JumpIf(startExecuteDowned, () => Victim.Downed && Victim.RaceProps.executionRange <= 2)); if (pawn?.equipment?.PrimaryEq?.PrimaryVerb?.IsMeleeAttack ?? false) { yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { pawn.meleeVerbs.TryMeleeAttack(Victim); }).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)); } else { yield return(Toils_Combat.CastVerb(VictimInd, false).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse) .FailOn(() => { if (Find.TickManager.TicksGame <= jobStartTick + MaxHuntTicks) { if (comp == null || comp.HasAndUsesAmmoOrMagazine) { return false; } } return true; })); yield return(Toils_Jump.Jump(moveIfCannotHit)); } yield return(Toils_Jump.Jump(moveIfCannotHit)); // Execute downed animal - adapted from JobDriver_Slaughter yield return(startExecuteDowned); yield return(Toils_General.WaitWith(VictimInd, 180, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)); yield return(new Toil { initAction = delegate { ExecutionUtility.DoExecutionByCut(pawn, Victim); }, defaultCompleteMode = ToilCompleteMode.Instant }); // Haul corpse to stockpile yield return(startCollectCorpse); yield return(Toils_Goto.GotoCell(VictimInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(VictimInd).FailOnSomeonePhysicallyInteracting(VictimInd)); yield return(Toils_Haul.StartCarryThing(VictimInd)); var carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true)); }
protected override IEnumerable <Toil> MakeNewToils() { Toil beatingContinues = Toils_General.Label(); Toil beatingComplete = Toils_General.Label(); Toil beatingCancelled = Toils_General.Label(); yield return(Toils_General.Do(delegate { Messages.Message("CM_Beat_Prisoners_Break_Attempt".Translate(pawn, Victim), Victim, MessageTypeDefOf.NeutralEvent); })); yield return(beatingContinues); yield return(GotoPrisoner(pawn, Victim)); yield return(Toils_Interpersonal.GotoInteractablePosition(TargetIndex.A)); yield return(ThreatenPrisoner(pawn, Victim)); yield return(Toils_General.Do(delegate { BeatingInProgress beating = Current.Game.World.GetComponent <BeatingTracker>()?.GetOrStartBeatingInProgress(Victim, pawn); if (beating != null) { beating.TryFightBack(); } })); yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate { if (Victim == null || !Victim.Spawned || Victim.InMentalState || !Victim.IsPrisonerOfColony || !Victim.guest.PrisonerIsSecure || Victim.guest.interactionMode != PrisonerInteractionModeDefOf.ReduceResistance) { pawn.jobs.curDriver.JumpToToil(beatingCancelled); } if (Victim.Downed) { pawn.jobs.curDriver.JumpToToil(beatingComplete); } if (pawn.meleeVerbs.TryMeleeAttack(Victim, job.verbToUse) && pawn.CurJob != null && pawn.jobs.curDriver == this) { numMeleeAttacksMade++; BeatingInProgress beating = Current.Game.World.GetComponent <BeatingTracker>()?.GetBeatingInProgress(Victim); // Keep going if there is a fight, otherwise do the requested number of attacks if ((beating != null && beating.fightingBack) || numMeleeAttacksMade < job.maxNumMeleeAttacks) { pawn.jobs.curDriver.JumpToToil(beatingContinues); } else { pawn.jobs.curDriver.JumpToToil(beatingComplete); } } })); yield return(beatingComplete); Toil giveThoughts = Toils_General.Do(delegate { pawn.records.Increment(BeatPrisonersDefOf.CM_Beat_Prisoners_Record_Prisoners_Beaten); BeatPrisonersUtility.GiveThoughtsForPrisonerBeaten(Victim, pawn); // This never seems to get called, because if the initiator goes down, the job is interrupted // Leaving it anyway to show desired behavior. This needs to go in JobDriver_Patches for Cleanup if (pawn.Downed || pawn.Dead) { // If this became a fight, losing might trigger a prison break Current.Game.World.GetComponent <BeatingTracker>()?.BeaterDowned(Victim, pawn); pawn.jobs.curDriver.JumpToToil(beatingCancelled); } }); yield return(giveThoughts); //yield return Toils_Interpersonal.SetLastInteractTime(TargetIndex.A); yield return(BreakResistance(TargetIndex.A)); yield return(beatingCancelled); yield return(Toils_General.Do(delegate { Current.Game.World.GetComponent <BeatingTracker>()?.StopBeating(Victim, pawn); })); }
protected override IEnumerable <Toil> MakeNewToils() { // Toil toil = new Toil(); toil.initAction = delegate { //Empty }; this.EndOnDespawnedOrNull(InquisitorIndex, JobCondition.Incompletable); this.EndOnDespawnedOrNull(PreacherIndex, JobCondition.Incompletable); //this.EndOnDespawnedOrNull(Build, JobCondition.Incompletable); yield return(Toils_Reserve.Reserve(PreacherIndex, this.job.def.joyMaxParticipants)); Toil gotoPreacher; gotoPreacher = Toils_Goto.GotoThing(PreacherIndex, PathEndMode.ClosestTouch); yield return(gotoPreacher); if (Preacher.jobs.curDriver.asleep) { Toil watchToil = new Toil(); watchToil.defaultCompleteMode = ToilCompleteMode.Delay; watchToil.defaultDuration = this.job.def.joyDuration; watchToil.AddPreTickAction(() => { this.pawn.rotationTracker.FaceCell(Preacher.Position); this.pawn.GainComfortFromCellIfPossible(); }); yield return(watchToil); } Action hitAction = delegate { Pawn prey = Preacher; bool surpriseAttack = this.firstHit; if (pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; if (Prefs.PauseOnUrgentLetter && !Find.TickManager.Paused) { Find.TickManager.TogglePaused(); } Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelShort, }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig); } this.pawn.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, hitAction).JumpIfDespawnedOrNull(TargetIndex.A, toil).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f)); yield return(toil); this.AddFinishAction(() => { //if (this.TargetB.HasThing) //{ // Find.Reservations.Release(this.job.targetC.Thing, pawn); //} }); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Reserve.Reserve(TargetIndex.A)); //Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); //gotoToil.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 = "Hunting"; //})); //yield return gotoToil; Action onHitAction = delegate { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; Job tjob = prey.CurJob; if (this.pawn.needs.food.CurLevelPercentage < 1 && !prey.Dead && this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { float new_food = this.pawn.needs.food.CurLevelPercentage + 0.5f; if (new_food > 1) { new_food = 1; } this.pawn.needs.food.CurLevelPercentage = new_food; if (prey.Dead) { return; } prey.stances.stunner.StunFor((int)700); IEnumerable <Hediff> visibleDiffs = prey.health.hediffSet.hediffs; List <Hediff> toremove = new List <Hediff>(); foreach (Hediff h in visibleDiffs) { if ((h.source == this.pawn.def || (h.def == HediffDefOf.MissingBodyPart && h.ageTicks < 100)) && h.def != HediffDefOf.BloodLoss) { toremove.Add(h); } } foreach (Hediff h in toremove) { prey.health.RemoveHediff(h); } prey.jobs.StartJob(tjob, JobCondition.InterruptForced); } else { if (Math.Abs(this.pawn.needs.food.CurLevelPercentage - 1) < float.Epsilon) { this.pawn.jobs.curDriver.ReadyForNextToil(); } } this.firstHit = false; }; yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction)); }