private static ThinkResult DetermineNextJob2(Pawn_JobTracker __instance, out ThinkTreeDef thinkTree) { ThinkResult result = funcDetermineNextConstantThinkTreeJob(__instance); if (result.Job != null) { thinkTree = pawnFieldRef(__instance).thinker.ConstantThinkTree; return(result); } ThinkResult result2 = ThinkResult.NoJob; try { result2 = pawnFieldRef(__instance).thinker.MainThinkNodeRoot.TryIssueJobPackage(pawnFieldRef(__instance), default(JobIssueParams)); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawnFieldRef(__instance), pawnFieldRef(__instance).ToStringSafe() + " threw exception while determining job (main)", exception); thinkTree = null; return(ThinkResult.NoJob); } thinkTree = pawnFieldRef(__instance).thinker.MainThinkTree; return(result2); }
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 static void WriteItemToConsole(ThinkTreeDef item) { CONS.WriteLine($" {nameof(ThinkTreeDef)}"); CONS.WriteLine($" defName: {item.DefName.ToStringOrDefault()}"); CONS.WriteLine(" thinkRoot"); RenderThinkNode(item.ThinkRoot); }
public void Clear() { def = null; targetA = LocalTargetInfo.Invalid; targetB = LocalTargetInfo.Invalid; targetC = LocalTargetInfo.Invalid; targetQueueA = null; targetQueueB = null; count = -1; countQueue = null; loadID = -1; startTick = -1; expiryInterval = -1; checkOverrideOnExpire = false; playerForced = false; placedThings = null; maxNumMeleeAttacks = int.MaxValue; maxNumStaticAttacks = int.MaxValue; locomotionUrgency = LocomotionUrgency.Jog; haulMode = HaulMode.Undefined; bill = null; commTarget = null; plantDefToSow = null; verbToUse = null; haulOpportunisticDuplicates = false; exitMapOnArrival = false; failIfCantJoinOrCreateCaravan = false; killIncappedTarget = false; ignoreForbidden = false; ignoreDesignations = false; canBash = false; canUseRangedWeapon = true; haulDroppedApparel = false; restUntilHealed = false; ignoreJoyTimeAssignment = false; doUntilGatheringEnded = false; overeat = false; attackDoorIfTargetLost = false; takeExtraIngestibles = 0; expireRequiresEnemiesNearby = false; lord = null; collideWithPawns = false; forceSleep = false; interaction = null; endIfCantShootTargetFromCurPos = false; endIfCantShootInMelee = false; checkEncumbrance = false; followRadius = 0f; endAfterTendedOnce = false; quest = null; mote = null; jobGiverThinkTree = null; jobGiver = null; workGiverDef = null; if (cachedDriver != null) { cachedDriver.job = null; } cachedDriver = null; }
public void StartJob(CaravanJob newJob, JobCondition lastJobEndCondition = JobCondition.None, ThinkNode jobGiver = null, bool resumeCurJobAfterwards = false, bool cancelBusyStances = true, ThinkTreeDef thinkTree = null, JobTag?tag = null) { //Log.Message("JecsTools :: CaravanJobTracker :: JobTracker StartJob :: " + newJob.def.label); if (!Find.TickManager.Paused || lastJobGivenAtFrame == RealTime.frameCount) { jobsGivenThisTick++; jobsGivenThisTickTextual = jobsGivenThisTickTextual + "(" + newJob + ") "; } lastJobGivenAtFrame = RealTime.frameCount; if (jobsGivenThisTick > 10) { var text = jobsGivenThisTickTextual; jobsGivenThisTick = 0; jobsGivenThisTickTextual = string.Empty; StartErrorRecoverJob(string.Concat(caravan, " started 10 jobs in one tick. newJob=", newJob, " jobGiver=", jobGiver, " jobList=", text)); return; } if (debugLog) { DebugLogEvent(string.Concat("StartJob [", newJob, "] lastJobEndCondition=", lastJobEndCondition, ", jobGiver=", jobGiver, ", cancelBusyStances=", cancelBusyStances)); } if (curJob != null) { if (lastJobEndCondition == JobCondition.None) { Log.Warning(string.Concat(caravan, " starting job ", newJob, " while already having job ", curJob, " without a specific job end condition.")); lastJobEndCondition = JobCondition.InterruptForced; } if (resumeCurJobAfterwards && curJob.def.suspendable) { jobQueue.EnqueueFirst(curJob, null); if (debugLog) { DebugLogEvent(" JobQueue EnqueueFirst curJob: " + curJob); } } CleanupCurrentJob(lastJobEndCondition, !resumeCurJobAfterwards, cancelBusyStances); } if (newJob == null) { Log.Warning(caravan + " tried to start doing a null job."); return; } newJob.startTick = Find.TickManager.TicksGame; if (newJob.playerForced) { newJob.ignoreForbidden = true; newJob.ignoreDesignations = true; } curJob = newJob; curDriver = curJob.MakeDriver(caravan); curDriver.Notify_Starting(); curDriver.SetupToils(); curDriver.ReadyForNextToil(); }
private ThinkResult DetermineNextJob(out ThinkTreeDef thinkTree) { ThinkResult result = this.DetermineNextConstantThinkTreeJob(); if (result.Job != null) { thinkTree = this.pawn.thinker.ConstantThinkTree; return(result); } ThinkResult result2 = ThinkResult.NoJob; try { result2 = this.pawn.thinker.MainThinkNodeRoot.TryIssueJobPackage(this.pawn, default(JobIssueParams)); } catch (Exception ex) { this.StartErrorRecoverJob(this.pawn + " threw exception while determining job (main): " + ex.ToString()); thinkTree = null; return(ThinkResult.NoJob); } finally { } thinkTree = this.pawn.thinker.MainThinkTree; return(result2); }
private static ThinkResult DetermineNextJob2(Pawn_JobTracker __instance, out ThinkTreeDef thinkTree) { ThinkResult result = __instance.DetermineNextConstantThinkTreeJob(); if (result.Job != null) { thinkTree = __instance.pawn.thinker.ConstantThinkTree; return(result); } ThinkResult result2 = ThinkResult.NoJob; try { result2 = __instance.pawn.thinker.MainThinkNodeRoot.TryIssueJobPackage(__instance.pawn, default); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(__instance.pawn, __instance.pawn.ToStringSafe() + " threw exception while determining job (main)", exception); thinkTree = null; return(ThinkResult.NoJob); } finally { } thinkTree = __instance.pawn.thinker.MainThinkTree; return(result2); }
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); }
static void PrintHumanlikeThinkTree() { ThinkTreeDef tree = DefDatabase <ThinkTreeDef> .GetNamed("Humanlike"); if (tree == null) { return; } string outStr = TreeUtilities.PrettyPrintTree(tree.thinkRoot, GetChildren, GetNodeLabel); Log.Message(outStr); }
static void Prepare() { DefStupidPawns = DefDatabase <ThinkTreeDef> .GetNamedSilentFail("Zombie"); DefPawns = ( from def in DefDatabase <ThingDef> .AllDefs where def.race?.intelligence == Intelligence.Humanlike && !def.defName.Contains("AIPawn") && !def.defName.Contains("Robot") && !def.defName.Contains("ChjDroid") && !def.defName.Contains("ChjBattleDroid") && (DefStupidPawns == null || def.race.thinkTreeMain != DefStupidPawns) select def ); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { List <Trait> allTraits = pawn.story.traits.allTraits; for (int i = 0; i < allTraits.Count; i++) { ThinkTreeDef thinkTree = allTraits[i].CurrentData.thinkTree; if (thinkTree != null) { return(thinkTree.thinkRoot.TryIssueJobPackage(pawn, jobParams)); } } return(ThinkResult.NoJob); }
static bool Prefix(Pawn_JobTracker_Crutch __instance, JobCondition condition) { if (__instance == null || __instance._pawn == null || !__instance._pawn.IsColonistPlayerControlled || __instance.curJob == null) { return(true); } if (Settings.fun_police && __instance._pawn.needs.joy != null && __instance._pawn.needs.joy.CurLevel > 0.95f) { CompJoyToppedOff c = __instance._pawn.TryGetComp <CompJoyToppedOff>(); if (c != null) { c.JoyToppedOff = true; } } Job job = null; if (Settings.clean_before_work && condition == JobCondition.Succeeded && __instance.jobQueue != null && __instance.jobQueue.Count == 0 && __instance.curJob != null && ProperJob(__instance.curJob, __instance._pawn, JobDefOf.DeliverFood)) { job = MakeCleaningJob(__instance._pawn, __instance.curJob.targetA, Settings.op_clean_num); } if (Settings.clean_after_tending && condition == JobCondition.Succeeded && __instance.jobQueue != null && __instance.jobQueue.Count == 0 && ProperJob(__instance.curJob, __instance._pawn, JobDefOf.TendPatient)) { ThinkTreeDef thinkTree = null; MethodInfo mi = AccessTools.Method(typeof(Pawn_JobTracker), "DetermineNextJob"); ThinkResult thinkResult = (ThinkResult)mi.Invoke(__instance, new object[] { thinkTree }); if (ProperJob(thinkResult.Job, __instance._pawn, JobDefOf.TendPatient)) { Pawn pawn = (Pawn)thinkResult.Job.targetA.Thing; if (pawn.GetRoom() == __instance.curJob.targetA.Thing.GetRoom() || ((float)HealthUtility.TicksUntilDeathDueToBloodLoss(pawn) / 2500f) < 6) { return(true); } } job = MakeCleaningJob(__instance._pawn, __instance.curJob.targetA, Settings.doc_clean_num); } // if (job != null) { __instance.jobQueue.EnqueueFirst(job); } // return(true); }
public void CheckForJobOverride() { if (this.debugLog) { this.DebugLogEvent("CheckForJobOverride"); } ThinkTreeDef thinkTree = default(ThinkTreeDef); ThinkResult thinkResult = this.DetermineNextJob(out thinkTree); if (this.ShouldStartJobFromThinkTree(thinkResult)) { this.CheckLeaveJoinableLordBecauseJobIssued(thinkResult); this.StartJob(thinkResult.Job, JobCondition.InterruptOptional, thinkResult.SourceNode, false, false, thinkTree, thinkResult.Tag, thinkResult.FromQueue); } }
public void Reset(bool clearInspiration = false) { mentalStateHandler.Reset(); mentalBreaker.Reset(); if (clearInspiration) { inspirationHandler.Reset(); } activeInt = true; lastJobTag = JobTag.Misc; lastIngestTick = -99999; nextApparelOptimizeTick = -99999; lastJobGiver = null; lastJobGiverThinkTree = null; lastGivenWorkType = null; canFleeIndividual = true; exitMapAfterTick = -99999; lastDisturbanceTick = -99999; forcedGotoPosition = IntVec3.Invalid; knownExploder = null; wantsToTradeWithColony = false; lastMannedThing = null; canLovinTick = -99999; canSleepTick = -99999; meleeThreat = null; lastMeleeThreatHarmTick = -99999; lastEngageTargetTick = -99999; lastAttackTargetTick = -99999; lastAttackedTarget = LocalTargetInfo.Invalid; enemyTarget = null; duty = null; thinkData.Clear(); lastAssignedInteractTime = -99999; interactionsToday = 0; lastInventoryRawFoodUseTick = 0; priorityWork.Clear(); nextMoveOrderIsWait = true; lastTakeCombatEnhancingDrugTick = -99999; lastHarmTick = -99999; anyCloseHostilesRecently = false; WillJoinColonyIfRescued = false; WildManEverReachedOutside = false; timesGuestTendedToByPlayer = 0; lastSelfTendTick = -99999; spawnedByInfestationThingComp = false; lastPredatorHuntingPlayerNotificationTick = -99999; }
public void Reset() { this.mentalStateHandler.Reset(); this.mentalBreaker.Reset(); this.inspirationHandler.Reset(); this.activeInt = true; this.lastJobTag = JobTag.Misc; this.lastIngestTick = -99999; this.nextApparelOptimizeTick = -99999; this.lastJobGiver = null; this.lastJobGiverThinkTree = null; this.lastGivenWorkType = null; this.canFleeIndividual = true; this.exitMapAfterTick = -99999; this.lastDisturbanceTick = -99999; this.forcedGotoPosition = IntVec3.Invalid; this.knownExploder = null; this.wantsToTradeWithColony = false; this.lastMannedThing = null; this.canLovinTick = -99999; this.canSleepTick = -99999; this.meleeThreat = null; this.lastMeleeThreatHarmTick = -99999; this.lastEngageTargetTick = -99999; this.lastAttackTargetTick = -99999; this.lastAttackedTarget = LocalTargetInfo.Invalid; this.enemyTarget = null; this.duty = null; this.thinkData.Clear(); this.lastAssignedInteractTime = -99999; this.lastInventoryRawFoodUseTick = 0; this.priorityWork.Clear(); this.nextMoveOrderIsWait = true; this.lastTakeCombatEnhancingDrugTick = -99999; this.lastHarmTick = -99999; this.anyCloseHostilesRecently = false; this.willJoinColonyIfRescued = false; this.wildManEverReachedOutside = false; this.timesGuestTendedToByPlayer = 0; this.lastSelfTendTick = -99999; this.spawnedByInfestationThingComp = false; }
private void TryFindAndStartJob() { if (pawn.thinker == null) { Log.ErrorOnce(pawn + " did TryFindAndStartJob but had no thinker.", 8573261); } else { if (curJob != null) { Log.Warning(pawn + " doing TryFindAndStartJob while still having job " + curJob); } if (debugLog) { DebugLogEvent("TryFindAndStartJob"); } if (!CanDoAnyJob()) { if (debugLog) { DebugLogEvent(" CanDoAnyJob is false. Clearing queue and returning"); } ClearQueuedJobs(); } else { ThinkTreeDef thinkTree; ThinkResult result = DetermineNextJob(out thinkTree); if (result.IsValid) { CheckLeaveJoinableLordBecauseJobIssued(result); Job job = result.Job; ThinkNode sourceNode = result.SourceNode; ThinkTreeDef thinkTree2 = thinkTree; StartJob(job, JobCondition.None, sourceNode, resumeCurJobAfterwards: false, cancelBusyStances: false, thinkTree2, result.Tag, result.FromQueue); } } } }
private void TryFindAndStartJob() { if (this.pawn.thinker == null) { Log.ErrorOnce(this.pawn + " did TryFindAndStartJob but had no thinker.", 8573261, false); } else { if (this.curJob != null) { Log.Warning(this.pawn + " doing TryFindAndStartJob while still having job " + this.curJob, false); } if (this.debugLog) { this.DebugLogEvent("TryFindAndStartJob"); } if (!this.CanDoAnyJob()) { if (this.debugLog) { this.DebugLogEvent(" CanDoAnyJob is false. Clearing queue and returning"); } this.ClearQueuedJobs(); } else { ThinkTreeDef thinkTreeDef; ThinkResult result = this.DetermineNextJob(out thinkTreeDef); if (result.IsValid) { this.CheckLeaveJoinableLordBecauseJobIssued(result); Job job = result.Job; ThinkNode sourceNode = result.SourceNode; ThinkTreeDef thinkTree = thinkTreeDef; this.StartJob(job, JobCondition.None, sourceNode, false, false, thinkTree, result.Tag, result.FromQueue); } } } }
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; } }
public static void Postfix(Pawn_JobTracker __instance, ThinkResult __result, ThinkTreeDef thinkTree) { FieldInfo info = __instance.GetType().GetField("pawn", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); Pawn actor = info.GetValue(__instance) as Pawn; if (actor.Faction != Faction.OfPlayer) { return; } RestrictedEntityManager manager = actor.Map.GetComponent <RestrictedEntityManager>(); manager.EndForbiddenSection(actor); }
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; } }
static bool Prefix(ref Pawn_JobTracker_Crutch __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue) { if (__instance == null || __instance._pawn == null || newJob == null || newJob.def == null) { return(true); } if (Settings.fun_police && __instance._pawn.needs.joy != null && __instance._pawn.needs.joy.CurLevel < 0.8f) { CompJoyToppedOff c = __instance._pawn.TryGetComp <CompJoyToppedOff>(); if (c != null) { c.JoyToppedOff = false; } } if (!Settings.clean_before_work && !Settings.hauling_over_bills) { return(true); } if (!newJob.def.allowOpportunisticPrefix) { return(true); } Job job = null; if (newJob.def == JobDefOf.DoBill) { if (Settings.hauling_over_bills) { job = Hauling_Opportunity(newJob, __instance._pawn); } } else if (!newJob.playerForced && newJob.targetA != null && newJob.targetA.Cell != null) { IntVec3 cell = newJob.targetA.Cell; if (!cell.IsValid || cell.IsForbidden(__instance._pawn) || __instance._pawn.Downed) { return(true); } if (Settings.clean_before_work && (newJob.targetA.Thing != null && newJob.targetA.Thing.GetType().IsSubclassOf(typeof(Building)) || newJob.def.joyKind != null)) { job = Cleaning_Opportunity(newJob, cell, __instance._pawn, 20); } } if (job != null) { if (Settings.add_to_que) { __instance.jobQueue.EnqueueFirst(newJob); } __instance.jobQueue.EnqueueFirst(job); __instance.curJob = null; __instance.curDriver = null; return(false); } return(true); }
public void StartJob(Job newJob, JobCondition lastJobEndCondition = JobCondition.None, ThinkNode jobGiver = null, bool resumeCurJobAfterwards = false, bool cancelBusyStances = true, ThinkTreeDef thinkTree = null, JobTag?tag = default(JobTag?), 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 = string.Empty; this.startingNewJob = false; this.pawn.ClearReservationsForJob(newJob); this.StartErrorRecoverJob(this.pawn + " started 10 jobs in one tick. newJob=" + newJob + " jobGiver=" + jobGiver + " jobList=" + text); } else { PawnPosture posture = this.pawn.GetPosture(); LayingDownState layingDown = (this.pawn.jobs != null && this.pawn.jobs.curDriver != null) ? this.pawn.jobs.curDriver.layingDown : LayingDownState.NotLaying; if (this.debugLog) { this.DebugLogEvent("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(this.pawn + " starting job " + newJob + " from JobGiver " + this.pawn.mindState.lastJobGiver + " while already having job " + this.curJob + " without a specific job end condition."); 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."); } 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()) { if (tag.HasValue) { this.pawn.mindState.lastJobTag = tag.Value; } this.curDriver.Notify_Starting(); this.curDriver.Notify_LastPosture(posture, layingDown); 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()); this.EndCurrentJob(JobCondition.Errored, true); } } } } finally { this.startingNewJob = false; } }
public static void Postfix(Pawn_JobTracker __instance, ThinkResult __result, ThinkTreeDef thinkTree) { FieldInfo info = AccessTools.Field(typeof(Pawn_JobTracker), "pawn"); Pawn actor = info.GetValue(__instance) as Pawn; if (actor.Faction != Faction.OfPlayer) { return; } RestrictedEntityManager manager = actor.Map.GetComponent <RestrictedEntityManager>(); manager.EndForbiddenSection(actor); }
public static bool StartJob(Pawn_JobTracker __instance, 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) { return(false); }
static void Prefix(Pawn_JobTracker __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue) { if (newJob != null && newJob.targetB != null && newJob.targetB.Thing is StoredAmmo sa) { Pawn pawn = __instance.GetType().GetField("pawn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) as Pawn; Building_TurretGunCE turret = newJob.targetA.Thing as Building_TurretGunCE; FieldInfo fi = sa.root.GetType().GetField("AllowAdds", BindingFlags.Instance | BindingFlags.Public); try { fi.SetValue(sa.root, false); IntVec3 pos; Building building = sa.root as Building; if (sa.forced || sa.root == null) { pos = pawn.Position; } else { pos = building.InteractionCell; } if (!CombatExtendedUtil.TryDropAmmo(sa.ammoDef, sa.ammoCount, pos, sa.root.Map, out Thing t)) { Log.Error("Could not get ammo"); } else { newJob.targetB = t; newJob.count = t.stackCount; } } finally { fi.SetValue(sa.root, true); } } }
public static bool DetermineNextJob(Pawn_JobTracker __instance, ref ThinkResult __result, out ThinkTreeDef thinkTree) { ThinkResult constantThinkTreeJob = __instance.DetermineNextConstantThinkTreeJob(); if (constantThinkTreeJob.Job != null) { thinkTree = __instance.pawn.thinker.ConstantThinkTree; __result = constantThinkTreeJob; return(false); } ThinkResult thinkResult = ThinkResult.NoJob; try { thinkResult = __instance.pawn.thinker.MainThinkNodeRoot.TryIssueJobPackage(__instance.pawn, new JobIssueParams()); } catch (Exception ex) { JobUtility.TryStartErrorRecoverJob(__instance.pawn, __instance.pawn.ToStringSafe <Pawn>() + " threw exception while determining job (main)", ex); thinkTree = null; __result = ThinkResult.NoJob; return(false); } finally { } thinkTree = __instance?.pawn?.thinker?.MainThinkTree; //changed if (thinkTree == null) //changed { thinkResult = ThinkResult.NoJob; //changed } __result = thinkResult; return(false); }
public static bool StartJob(Pawn_JobTracker __instance, 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) { __instance.startingNewJob = true; try { if (!fromQueue && (!Find.TickManager.Paused || __instance.lastJobGivenAtFrame == RealTime.frameCount)) { ++__instance.jobsGivenThisTick; if (Prefs.DevMode) { __instance.jobsGivenThisTickTextual = __instance.jobsGivenThisTickTextual + "(" + newJob.ToString() + ") "; } } __instance.lastJobGivenAtFrame = RealTime.frameCount; if (__instance.jobsGivenThisTick > 10) { string givenThisTickTextual = __instance.jobsGivenThisTickTextual; __instance.jobsGivenThisTick = 0; __instance.jobsGivenThisTickTextual = ""; __instance.startingNewJob = false; __instance.pawn.ClearReservationsForJob(newJob); JobUtility.TryStartErrorRecoverJob(__instance.pawn, __instance.pawn.ToStringSafe <Pawn>() + " started 10 jobs in one tick. newJob=" + newJob.ToStringSafe <Job>() + " jobGiver=" + jobGiver.ToStringSafe <ThinkNode>() + " jobList=" + givenThisTickTextual); } else { if (__instance.debugLog) { __instance.DebugLogEvent("StartJob [" + (object)newJob + "] lastJobEndCondition=" + (object)lastJobEndCondition + ", jobGiver=" + (object)jobGiver + ", cancelBusyStances=" + cancelBusyStances.ToString()); } Pawn_StanceTracker stances = __instance.pawn.stances; //changed if (cancelBusyStances && stances != null && stances.FullBodyBusy) //changed { stances.CancelBusyStanceHard(); } if (__instance.curJob != null) { if (lastJobEndCondition == JobCondition.None) { Log.Warning(__instance.pawn.ToString() + " starting job " + (object)newJob + " from JobGiver " + (object)newJob.jobGiver + " while already having job " + (object)__instance.curJob + " without a specific job end condition."); lastJobEndCondition = JobCondition.InterruptForced; } if (resumeCurJobAfterwards && __instance.curJob.def.suspendable) { __instance.jobQueue.EnqueueFirst(__instance.curJob); if (__instance.debugLog) { __instance.DebugLogEvent(" JobQueue EnqueueFirst curJob: " + (object)__instance.curJob); } __instance.CleanupCurrentJob(lastJobEndCondition, false, cancelBusyStances); } else { __instance.CleanupCurrentJob(lastJobEndCondition, true, cancelBusyStances, canReturnCurJobToPool); } } if (newJob == null) { Log.Warning(__instance.pawn.ToString() + " tried to start doing a null job."); } else { newJob.startTick = Find.TickManager.TicksGame; if (__instance.pawn.Drafted || newJob.playerForced) { newJob.ignoreForbidden = true; newJob.ignoreDesignations = true; } __instance.curJob = newJob; __instance.curJob.jobGiverThinkTree = thinkTree; __instance.curJob.jobGiver = jobGiver; JobDriver cDriver = __instance.curJob.MakeDriver(__instance.pawn); //changed __instance.curDriver = cDriver; //changed bool flag = fromQueue; if (__instance.curDriver.TryMakePreToilReservations(!flag)) { Job newJob1 = __instance.TryOpportunisticJob(newJob); if (newJob1 != null) { __instance.jobQueue.EnqueueFirst(newJob); __instance.curJob = (Job)null; __instance.curDriver = (JobDriver)null; __instance.StartJob(newJob1); } else { if (tag.HasValue) { __instance.pawn.mindState.lastJobTag = tag.Value; } cDriver.SetInitialPosture(); //changed cDriver.Notify_Starting(); //changed cDriver.SetupToils(); //changed cDriver.ReadyForNextToil(); //changed } } else if (flag) { __instance.EndCurrentJob(JobCondition.QueuedNoLongerValid); } else { Log.Warning("TryMakePreToilReservations() returned false for a non-queued job right after StartJob(). This should have been checked before. curJob=" + __instance.curJob.ToStringSafe <Job>()); __instance.EndCurrentJob(JobCondition.Errored); } } } } finally { __instance.startingNewJob = false; } return(false); }
private static float <TryIssueJobPackage> m__0(ThinkTreeDef tDef) { return(tDef.insertPriority); }
static bool Prefix(ref Pawn_JobTracker_Crutch __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue) { try { if (__instance == null || __instance._pawn == null || !__instance._pawn.IsColonistPlayerControlled || newJob == null || newJob.def == null) { return(true); } if (Settings.fun_police && __instance._pawn.needs.joy != null && __instance._pawn.needs.joy.CurLevel < 0.8f) { CompJoyToppedOff c = __instance._pawn.TryGetComp <CompJoyToppedOff>(); if (c != null) { c.JoyToppedOff = false; } } if (!Settings.clean_before_work && !Settings.hauling_over_bills) { return(true); } if (!newJob.def.allowOpportunisticPrefix) { return(true); } Job job = null; if (newJob.def == JobDefOf.DoBill) { if (Settings.hauling_over_bills) { job = Hauling_Opportunity(newJob, __instance._pawn); } } else if (!newJob.playerForced && newJob.targetA != null && newJob.targetA.Cell != null) { IntVec3 cell = newJob.targetA.Cell; if (!cell.IsValid || cell.IsForbidden(__instance._pawn) || __instance._pawn.Downed) { return(true); } if (Settings.clean_before_work && (newJob.targetA.Thing != null && newJob.targetA.Thing.GetType().IsSubclassOf(typeof(Building)) && newJob.def != JobDefOf.PlaceNoCostFrame && newJob.def != JobDefOf.FinishFrame || newJob.def.joyKind != null) && !HealthAIUtility.ShouldBeTendedNowByPlayer(__instance._pawn)) { job = Cleaning_Opportunity(newJob, cell, __instance._pawn, Settings.op_clean_num); } } //Log.Message($"pawn={__instance._pawn},job={newJob},enque={job}, limit = {Settings.op_clean_num}"); if (job != null) { if (Settings.add_to_que) { newJob.playerForced = true; __instance.jobQueue.EnqueueFirst(newJob); } __instance.jobQueue.EnqueueFirst(job); //__instance.curJob = null; //__instance.curDriver = null; return(false); } } catch (Exception e) { Log.Error($"CommonSense: opportunistic task skipped due to error ({e.Message})"); } return(true); }