private ThinkResult DetermineNextJob(out ThinkTreeDef thinkTree) { ThinkResult thinkResult = this.DetermineNextConstantThinkTreeJob(); ThinkResult result; if (thinkResult.Job != null) { thinkTree = this.pawn.thinker.ConstantThinkTree; result = thinkResult; } else { ThinkResult thinkResult2 = ThinkResult.NoJob; try { Profiler.BeginSample("Determine next job (main)"); thinkResult2 = this.pawn.thinker.MainThinkNodeRoot.TryIssueJobPackage(this.pawn, default(JobIssueParams)); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, this.pawn.ToStringSafe <Pawn>() + " threw exception while determining job (main)", exception, null); thinkTree = null; return(ThinkResult.NoJob); } finally { Profiler.EndSample(); } thinkTree = this.pawn.thinker.MainThinkTree; result = thinkResult2; } return(result); }
private ThinkResult DetermineNextConstantThinkTreeJob() { ThinkResult noJob; if (this.pawn.thinker.ConstantThinkTree == null) { noJob = ThinkResult.NoJob; } else { try { Profiler.BeginSample("Determine next job (constant)"); return(this.pawn.thinker.ConstantThinkNodeRoot.TryIssueJobPackage(this.pawn, default(JobIssueParams))); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, this.pawn.ToStringSafe <Pawn>() + " threw exception while determining job (constant)", exception, null); } finally { Profiler.EndSample(); } noJob = ThinkResult.NoJob; } return(noJob); }
private ThinkResult DetermineNextJob(out ThinkTreeDef thinkTree) { ThinkResult result = DetermineNextConstantThinkTreeJob(); if (result.Job != null) { thinkTree = pawn.thinker.ConstantThinkTree; return(result); } ThinkResult result2 = ThinkResult.NoJob; try { result2 = pawn.thinker.MainThinkNodeRoot.TryIssueJobPackage(pawn, default(JobIssueParams)); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, pawn.ToStringSafe() + " threw exception while determining job (main)", exception); thinkTree = null; return(ThinkResult.NoJob); } finally { } thinkTree = pawn.thinker.MainThinkTree; return(result2); }
private void FinalizeTick() { jobsGivenRecentTicks.Add(jobsGivenThisTick); jobsGivenRecentTicksTextual.Add(jobsGivenThisTickTextual); while (jobsGivenRecentTicks.Count > 10) { jobsGivenRecentTicks.RemoveAt(0); jobsGivenRecentTicksTextual.RemoveAt(0); } if (jobsGivenThisTick != 0) { int num = 0; for (int i = 0; i < jobsGivenRecentTicks.Count; i++) { num += jobsGivenRecentTicks[i]; } if (num >= 10) { string text = jobsGivenRecentTicksTextual.ToCommaList(); jobsGivenRecentTicks.Clear(); jobsGivenRecentTicksTextual.Clear(); JobUtility.TryStartErrorRecoverJob(pawn, pawn.ToStringSafe() + " started " + 10 + " jobs in " + 10 + " ticks. List: " + text); } } }
private void FinalizeTick() { this.jobsGivenRecentTicks.Add(this.jobsGivenThisTick); this.jobsGivenRecentTicksTextual.Add(this.jobsGivenThisTickTextual); while (this.jobsGivenRecentTicks.Count > 10) { this.jobsGivenRecentTicks.RemoveAt(0); this.jobsGivenRecentTicksTextual.RemoveAt(0); } if (this.jobsGivenThisTick != 0) { int num = 0; for (int i = 0; i < this.jobsGivenRecentTicks.Count; i++) { num += this.jobsGivenRecentTicks[i]; } if (num >= 10) { string text = this.jobsGivenRecentTicksTextual.ToCommaList(false); this.jobsGivenRecentTicks.Clear(); this.jobsGivenRecentTicksTextual.Clear(); JobUtility.TryStartErrorRecoverJob(this.pawn, string.Concat(new object[] { this.pawn.ToStringSafe <Pawn>(), " started ", 10, " jobs in ", 10, " ticks. List: ", text }), null, null); } } }
private bool CheckCurrentToilEndOrFail() { try { Toil curToil = CurToil; if (globalFailConditions != null) { for (int i = 0; i < globalFailConditions.Count; i++) { JobCondition jobCondition = globalFailConditions[i](); if (jobCondition != JobCondition.Ongoing) { if (pawn.jobs.debugLog) { pawn.jobs.DebugLogEvent(GetType().Name + " ends current job " + job.ToStringSafe() + " because of globalFailConditions[" + i + "]"); } EndJobWith(jobCondition); return(true); } } } if (curToil != null && curToil.endConditions != null) { for (int j = 0; j < curToil.endConditions.Count; j++) { JobCondition jobCondition2 = curToil.endConditions[j](); if (jobCondition2 != JobCondition.Ongoing) { if (pawn.jobs.debugLog) { pawn.jobs.DebugLogEvent(GetType().Name + " ends current job " + job.ToStringSafe() + " because of toils[" + curToilIndex + "].endConditions[" + j + "]"); } EndJobWith(jobCondition2); return(true); } } } return(false); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "Exception in CheckCurrentToilEndOrFail for pawn " + pawn.ToStringSafe(), exception, this); return(true); } }
private ThinkResult DetermineNextConstantThinkTreeJob() { if (this.pawn.thinker.ConstantThinkTree == null) { return(ThinkResult.NoJob); } try { return(this.pawn.thinker.ConstantThinkNodeRoot.TryIssueJobPackage(this.pawn, default(JobIssueParams))); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, this.pawn.ToStringSafe <Pawn>() + " threw exception while determining job (constant)", exception, null); } finally { } return(ThinkResult.NoJob); }
internal void SetupToils() { try { this.toils.Clear(); foreach (Toil toil in this.MakeNewToils()) { if (toil.defaultCompleteMode == ToilCompleteMode.Undefined) { Log.Error("Toil has undefined complete mode.", false); toil.defaultCompleteMode = ToilCompleteMode.Instant; } toil.actor = this.pawn; this.toils.Add(toil); } } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, "Exception in SetupToils for pawn " + this.pawn.ToStringSafe <Pawn>(), exception, this); } }
internal void SetupToils() { try { toils.Clear(); foreach (Toil item in MakeNewToils()) { if (item.defaultCompleteMode == ToilCompleteMode.Undefined) { Log.Error("Toil has undefined complete mode."); item.defaultCompleteMode = ToilCompleteMode.Instant; } item.actor = pawn; toils.Add(item); } } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "Exception in SetupToils for pawn " + pawn.ToStringSafe(), exception, this); } }
public void DriverTick() { try { this.ticksLeftThisToil--; this.debugTicksSpentThisToil++; if (this.CurToil == null) { if (!this.pawn.stances.FullBodyBusy || this.CanStartNextToilInBusyStance) { this.ReadyForNextToil(); } } else if (!this.CheckCurrentToilEndOrFail()) { if (this.curToilCompleteMode == ToilCompleteMode.Delay) { if (this.ticksLeftThisToil <= 0) { this.ReadyForNextToil(); return; } } else if (this.curToilCompleteMode == ToilCompleteMode.FinishedBusy) { if (!this.pawn.stances.FullBodyBusy) { this.ReadyForNextToil(); return; } } if (this.wantBeginNextToil) { this.TryActuallyStartNextToil(); } else if (this.curToilCompleteMode == ToilCompleteMode.Instant && this.debugTicksSpentThisToil > 300) { Log.Error(string.Concat(new object[] { this.pawn, " had to be broken from frozen state. He was doing job ", this.job, ", toilindex=", this.curToilIndex }), false); this.ReadyForNextToil(); } else { Job curJob = this.pawn.CurJob; if (this.CurToil.preTickActions != null) { Toil curToil = this.CurToil; for (int i = 0; i < curToil.preTickActions.Count; i++) { curToil.preTickActions[i](); if (this.pawn.CurJob != curJob) { return; } if (this.CurToil != curToil || this.wantBeginNextToil) { return; } } } if (this.CurToil.tickAction != null) { this.CurToil.tickAction(); } } } } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, "Exception in JobDriver tick for pawn " + this.pawn.ToStringSafe <Pawn>(), exception, this); } }
public void StartJob(Job newJob, JobCondition lastJobEndCondition = JobCondition.None, ThinkNode jobGiver = null, bool resumeCurJobAfterwards = false, bool cancelBusyStances = true, ThinkTreeDef thinkTree = null, JobTag?tag = null, bool fromQueue = false) { this.startingNewJob = true; try { if (!fromQueue && (!Find.TickManager.Paused || this.lastJobGivenAtFrame == RealTime.frameCount)) { this.jobsGivenThisTick++; this.jobsGivenThisTickTextual = this.jobsGivenThisTickTextual + "(" + newJob.ToString() + ") "; } this.lastJobGivenAtFrame = RealTime.frameCount; if (this.jobsGivenThisTick > 10) { string text = this.jobsGivenThisTickTextual; this.jobsGivenThisTick = 0; this.jobsGivenThisTickTextual = ""; this.startingNewJob = false; this.pawn.ClearReservationsForJob(newJob); JobUtility.TryStartErrorRecoverJob(this.pawn, string.Concat(new string[] { this.pawn.ToStringSafe <Pawn>(), " started 10 jobs in one tick. newJob=", newJob.ToStringSafe <Job>(), " jobGiver=", jobGiver.ToStringSafe <ThinkNode>(), " jobList=", text }), null, null); } else { if (this.debugLog) { this.DebugLogEvent(string.Concat(new object[] { "StartJob [", newJob, "] lastJobEndCondition=", lastJobEndCondition, ", jobGiver=", jobGiver, ", cancelBusyStances=", cancelBusyStances })); } if (cancelBusyStances && this.pawn.stances.FullBodyBusy) { this.pawn.stances.CancelBusyStanceHard(); } if (this.curJob != null) { if (lastJobEndCondition == JobCondition.None) { Log.Warning(string.Concat(new object[] { this.pawn, " starting job ", newJob, " from JobGiver ", this.pawn.mindState.lastJobGiver, " while already having job ", this.curJob, " without a specific job end condition." }), false); lastJobEndCondition = JobCondition.InterruptForced; } if (resumeCurJobAfterwards && this.curJob.def.suspendable) { this.jobQueue.EnqueueFirst(this.curJob, null); if (this.debugLog) { this.DebugLogEvent(" JobQueue EnqueueFirst curJob: " + this.curJob); } this.CleanupCurrentJob(lastJobEndCondition, false, cancelBusyStances); } else { this.CleanupCurrentJob(lastJobEndCondition, true, cancelBusyStances); } } if (newJob == null) { Log.Warning(this.pawn + " tried to start doing a null job.", false); } else { newJob.startTick = Find.TickManager.TicksGame; if (this.pawn.Drafted || newJob.playerForced) { newJob.ignoreForbidden = true; newJob.ignoreDesignations = true; } this.curJob = newJob; this.pawn.mindState.lastJobGiver = jobGiver; this.pawn.mindState.lastJobGiverThinkTree = thinkTree; this.curDriver = this.curJob.MakeDriver(this.pawn); if (this.curDriver.TryMakePreToilReservations()) { Job job = this.TryOpportunisticJob(newJob); if (job != null) { this.jobQueue.EnqueueFirst(newJob, null); this.curJob = null; this.curDriver = null; this.StartJob(job, JobCondition.None, null, false, true, null, null, false); } else { if (tag != null) { this.pawn.mindState.lastJobTag = tag.Value; } this.curDriver.SetInitialPosture(); this.curDriver.Notify_Starting(); this.curDriver.SetupToils(); this.curDriver.ReadyForNextToil(); } } else if (fromQueue) { this.EndCurrentJob(JobCondition.QueuedNoLongerValid, true); } else { Log.Warning("TryMakePreToilReservations() returned false for a non-queued job right after StartJob(). This should have been checked before. curJob=" + this.curJob.ToStringSafe <Job>(), false); this.EndCurrentJob(JobCondition.Errored, true); } } } } finally { this.startingNewJob = false; } }
public void StartJob(Job newJob, JobCondition lastJobEndCondition = JobCondition.None, ThinkNode jobGiver = null, bool resumeCurJobAfterwards = false, bool cancelBusyStances = true, ThinkTreeDef thinkTree = null, JobTag?tag = null, bool fromQueue = false, bool canReturnCurJobToPool = false) { startingNewJob = true; try { if (!fromQueue && (!Find.TickManager.Paused || lastJobGivenAtFrame == RealTime.frameCount)) { jobsGivenThisTick++; if (Prefs.DevMode) { jobsGivenThisTickTextual = jobsGivenThisTickTextual + "(" + newJob.ToString() + ") "; } } lastJobGivenAtFrame = RealTime.frameCount; if (jobsGivenThisTick > 10) { string text = jobsGivenThisTickTextual; jobsGivenThisTick = 0; jobsGivenThisTickTextual = ""; startingNewJob = false; pawn.ClearReservationsForJob(newJob); JobUtility.TryStartErrorRecoverJob(pawn, pawn.ToStringSafe() + " started 10 jobs in one tick. newJob=" + newJob.ToStringSafe() + " jobGiver=" + jobGiver.ToStringSafe() + " jobList=" + text); return; } if (debugLog) { DebugLogEvent(string.Concat("StartJob [", newJob, "] lastJobEndCondition=", lastJobEndCondition, ", jobGiver=", jobGiver, ", cancelBusyStances=", cancelBusyStances.ToString())); } if (cancelBusyStances && pawn.stances.FullBodyBusy) { pawn.stances.CancelBusyStanceHard(); } if (curJob != null) { if (lastJobEndCondition == JobCondition.None) { Log.Warning(string.Concat(pawn, " starting job ", newJob, " from JobGiver ", newJob.jobGiver, " while already having job ", curJob, " without a specific job end condition.")); lastJobEndCondition = JobCondition.InterruptForced; } if (resumeCurJobAfterwards && curJob.def.suspendable) { jobQueue.EnqueueFirst(curJob); if (debugLog) { DebugLogEvent(" JobQueue EnqueueFirst curJob: " + curJob); } CleanupCurrentJob(lastJobEndCondition, releaseReservations: false, cancelBusyStances); } else { CleanupCurrentJob(lastJobEndCondition, releaseReservations: true, cancelBusyStances, canReturnCurJobToPool); } } if (newJob == null) { Log.Warning(string.Concat(pawn, " tried to start doing a null job.")); return; } newJob.startTick = Find.TickManager.TicksGame; if (pawn.Drafted || newJob.playerForced) { newJob.ignoreForbidden = true; newJob.ignoreDesignations = true; } curJob = newJob; curJob.jobGiverThinkTree = thinkTree; curJob.jobGiver = jobGiver; curDriver = curJob.MakeDriver(pawn); bool flag = fromQueue; if (curDriver.TryMakePreToilReservations(!flag)) { Job job = TryOpportunisticJob(newJob); if (job != null) { jobQueue.EnqueueFirst(newJob); curJob = null; curDriver = null; StartJob(job); return; } if (tag.HasValue) { pawn.mindState.lastJobTag = tag.Value; } curDriver.SetInitialPosture(); curDriver.Notify_Starting(); curDriver.SetupToils(); curDriver.ReadyForNextToil(); } else if (flag) { EndCurrentJob(JobCondition.QueuedNoLongerValid); } else { Log.Warning("TryMakePreToilReservations() returned false for a non-queued job right after StartJob(). This should have been checked before. curJob=" + curJob.ToStringSafe()); EndCurrentJob(JobCondition.Errored); } } finally { startingNewJob = false; } }
private void TryActuallyStartNextToil() { if (!pawn.Spawned || (pawn.stances.FullBodyBusy && !CanStartNextToilInBusyStance) || job == null || pawn.CurJob != job) { return; } if (HaveCurToil) { CurToil.Cleanup(curToilIndex, this); } if (nextToilIndex >= 0) { curToilIndex = nextToilIndex; nextToilIndex = -1; } else { curToilIndex++; } wantBeginNextToil = false; if (!HaveCurToil) { if (pawn.stances != null && pawn.stances.curStance.StanceBusy) { Log.ErrorOnce(pawn.ToStringSafe() + " ended job " + job.ToStringSafe() + " due to running out of toils during a busy stance.", 6453432); } EndJobWith(JobCondition.Succeeded); return; } debugTicksSpentThisToil = 0; ticksLeftThisToil = CurToil.defaultDuration; curToilCompleteMode = CurToil.defaultCompleteMode; if (CheckCurrentToilEndOrFail()) { return; } Toil curToil = CurToil; if (CurToil.preInitActions != null) { for (int i = 0; i < CurToil.preInitActions.Count; i++) { try { CurToil.preInitActions[i](); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "JobDriver threw exception in preInitActions[" + i + "] for pawn " + pawn.ToStringSafe(), exception, this); return; } if (CurToil != curToil) { break; } } } if (CurToil != curToil) { return; } if (CurToil.initAction != null) { try { CurToil.initAction(); } catch (Exception exception2) { JobUtility.TryStartErrorRecoverJob(pawn, "JobDriver threw exception in initAction for pawn " + pawn.ToStringSafe(), exception2, this); return; } } if (!ended && curToilCompleteMode == ToilCompleteMode.Instant && CurToil == curToil) { ReadyForNextToil(); } }
public void DriverTick() { try { ticksLeftThisToil--; debugTicksSpentThisToil++; if (CurToil == null) { if (!pawn.stances.FullBodyBusy || CanStartNextToilInBusyStance) { ReadyForNextToil(); } } else { if (CheckCurrentToilEndOrFail()) { return; } if (curToilCompleteMode == ToilCompleteMode.Delay) { if (ticksLeftThisToil > 0) { goto IL_0099; } ReadyForNextToil(); } else { if (curToilCompleteMode != ToilCompleteMode.FinishedBusy || pawn.stances.FullBodyBusy) { goto IL_0099; } ReadyForNextToil(); } return; } goto end_IL_0000; IL_01b8: if (job.mote != null) { job.mote.Maintain(); } goto end_IL_0000; IL_0099: if (wantBeginNextToil) { TryActuallyStartNextToil(); return; } if (curToilCompleteMode == ToilCompleteMode.Instant && debugTicksSpentThisToil > 300) { Log.Error(string.Concat(pawn, " had to be broken from frozen state. He was doing job ", job, ", toilindex=", curToilIndex)); ReadyForNextToil(); return; } Job startingJob = pawn.CurJob; int startingJobId = startingJob.loadID; if (CurToil.preTickActions != null) { Toil curToil = CurToil; for (int i = 0; i < curToil.preTickActions.Count; i++) { curToil.preTickActions[i](); if (JobChanged() || CurToil != curToil || wantBeginNextToil) { return; } } } if (CurToil.tickAction == null) { goto IL_01b8; } CurToil.tickAction(); if (!JobChanged()) { goto IL_01b8; } end_IL_0000: bool JobChanged() { if (pawn.CurJob == startingJob) { return(pawn.CurJob.loadID != startingJobId); } return(true); } } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "Exception in JobDriver tick for pawn " + pawn.ToStringSafe(), exception, this); } }
private void TryActuallyStartNextToil() { if (this.pawn.Spawned) { if (!this.pawn.stances.FullBodyBusy || this.CanStartNextToilInBusyStance) { if (this.HaveCurToil) { this.CurToil.Cleanup(this.curToilIndex, this); } if (this.nextToilIndex >= 0) { this.curToilIndex = this.nextToilIndex; this.nextToilIndex = -1; } else { this.curToilIndex++; } this.wantBeginNextToil = false; if (!this.HaveCurToil) { if (this.pawn.stances != null && this.pawn.stances.curStance.StanceBusy) { Log.ErrorOnce(this.pawn.ToStringSafe <Pawn>() + " ended job " + this.job.ToStringSafe <Job>() + " due to running out of toils during a busy stance.", 6453432, false); } this.EndJobWith(JobCondition.Succeeded); } else { this.debugTicksSpentThisToil = 0; this.ticksLeftThisToil = this.CurToil.defaultDuration; this.curToilCompleteMode = this.CurToil.defaultCompleteMode; if (!this.CheckCurrentToilEndOrFail()) { Toil curToil = this.CurToil; if (this.CurToil.preInitActions != null) { for (int i = 0; i < this.CurToil.preInitActions.Count; i++) { try { this.CurToil.preInitActions[i](); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, string.Concat(new object[] { "JobDriver threw exception in preInitActions[", i, "] for pawn ", this.pawn.ToStringSafe <Pawn>() }), exception, this); return; } if (this.CurToil != curToil) { break; } } } if (this.CurToil == curToil) { if (this.CurToil.initAction != null) { try { this.CurToil.initAction(); } catch (Exception exception2) { JobUtility.TryStartErrorRecoverJob(this.pawn, "JobDriver threw exception in initAction for pawn " + this.pawn.ToStringSafe <Pawn>(), exception2, this); return; } } if (this.CurToil == curToil && !this.ended && this.curToilCompleteMode == ToilCompleteMode.Instant) { this.ReadyForNextToil(); } } } } } } }
private bool CheckCurrentToilEndOrFail() { bool result; try { Toil curToil = this.CurToil; if (this.globalFailConditions != null) { for (int i = 0; i < this.globalFailConditions.Count; i++) { JobCondition jobCondition = this.globalFailConditions[i](); if (jobCondition != JobCondition.Ongoing) { if (this.pawn.jobs.debugLog) { this.pawn.jobs.DebugLogEvent(string.Concat(new object[] { base.GetType().Name, " ends current job ", this.job.ToStringSafe <Job>(), " because of globalFailConditions[", i, "]" })); } this.EndJobWith(jobCondition); return(true); } } } if (curToil != null && curToil.endConditions != null) { for (int j = 0; j < curToil.endConditions.Count; j++) { JobCondition jobCondition2 = curToil.endConditions[j](); if (jobCondition2 != JobCondition.Ongoing) { if (this.pawn.jobs.debugLog) { this.pawn.jobs.DebugLogEvent(string.Concat(new object[] { base.GetType().Name, " ends current job ", this.job.ToStringSafe <Job>(), " because of toils[", this.curToilIndex, "].endConditions[", j, "]" })); } this.EndJobWith(jobCondition2); return(true); } } } result = false; } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(this.pawn, "Exception in CheckCurrentToilEndOrFail for pawn " + this.pawn.ToStringSafe <Pawn>(), exception, this); result = true; } return(result); }
public void DriverTick() { try { ticksLeftThisToil--; debugTicksSpentThisToil++; if (CurToil == null) { if (!pawn.stances.FullBodyBusy || CanStartNextToilInBusyStance) { ReadyForNextToil(); } } else if (!CheckCurrentToilEndOrFail()) { if (curToilCompleteMode == ToilCompleteMode.Delay) { if (ticksLeftThisToil > 0) { goto IL_00b6; } ReadyForNextToil(); } else { if (curToilCompleteMode != ToilCompleteMode.FinishedBusy || pawn.stances.FullBodyBusy) { goto IL_00b6; } ReadyForNextToil(); } } goto end_IL_0000; IL_00b6: if (wantBeginNextToil) { TryActuallyStartNextToil(); } else if (curToilCompleteMode == ToilCompleteMode.Instant && debugTicksSpentThisToil > 300) { Log.Error(pawn + " had to be broken from frozen state. He was doing job " + job + ", toilindex=" + curToilIndex); ReadyForNextToil(); } else { Job curJob = pawn.CurJob; if (CurToil.preTickActions != null) { Toil curToil = CurToil; for (int i = 0; i < curToil.preTickActions.Count; i++) { curToil.preTickActions[i](); if (pawn.CurJob != curJob || CurToil != curToil || wantBeginNextToil) { return; } } } if (CurToil.tickAction != null) { CurToil.tickAction(); } } end_IL_0000 :; } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "Exception in JobDriver tick for pawn " + pawn.ToStringSafe(), exception, this); } }