예제 #1
0
        public static Toil DepositHauledThingInContainer(TargetIndex containerInd, TargetIndex reserveForContainerInd)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(actor + " tried to place hauled thing in container but is not hauling anything.", false);
                    return;
                }
                Thing      thing      = curJob.GetTarget(containerInd).Thing;
                ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner();
                if (thingOwner != null)
                {
                    int num = actor.carryTracker.CarriedThing.stackCount;
                    if (thing is IConstructible)
                    {
                        int a = GenConstruct.AmountNeededByOf((IConstructible)thing, actor.carryTracker.CarriedThing.def);
                        num = Mathf.Min(a, num);
                        if (reserveForContainerInd != TargetIndex.None)
                        {
                            Thing thing2 = curJob.GetTarget(reserveForContainerInd).Thing;
                            if (thing2 != null && thing2 != thing)
                            {
                                int num2 = GenConstruct.AmountNeededByOf((IConstructible)thing2, actor.carryTracker.CarriedThing.def);
                                num = Mathf.Min(num, actor.carryTracker.CarriedThing.stackCount - num2);
                            }
                        }
                    }
                    if (actor.carryTracker.innerContainer.TryTransferToContainer(actor.carryTracker.CarriedThing, thingOwner, num, true) != 0)
                    {
                        Building_Grave building_Grave = thing as Building_Grave;
                        if (building_Grave != null)
                        {
                            building_Grave.Notify_CorpseBuried(actor);
                        }
                    }
                }
                else if (curJob.GetTarget(containerInd).Thing.def.Minifiable)
                {
                    actor.carryTracker.innerContainer.ClearAndDestroyContents(DestroyMode.Vanish);
                }
                else
                {
                    Log.Error("Could not deposit hauled thing in container: " + curJob.GetTarget(containerInd).Thing, false);
                }
            };
            return(toil);
        }
        // Token: 0x0600002D RID: 45 RVA: 0x0000384C File Offset: 0x00001A4C
        public static Toil MakeUnfinishedThingIfNeeded()
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                bool flag   = !curJob.RecipeDef.UsesUnfinishedThing;
                if (!flag)
                {
                    bool flag2 = curJob.GetTarget(TargetIndex.B).Thing is UnfinishedThing;
                    if (!flag2)
                    {
                        List <Thing> list  = Toils_WPRecipe.CalculateIngredients(curJob, actor);
                        string       str   = "ingredient list in toil_wprecipe";
                        List <Thing> list2 = list;
                        Log.Message(str + ((list2 != null) ? list2.ToString() : null), false);
                        Thing thing = Toils_WPRecipe.CalculateDominantIngredient(curJob, list);
                        for (int i = 0; i < list.Count; i++)
                        {
                            Thing  thing2 = list[i];
                            string str2   = "ingredient in toil_wprecipe";
                            Thing  thing3 = list[i];
                            Log.Message(str2 + ((thing3 != null) ? thing3.ToString() : null), false);
                            actor.Map.designationManager.RemoveAllDesignationsOn(thing2, false);
                            bool spawned = thing2.Spawned;
                            if (spawned)
                            {
                                thing2.DeSpawn(DestroyMode.Vanish);
                            }
                        }
                        ThingDef        stuff           = (!curJob.RecipeDef.unfinishedThingDef.MadeFromStuff) ? null : thing.def;
                        UnfinishedThing unfinishedThing = (UnfinishedThing)ThingMaker.MakeThing(curJob.RecipeDef.unfinishedThingDef, stuff);
                        unfinishedThing.Creator     = actor;
                        unfinishedThing.BoundBill   = (Bill_ProductionWithUft)curJob.bill;
                        unfinishedThing.ingredients = list;
                        CompColorable compColorable = unfinishedThing.TryGetComp <CompColorable>();
                        bool          flag3         = compColorable != null;
                        if (flag3)
                        {
                            compColorable.Color = thing.DrawColor;
                        }
                        GenSpawn.Spawn(unfinishedThing, curJob.GetTarget(TargetIndex.A).Cell, actor.Map, WipeMode.Vanish);
                        curJob.SetTarget(TargetIndex.B, unfinishedThing);
                        actor.Reserve(unfinishedThing, curJob, 1, -1, null, true);
                    }
                }
            };
            return(toil);
        }
 public static T FailOnThingMissingDesignation <T>(this T f, TargetIndex ind, DesignationDef desDef) where T : IJobEndable
 {
     f.AddEndCondition(delegate
     {
         Pawn actor = f.GetActor();
         Job curJob = actor.jobs.curJob;
         JobCondition result;
         if (curJob.ignoreDesignations)
         {
             result = JobCondition.Ongoing;
         }
         else
         {
             Thing thing = curJob.GetTarget(ind).Thing;
             if (thing == null || actor.Map.designationManager.DesignationOn(thing, desDef) == null)
             {
                 result = JobCondition.Incompletable;
             }
             else
             {
                 result = JobCondition.Ongoing;
             }
         }
         return(result);
     });
     return(f);
 }
예제 #4
0
        public static Toil JumpToCarryToNextContainerIfPossible(Toil carryToContainerToil, TargetIndex primaryTargetInd)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (actor.carryTracker.CarriedThing == null)
                {
                    return;
                }
                if (curJob.targetQueueB != null && curJob.targetQueueB.Count > 0)
                {
                    Thing             primaryTarget = curJob.GetTarget(primaryTargetInd).Thing;
                    bool              hasSpareItems = actor.carryTracker.CarriedThing.stackCount > GenConstruct.AmountNeededByOf((IConstructible)primaryTarget, actor.carryTracker.CarriedThing.def);
                    Predicate <Thing> validator     = (Thing th) => GenConstruct.CanConstruct(th, actor, false, false) && ((IConstructible)th).MaterialsNeeded().Any((ThingDefCountClass need) => need.thingDef == actor.carryTracker.CarriedThing.def) && (th == primaryTarget || hasSpareItems);
                    Thing             nextTarget    = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, from targ in curJob.targetQueueB
                                                                                               select targ.Thing, PathEndMode.Touch, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), 99999f, validator, null);
                    if (nextTarget != null)
                    {
                        curJob.targetQueueB.RemoveAll((LocalTargetInfo targ) => targ.Thing == nextTarget);
                        curJob.targetB = nextTarget;
                        actor.jobs.curDriver.JumpToToil(carryToContainerToil);
                    }
                }
            };
            return(toil);
        }
예제 #5
0
        public static Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false, float maxRangeFactor = 1f)
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn    actor  = toil.actor;
                Job     curJob = actor.jobs.curJob;
                Thing   thing  = curJob.GetTarget(targetInd).Thing;
                Pawn    pawn   = thing as Pawn;
                IntVec3 intVec;
                if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster = toil.actor,
                    target = thing,
                    verb = curJob.verbToUse,
                    maxRangeFromTarget = ((closeIfDowned && pawn != null && pawn.Downed) ? Mathf.Min(curJob.verbToUse.verbProps.range, (float)pawn.RaceProps.executionRange) : Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, 1.42f)),
                    wantCoverFromTarget = false
                }, out intVec))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                toil.actor.pather.StartPath(intVec, PathEndMode.OnCell);
                actor.Map.pawnDestinationReservationManager.Reserve(actor, curJob, intVec);
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }
예제 #6
0
        public static Toil FollowAndMeleeAttack(TargetIndex targetInd, Action hitAction)
        {
            Toil followAndAttack = new Toil();

            followAndAttack.tickAction = delegate()
            {
                Pawn      actor     = followAndAttack.actor;
                Job       curJob    = actor.jobs.curJob;
                JobDriver curDriver = actor.jobs.curDriver;
                Thing     thing     = curJob.GetTarget(targetInd).Thing;
                Pawn      pawn      = thing as Pawn;
                if (!thing.Spawned)
                {
                    curDriver.ReadyForNextToil();
                    return;
                }
                if (thing != actor.pather.Destination.Thing || (!actor.pather.Moving && !actor.CanReachImmediate(thing, PathEndMode.Touch)))
                {
                    actor.pather.StartPath(thing, PathEndMode.Touch);
                }
                else if (actor.CanReachImmediate(thing, PathEndMode.Touch))
                {
                    if (pawn != null && pawn.Downed && !curJob.killIncappedTarget)
                    {
                        curDriver.ReadyForNextToil();
                        return;
                    }
                    hitAction();
                }
            };
            followAndAttack.defaultCompleteMode = ToilCompleteMode.Never;
            return(followAndAttack);
        }
예제 #7
0
        public static Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false, float maxRangeFactor = 1f)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor  = toil.actor;
                Job   curJob = actor.jobs.curJob;
                Thing thing  = curJob.GetTarget(targetInd).Thing;
                Pawn  pawn   = thing as Pawn;
                CastPositionRequest newReq = default(CastPositionRequest);
                newReq.caster              = toil.actor;
                newReq.target              = thing;
                newReq.verb                = curJob.verbToUse;
                newReq.maxRangeFromTarget  = ((!closeIfDowned || pawn == null || !pawn.Downed) ? Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, 1.42f) : Mathf.Min(curJob.verbToUse.verbProps.range, pawn.RaceProps.executionRange));
                newReq.wantCoverFromTarget = false;
                if (!CastPositionFinder.TryFindCastPosition(newReq, out IntVec3 dest))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }
                else
                {
                    toil.actor.pather.StartPath(dest, PathEndMode.OnCell);
                    actor.Map.pawnDestinationReservationManager.Reserve(actor, curJob, dest);
                }
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }
예제 #8
0
        private static List <Thing> CalculateIngredients(Job job, Pawn actor)
        {
            UnfinishedThing unfinishedThing = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (unfinishedThing != null)
            {
                List <Thing> ingredients = unfinishedThing.ingredients;
                job.RecipeDef.Worker.ConsumeIngredient(unfinishedThing, job.RecipeDef, actor.Map);
                job.placedThings = null;
                return(ingredients);
            }
            List <Thing> list = new List <Thing>();

            if (job.placedThings != null)
            {
                for (int i = 0; i < job.placedThings.Count; i++)
                {
                    if (job.placedThings[i].Count <= 0)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            "PlacedThing ",
                            job.placedThings[i],
                            " with count ",
                            job.placedThings[i].Count,
                            " for job ",
                            job
                        }));
                    }
                    else
                    {
                        Thing thing;
                        if (job.placedThings[i].Count < job.placedThings[i].thing.stackCount)
                        {
                            thing = job.placedThings[i].thing.SplitOff(job.placedThings[i].Count);
                        }
                        else
                        {
                            thing = job.placedThings[i].thing;
                        }
                        job.placedThings[i].Count = 0;
                        if (list.Contains(thing))
                        {
                            Log.Error("Tried to add ingredient from job placed targets twice: " + thing);
                        }
                        else
                        {
                            list.Add(thing);
                            IStrippable strippable = thing as IStrippable;
                            if (strippable != null)
                            {
                                strippable.Strip();
                            }
                        }
                    }
                }
            }
            job.placedThings = null;
            return(list);
        }
예제 #9
0
        /// <summary>
        /// Gets the dominant ingredient that determines the stuff, color, and possibly other properties of recipe products.
        /// </summary>
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing;

            if (uft != null && uft.def.MadeFromStuff)
            {
                return(uft.ingredients.First(ing => ing.def == uft.Stuff));
            }

            if (!ingredients.NullOrEmpty())
            {
                // if the recipe uses stuff ingredient (from recipe maker), then the first ingredient is the dominant one (stuff)
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    return(ingredients[0]);
                }

                if (job.RecipeDef.products.Any(x => x.thingDef.MadeFromStuff))
                {
                    return(ingredients.Where(x => x.def.IsStuff).RandomElementByWeight(x => x.stackCount));
                }
                else
                {
                    return(ingredients.RandomElementByWeight(x => x.stackCount));
                }
            }

            return(null);
        }
예제 #10
0
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
            Thing           result;

            if (uft != null && uft.def.MadeFromStuff)
            {
                result = uft.ingredients.First((Thing ing) => ing.def == uft.Stuff);
            }
            else if (!ingredients.NullOrEmpty <Thing>())
            {
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    result = ingredients[0];
                }
                else if (job.RecipeDef.products.Any((ThingDefCountClass x) => x.thingDef.MadeFromStuff))
                {
                    result = (from x in ingredients
                              where x.def.IsStuff
                              select x).RandomElementByWeight((Thing x) => (float)x.stackCount);
                }
                else
                {
                    result = ingredients.RandomElementByWeight((Thing x) => (float)x.stackCount);
                }
            }
            else
            {
                result = null;
            }
            return(result);
        }
예제 #11
0
        public static Toil CheckForGetOpportunityDuplicate(Toil getHaulTargetToil, TargetIndex haulableInd, TargetIndex storeCellInd, bool takeFromValidStorage = false, Predicate <Thing> extraValidator = null)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (actor.carryTracker.CarriedThing.def.stackLimit != 1 && !actor.carryTracker.Full && curJob.count > 0)
                {
                    Thing             thing     = null;
                    Predicate <Thing> validator = delegate(Thing t)
                    {
                        if (!t.Spawned)
                        {
                            return(false);
                        }
                        if (t.def != actor.carryTracker.CarriedThing.def)
                        {
                            return(false);
                        }
                        if (!t.CanStackWith(actor.carryTracker.CarriedThing))
                        {
                            return(false);
                        }
                        if (t.IsForbidden(actor))
                        {
                            return(false);
                        }
                        if (!takeFromValidStorage && t.IsInValidStorage())
                        {
                            return(false);
                        }
                        if (storeCellInd != 0 && !curJob.GetTarget(storeCellInd).Cell.IsValidStorageFor(actor.Map, t))
                        {
                            return(false);
                        }
                        if (!actor.CanReserve(t, 1, -1, null, false))
                        {
                            return(false);
                        }
                        if (extraValidator != null && !extraValidator(t))
                        {
                            return(false);
                        }
                        return(true);
                    };
                    thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), 8f, validator, null, 0, -1, false, RegionType.Set_Passable, false);
                    if (thing != null)
                    {
                        curJob.SetTarget(haulableInd, thing);
                        actor.jobs.curDriver.JumpToToil(getHaulTargetToil);
                    }
                }
            };
            return(toil);
        }
예제 #12
0
        public static Toil MakeUnfinishedThingIfNeeded()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (!curJob.RecipeDef.UsesUnfinishedThing)
                {
                    return;
                }
                if (curJob.GetTarget(TargetIndex.B).Thing is UnfinishedThing)
                {
                    return;
                }
                List <Thing> list  = Toils_Recipe.CalculateIngredients(curJob, actor);
                Thing        thing = Toils_Recipe.CalculateDominantIngredient(curJob, list);
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing2 = list[i];
                    actor.Map.designationManager.RemoveAllDesignationsOn(thing2, false);
                    if (thing2.Spawned)
                    {
                        thing2.DeSpawn(DestroyMode.Vanish);
                    }
                }
                ThingDef        stuff           = (!curJob.RecipeDef.unfinishedThingDef.MadeFromStuff) ? null : thing.def;
                UnfinishedThing unfinishedThing = (UnfinishedThing)ThingMaker.MakeThing(curJob.RecipeDef.unfinishedThingDef, stuff);
                unfinishedThing.Creator     = actor;
                unfinishedThing.BoundBill   = (Bill_ProductionWithUft)curJob.bill;
                unfinishedThing.ingredients = list;
                CompColorable compColorable = unfinishedThing.TryGetComp <CompColorable>();
                if (compColorable != null)
                {
                    compColorable.Color = thing.DrawColor;
                }
                GenSpawn.Spawn(unfinishedThing, curJob.GetTarget(TargetIndex.A).Cell, actor.Map, WipeMode.Vanish);
                curJob.SetTarget(TargetIndex.B, unfinishedThing);
                actor.Reserve(unfinishedThing, curJob, 1, -1, null, true);
            };
            return(toil);
        }
        public static Toil SetTargetToIngredientPlaceCell(TargetIndex billGiverInd, TargetIndex carryItemInd, TargetIndex cellTargetInd)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn       actor     = toil.actor;
                Job        curJob    = actor.jobs.curJob;
                Thing      thing     = curJob.GetTarget(carryItemInd).Thing;
                IBillGiver billGiver = curJob.GetTarget(billGiverInd).Thing as IBillGiver;
                IntVec3    c         = IntVec3.Invalid;
                foreach (IntVec3 item in Toils_JobTransforms.IngredientPlaceCellsInOrder(billGiver))
                {
                    if (!c.IsValid)
                    {
                        c = item;
                    }
                    bool         flag = false;
                    List <Thing> list = actor.Map.thingGrid.ThingsListAt(item);
                    int          num  = 0;
                    while (num < list.Count)
                    {
                        if (list[num].def.category != ThingCategory.Item || (list[num].def == thing.def && list[num].stackCount != list[num].def.stackLimit))
                        {
                            num++;
                            continue;
                        }
                        flag = true;
                        break;
                    }
                    if (!flag)
                    {
                        curJob.SetTarget(cellTargetInd, item);
                        return;
                    }
                }
                curJob.SetTarget(cellTargetInd, c);
            };
            return(toil);
        }
예제 #14
0
 public static T FailOnCellMissingDesignation <T>(this T f, TargetIndex ind, DesignationDef desDef) where T : IJobEndable
 {
     f.AddEndCondition(delegate
     {
         Pawn actor = f.GetActor();
         Job curJob = actor.jobs.curJob;
         if (curJob.ignoreDesignations)
         {
             return(JobCondition.Ongoing);
         }
         return((actor.Map.designationManager.DesignationAt(curJob.GetTarget(ind).Cell, desDef) != null) ? JobCondition.Ongoing : JobCondition.Incompletable);
     });
     return(f);
 }
예제 #15
0
            internal void <> m__0()
            {
                Pawn actor  = this.toil.actor;
                Job  curJob = actor.jobs.curJob;
                bool allowManualCastWeapons = !actor.IsColonist;
                Verb verb = actor.TryGetAttackVerb(curJob.GetTarget(this.targetInd).Thing, allowManualCastWeapons);

                if (verb == null)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                curJob.verbToUse = verb;
            }
예제 #16
0
        public static Toil SetTargetToIngredientPlaceCell(TargetIndex billGiverInd, TargetIndex carryItemInd, TargetIndex cellTargetInd)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn       actor     = toil.actor;
                Job        curJob    = actor.jobs.curJob;
                Thing      thing     = curJob.GetTarget(carryItemInd).Thing;
                IBillGiver billGiver = curJob.GetTarget(billGiverInd).Thing as IBillGiver;
                IntVec3    c         = IntVec3.Invalid;
                foreach (IntVec3 current in Toils_JobTransforms.IngredientPlaceCellsInOrder(billGiver))
                {
                    if (!c.IsValid)
                    {
                        c = current;
                    }
                    bool         flag = false;
                    List <Thing> list = actor.Map.thingGrid.ThingsListAt(current);
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (list[i].def.category == ThingCategory.Item && (list[i].def != thing.def || list[i].stackCount == list[i].def.stackLimit))
                        {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        curJob.SetTarget(cellTargetInd, current);
                        return;
                    }
                }
                curJob.SetTarget(cellTargetInd, c);
            };
            return(toil);
        }
예제 #17
0
        public static Toil JumpIfTargetDowned(TargetIndex ind, Toil jumpToil)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                Pawn pawn   = curJob.GetTarget(ind).Thing as Pawn;
                if (pawn != null && pawn.Downed)
                {
                    actor.jobs.curDriver.JumpToToil(jumpToil);
                }
            };
            return(toil);
        }
예제 #18
0
        public static Toil JumpIfTargetNotHittable(TargetIndex ind, Toil jumpToil)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn            actor  = toil.actor;
                Job             curJob = actor.jobs.curJob;
                LocalTargetInfo target = curJob.GetTarget(ind);
                if (curJob.verbToUse == null || !curJob.verbToUse.IsStillUsableBy(actor) || !curJob.verbToUse.CanHitTarget(target))
                {
                    actor.jobs.curDriver.JumpToToil(jumpToil);
                }
            };
            return(toil);
        }
예제 #19
0
        public static Toil JumpIfCannotTouch(TargetIndex ind, PathEndMode peMode, Toil jumpToil)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn            actor  = toil.actor;
                Job             curJob = actor.jobs.curJob;
                LocalTargetInfo target = curJob.GetTarget(ind);
                if (!actor.CanReachImmediate(target, peMode))
                {
                    actor.jobs.curDriver.JumpToToil(jumpToil);
                }
            };
            return(toil);
        }
예제 #20
0
        public static Toil JumpIfTargetDownedDistant(TargetIndex ind, Toil jumpToil)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor          = toil.actor;
                Job  curJob         = actor.jobs.curJob;
                Pawn pawn           = curJob.GetTarget(ind).Thing as Pawn;
                int  executionRange = pawn.RaceProps.executionRange;
                if (pawn != null && pawn.Downed && (actor.Position - pawn.Position).LengthHorizontalSquared > executionRange * executionRange)
                {
                    actor.jobs.curDriver.JumpToToil(jumpToil);
                }
            };
            return(toil);
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.FailOnDestroyedOrNull(TargetIndex.A);
                    this.FailOnBurningImmobile(TargetIndex.B);
                    if (!this.forbiddenInitially)
                    {
                        this.FailOnForbidden(TargetIndex.A);
                    }
                    reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null);
                    this.$current  = reserveTargetA;
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);

                case 1u:
                    < MakeNewToils > c__AnonStorey.toilGoto = null;
                    < MakeNewToils > c__AnonStorey.toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn(delegate()
                    {
                        Pawn actor = < MakeNewToils > c__AnonStorey.toilGoto.actor;
                        Job curJob = actor.jobs.curJob;
                        if (curJob.haulMode == HaulMode.ToCellStorage)
                        {
                            Thing thing  = curJob.GetTarget(TargetIndex.A).Thing;
                            IntVec3 cell = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell;
                            if (!cell.IsValidStorageFor(< MakeNewToils > c__AnonStorey.< > f__ref$0.$this.Map, thing))
                            {
                                return(true);
                            }
                        }
                        return(false);
                    });
                    this.$current = < MakeNewToils > c__AnonStorey.toilGoto;
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.B);
            if (!this.forbiddenInitially)
            {
                this.FailOnForbidden(TargetIndex.A);
            }
            Toil reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null);

            yield return(reserveTargetA);

            Toil toilGoto = null;

            toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn(delegate()
            {
                Pawn actor = toilGoto.actor;
                Job curJob = actor.jobs.curJob;
                if (curJob.haulMode == HaulMode.ToCellStorage)
                {
                    Thing thing  = curJob.GetTarget(TargetIndex.A).Thing;
                    IntVec3 cell = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell;
                    if (!cell.IsValidStorageFor(this.Map, thing))
                    {
                        return(true);
                    }
                }
                return(false);
            });
            yield return(toilGoto);

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false));

            if (this.job.haulOpportunisticDuplicates)
            {
                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, TargetIndex.A, TargetIndex.B, false, null));
            }
            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));

            yield break;
        }
예제 #23
0
        public static Toil FollowAndMeleeAttack(TargetIndex targetInd, Action hitAction)
        {
            //Follow and attack victim
            Toil followAndAttack = new Toil();

            followAndAttack.tickAction = () =>
            {
                Pawn      actor      = followAndAttack.actor;
                Job       curJob     = actor.jobs.curJob;
                JobDriver driver     = actor.jobs.curDriver;
                Thing     victim     = curJob.GetTarget(targetInd).Thing;
                Pawn      victimPawn = victim as Pawn;

                if (!victim.Spawned)
                {
                    driver.ReadyForNextToil();
                    return;
                }

                if (victim != actor.pather.Destination.Thing ||
                    (!actor.pather.Moving && !actor.CanReachImmediate(victim, PathEndMode.Touch)))
                {
                    actor.pather.StartPath(victim, PathEndMode.Touch);
                }
                else
                {
                    if (actor.CanReachImmediate(victim, PathEndMode.Touch))
                    {
                        //Do not attack downed people unless the job specifies to do so
                        if (victimPawn != null && victimPawn.Downed && !curJob.killIncappedTarget)
                        {
                            driver.ReadyForNextToil();
                            return;
                        }

                        //Try to hit them
                        hitAction();
                    }
                }
            };
            followAndAttack.defaultCompleteMode = ToilCompleteMode.Never;
            return(followAndAttack);
        }
예제 #24
0
        public static Toil TrySetJobToUseAttackVerb(TargetIndex targetInd)
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                bool allowManualCastWeapons = !actor.IsColonist;
                Verb verb = actor.TryGetAttackVerb(curJob.GetTarget(targetInd).Thing, allowManualCastWeapons);
                if (verb == null)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                curJob.verbToUse = verb;
            };
            return(toil);
        }
예제 #25
0
        private static List <Thing> CalculateIngredients(Job job, Pawn actor)
        {
            UnfinishedThing unfinishedThing = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (unfinishedThing != null)
            {
                List <Thing> ingredients = unfinishedThing.ingredients;
                job.RecipeDef.Worker.ConsumeIngredient(unfinishedThing, job.RecipeDef, actor.Map);
                job.placedThings = null;
                return(ingredients);
            }
            List <Thing> list = new List <Thing>();

            if (job.placedThings != null)
            {
                for (int i = 0; i < job.placedThings.Count; i++)
                {
                    if (job.placedThings[i].Count <= 0)
                    {
                        Log.Error("PlacedThing " + job.placedThings[i] + " with count " + job.placedThings[i].Count + " for job " + job);
                    }
                    else
                    {
                        Thing thing = (job.placedThings[i].Count >= job.placedThings[i].thing.stackCount) ? job.placedThings[i].thing : job.placedThings[i].thing.SplitOff(job.placedThings[i].Count);
                        job.placedThings[i].Count = 0;
                        if (list.Contains(thing))
                        {
                            Log.Error("Tried to add ingredient from job placed targets twice: " + thing);
                        }
                        else
                        {
                            list.Add(thing);
                            if (job.RecipeDef.autoStripCorpses)
                            {
                                (thing as IStrippable)?.Strip();
                            }
                        }
                    }
                }
            }
            job.placedThings = null;
            return(list);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.B);
            if (!forbiddenInitially)
            {
                this.FailOnForbidden(TargetIndex.A);
            }
            Toil reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A);

            yield return(reserveTargetA);

            Toil toilGoto = null;

            toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn((Func <bool>) delegate
            {
                Pawn actor = toilGoto.actor;
                Job curJob = actor.jobs.curJob;
                if (curJob.haulMode == HaulMode.ToCellStorage)
                {
                    Thing thing = curJob.GetTarget(TargetIndex.A).Thing;
                    if (!actor.jobs.curJob.GetTarget(TargetIndex.B).Cell.IsValidStorageFor(base.Map, thing))
                    {
                        return(true);
                    }
                }
                return(false);
            });
            yield return(toilGoto);

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true));

            if (job.haulOpportunisticDuplicates)
            {
                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, TargetIndex.A, TargetIndex.B));
            }
            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, storageMode: true));
        }
예제 #27
0
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (uft != null && uft.def.MadeFromStuff)
            {
                return(uft.ingredients.First((Thing ing) => ing.def == uft.Stuff));
            }
            if (!ingredients.NullOrEmpty())
            {
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    return(ingredients[0]);
                }
                if (job.RecipeDef.products.Any((ThingDefCountClass x) => x.thingDef.MadeFromStuff))
                {
                    return(ingredients.Where((Thing x) => x.def.IsStuff).RandomElementByWeight((Thing x) => x.stackCount));
                }
                return(ingredients.RandomElementByWeight((Thing x) => x.stackCount));
            }
            return(null);
        }
예제 #28
0
        public static Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false, float maxRangeFactor = 1f)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn  actor     = toil.actor;
                Job   curJob    = actor.jobs.curJob;
                Thing targThing = curJob.GetTarget(targetInd).Thing;
                Pawn  targPawn  = targThing as Pawn;

                //We get closer if the target is downed and we can
                CastPositionRequest req = new CastPositionRequest();
                req.caster             = toil.actor;
                req.target             = targThing;
                req.verb               = curJob.verbToUse;
                req.maxRangeFromTarget = (!closeIfDowned || targPawn == null || !targPawn.Downed)
                                        ? Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, ShootTuning.MeleeRange)
                                        : Mathf.Min(curJob.verbToUse.verbProps.range, targPawn.RaceProps.executionRange);
                req.wantCoverFromTarget = false;

                IntVec3 dest;
                if (!CastPositionFinder.TryFindCastPosition(req, out dest))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                toil.actor.pather.StartPath(dest, PathEndMode.OnCell);

                actor.Map.pawnDestinationReservationManager.Reserve(actor, curJob, dest);
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;

            return(toil);
        }
        public static Toil MoveCurrentTargetIntoQueue(TargetIndex ind)
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Job             curJob = toil.actor.CurJob;
                LocalTargetInfo target = curJob.GetTarget(ind);
                if (target.IsValid)
                {
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind);
                    if (targetQueue == null)
                    {
                        curJob.AddQueuedTarget(ind, target);
                    }
                    else
                    {
                        targetQueue.Insert(0, target);
                    }
                    curJob.SetTarget(ind, null);
                }
            };
            return(toil);
        }
예제 #30
0
        public static Toil DoRecipeWork()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Initialized)
                {
                    jobDriver_DoBill.workLeft = unfinishedThing.workLeft;
                }
                else
                {
                    jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff);
                    if (unfinishedThing != null)
                    {
                        unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                    }
                }
                jobDriver_DoBill.billStartTick             = Find.TickManager.TicksGame;
                jobDriver_DoBill.ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
            };
            toil.tickAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                jobDriver_DoBill.ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing)
                {
                    actor.skills.Learn(curJob.RecipeDef.workSkill, 0.1f * curJob.RecipeDef.workSkillLearnFactor, false);
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                jobDriver_DoBill.workLeft -= num;
                if (unfinishedThing != null)
                {
                    unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                }
                actor.GainComfortFromCellIfPossible();
                if (jobDriver_DoBill.workLeft <= 0f)
                {
                    jobDriver_DoBill.ReadyForNextToil();
                }
                if (curJob.bill.recipe.UsesUnfinishedThing)
                {
                    int num2 = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick;
                    if (num2 >= 3000 && num2 % 1000 == 0)
                    {
                        actor.jobs.CheckForJobOverride();
                    }
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.CurJob;
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff));
            }, false, -0.5f);
            toil.FailOn(() => toil.actor.CurJob.bill.suspended);
            toil.activeSkill = (() => toil.actor.CurJob.bill.recipe.workSkill);
            return(toil);
        }