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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
                            }
                        }
                    }
                },
Пример #4
0
        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);
                                }
                            }
                        }
                    }