public static IEnumerable <Toil> MakeNewToils(object __instance, float drillInTickMultiplier = 1f) { JobDriver jd = (JobDriver)__instance; jd.EndOnDespawnedOrNull(TargetIndex.A); Toil toil = Toils_Misc.FindRandomAdjacentReachableCell(TargetIndex.A, TargetIndex.B); yield return(toil); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil supervise = new Toil(); supervise.tickAction = delegate() { LocalTargetInfo TargetA = Traverse.Create(__instance).Property("TargetA").GetValue <LocalTargetInfo>(); jd.pawn.rotationTracker.FaceCell(TargetA.Thing.OccupiedRect().ClosestCellTo(jd.pawn.Position)); Pawn actor = supervise.actor; actor.skills.Learn(SkillDefOf.Construction, 0.275f); float statValue = actor.GetStatValue(StatDefOf.ConstructionSpeed); //CompOilDerrick compOilDerrick = TargetA.Thing.TryGetComp<CompOilDerrick>(); object compOilDerrick = null; { // getting compOilDerrick ThingWithComps thingWithComps = TargetA.Thing as ThingWithComps; if (thingWithComps != null) { var found = thingWithComps.AllComps?.Where(x => x.GetType().ToString().StartsWith("CompOilDerrick")).FirstOrDefault(); if (found != null) { compOilDerrick = found; } } } bool flag = compOilDerrick != null; if (flag) { bool flag2 = !Traverse.Create(compOilDerrick).Property("WorkingNow").GetValue <bool>(); if (flag2) { jd.EndJobWith(JobCondition.Incompletable); } // compOilDerrick.Drill(statValue); Traverse.Create(compOilDerrick).Method("Drill", statValue * drillInTickMultiplier).GetValue(); bool isDilled = Traverse.Create(compOilDerrick).Property("IsDilled").GetValue <bool>(); if (isDilled) { jd.EndJobWith(JobCondition.Succeeded); } } }; supervise.handlingFacing = true; supervise.defaultCompleteMode = ToilCompleteMode.Never; supervise.activeSkill = (() => SkillDefOf.Construction); yield return(supervise); }
public static bool CheckCurrentToilEndOrFail2(JobDriver __instance) { try { Toil curToil = get_CurToil2(__instance); List <Func <JobCondition> > listFuncJobConditions = __instance.globalFailConditions; if (listFuncJobConditions != null) { for (int i = 0; i < listFuncJobConditions.Count; i++) { JobCondition jobCondition = listFuncJobConditions[i](); if (jobCondition != JobCondition.Ongoing) { if (__instance.pawn.jobs.debugLog) { __instance.pawn.jobs.DebugLogEvent(__instance.GetType().Name + " ends current job " + __instance.job.ToStringSafe() + " because of globalFailConditions[" + i + "]"); } __instance.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 (__instance.pawn.jobs.debugLog) { __instance.pawn.jobs.DebugLogEvent(__instance.GetType().Name + " ends current job " + __instance.job.ToStringSafe() + " because of toils[" + curToilIndex + "].endConditions[" + j + "]"); } __instance.EndJobWith(jobCondition2); return(true); } } } return(false); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(__instance.pawn, "Exception in CheckCurrentToilEndOrFail for pawn " + __instance.pawn.ToStringSafe(), exception, __instance); return(true); } }
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, 0, -1, actor)); } } } victim.stances.stunner.StunFor((int)BaseFeedTime); } } }; 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); PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor); } } } },
public static bool TryActuallyStartNextToil(JobDriver __instance) { if (!__instance.pawn.Spawned || (__instance.pawn.stances.FullBodyBusy && !get_CanStartNextToilInBusyStance2(__instance)) || __instance.job == null || __instance.pawn.CurJob != __instance.job) { return(false); } /* * if (get_HaveCurToil2(__instance)) * { * get_CurToil2(__instance).Cleanup(curToilIndex(__instance), __instance); * } */ if (curToilIndex(__instance) >= 0 && curToilIndex(__instance) < toils(__instance).Count&& __instance.job != null) { if (__instance.pawn.CurJob == __instance.job) { Toil curToil2 = toils(__instance)[curToilIndex(__instance)]; if (curToil2 != null) { curToil2.Cleanup(curToilIndex(__instance), __instance); } } } if (nextToilIndex(__instance) >= 0) { curToilIndex(__instance) = nextToilIndex(__instance); nextToilIndex(__instance) = -1; } else { curToilIndex(__instance)++; } wantBeginNextToil(__instance) = false; if (!get_HaveCurToil2(__instance)) { if (__instance.pawn.stances != null && __instance.pawn.stances.curStance.StanceBusy) { Log.ErrorOnce(__instance.pawn.ToStringSafe() + " ended job " + __instance.job.ToStringSafe() + " due to running out of toils during a busy stance.", 6453432); } __instance.EndJobWith(JobCondition.Succeeded); return(false); } __instance.debugTicksSpentThisToil = 0; Toil curToil = get_CurToil2(__instance); if (curToil != null) { __instance.ticksLeftThisToil = curToil.defaultDuration; curToilCompleteMode(__instance) = curToil.defaultCompleteMode; } if (CheckCurrentToilEndOrFail2(__instance)) { return(false); } curToil = get_CurToil2(__instance); Toil gct = get_CurToil2(__instance); if (gct != null && gct.preInitActions != null) { List <Action> preInitActions = gct.preInitActions; for (int i = 0; i < preInitActions.Count; i++) { try { gct = get_CurToil2(__instance); if (gct != null) { preInitActions = gct.preInitActions; } else { break; } preInitActions[i](); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(__instance.pawn, "JobDriver threw exception in preInitActions[" + i + "] for pawn " + __instance.pawn.ToStringSafe(), exception, __instance); return(false); } if (get_CurToil2(__instance) != curToil) { break; } gct = get_CurToil2(__instance); if (gct != null) { preInitActions = gct.preInitActions; } else { break; } } } Toil gct2 = get_CurToil2(__instance); if (gct2 == curToil) { if (gct2 != null) { if (gct2.initAction != null) { try { gct2.initAction(); } catch (Exception exception2) { JobUtility.TryStartErrorRecoverJob(__instance.pawn, "JobDriver threw exception in initAction for pawn " + __instance.pawn.ToStringSafe(), exception2, __instance); return(false); } } if (!__instance.ended && curToilCompleteMode(__instance) == ToilCompleteMode.Instant && get_CurToil2(__instance) == curToil) { __instance.ReadyForNextToil(); } } } return(false); }
public static IEnumerable <Toil> MakeFeedToils(JobDef job, JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, ThoughtDef victimThoughtDef, ThoughtDef actorThoughtDef, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition, bool needsGrapple = true, bool cleansWound = true, bool neverGiveUp = false) { yield return(Toils_Reserve.Reserve(TargetIndex.A)); Toil gotoToil = actor?.Faction == TargetA.Thing?.Faction && (!actor.InAggroMentalState && !((Pawn)TargetA.Thing).InAggroMentalState) ? Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch) : Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoToil); Toil grappleToil = new Toil() { initAction = delegate { MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); workLeft = BaseFeedTime; Pawn victim = TargetA.Thing as Pawn; if (victim != null) { // if (!AllowFeeding(actor, victim)) // { // actor.jobs.EndCurrentJob(JobCondition.Incompletable); // } if (actor.InAggroMentalState || victim.InAggroMentalState || victim.Faction != actor.Faction) { if (needsGrapple) { int grappleBonus = actor is PawnTemporary ? 100 : 0; if (!JecsTools.GrappleUtility.TryGrapple(actor, victim, grappleBonus)) { thisDriver.EndJobWith(JobCondition.Incompletable); PawnUtility.ForceWait(actor, (int)(BaseFeedTime * 0.15f)); return; } } } if (actor.IsVampire()) { VampireBiteUtility.MakeNew(actor, victim); } victim.stances.stunner.StunFor((int)BaseFeedTime, actor); } } }; yield return(grappleToil); Toil feedToil = new Toil() { tickAction = delegate { //try //{ if (TargetA.Thing is Pawn victim && victim.Spawned && !victim.Dead) { workLeft--; VampireWitnessUtility.HandleWitnessesOf(job, actor, victim); if (victim?.needs?.mood?.thoughts?.memories != null) { Thought_Memory victimThought = null; if (victimThoughtDef != null) { victimThought = (Thought_Memory)ThoughtMaker.MakeThought(victimThoughtDef); } if (victimThought != null) { victim.needs.mood.thoughts.memories.TryGainMemory(victimThought); } } if (actor?.needs?.mood?.thoughts?.memories != null) { Thought_Memory actorThought = null; if (actorThoughtDef != null) { actorThought = (Thought_Memory)ThoughtMaker.MakeThought(actorThoughtDef); } if (actorThought != null) { actor.needs.mood.thoughts.memories.TryGainMemory(actorThought); } } 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 != null && !victim.Dead && needsGrapple) { int victimBonus = (victim.VampComp() is CompVampire victimVampComp) ? -victimVampComp.Generation + 14 : 0; int actorBonus = 0; if (actor?.VampComp() is CompVampire v2 && v2.IsVampire) { actorBonus = -v2.Generation + 14; } if (!JecsTools.GrappleUtility.TryGrapple(actor, victim, actorBonus, victimBonus)) { thisDriver.EndJobWith(JobCondition.Incompletable); } } if (!stopCondition(actor, victim)) { thisDriver.ReadyForNextToil(); if (actor.IsVampire() && cleansWound) { VampireBiteUtility.CleanBite(actor, victim); } } else { if (victim != null && !victim.Dead) { victim.stances.stunner.StunFor((int)BaseFeedTime, actor); PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor); } } } }