private void MakeDowned(DamageInfo?dinfo, Hediff hediff)
 {
     if (this.Downed)
     {
         Log.Error(this.pawn + " tried to do MakeDowned while already downed.", false);
     }
     else
     {
         if (this.pawn.guilt != null && this.pawn.GetLord() != null && this.pawn.GetLord().LordJob != null && this.pawn.GetLord().LordJob.GuiltyOnDowned)
         {
             this.pawn.guilt.Notify_Guilty();
         }
         this.healthState = PawnHealthState.Down;
         PawnDiedOrDownedThoughtsUtility.TryGiveThoughts(this.pawn, dinfo, PawnDiedOrDownedThoughtsKind.Downed);
         if (this.pawn.InMentalState)
         {
             this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState();
         }
         if (this.pawn.Spawned)
         {
             if (this.pawn.IsColonist && dinfo != null && dinfo.Value.Def.externalViolence)
             {
                 Find.StoryWatcher.watcherRampUp.Notify_ColonistViolentlyDownedOrKilled(this.pawn);
             }
             this.pawn.DropAndForbidEverything(true);
             this.pawn.stances.CancelBusyStanceSoft();
         }
         this.pawn.ClearMind(true);
         if (Current.ProgramState == ProgramState.Playing)
         {
             Lord lord = this.pawn.GetLord();
             if (lord != null)
             {
                 lord.Notify_PawnLost(this.pawn, PawnLostCondition.IncappedOrKilled);
             }
         }
         if (this.pawn.Drafted)
         {
             this.pawn.drafter.Drafted = false;
         }
         PortraitsCache.SetDirty(this.pawn);
         if (this.pawn.SpawnedOrAnyParentSpawned)
         {
             GenHostility.Notify_PawnLostForTutor(this.pawn, this.pawn.MapHeld);
         }
         if (this.pawn.RaceProps.Humanlike && Current.ProgramState == ProgramState.Playing && this.pawn.SpawnedOrAnyParentSpawned)
         {
             if (this.pawn.HostileTo(Faction.OfPlayer))
             {
                 LessonAutoActivator.TeachOpportunity(ConceptDefOf.Capturing, this.pawn, OpportunityType.Important);
             }
             if (this.pawn.Faction == Faction.OfPlayer)
             {
                 LessonAutoActivator.TeachOpportunity(ConceptDefOf.Rescuing, this.pawn, OpportunityType.Critical);
             }
         }
         if (dinfo != null && dinfo.Value.Instigator != null)
         {
             Pawn pawn = dinfo.Value.Instigator as Pawn;
             if (pawn != null)
             {
                 RecordsUtility.Notify_PawnDowned(this.pawn, pawn);
             }
         }
         if (this.pawn.Spawned)
         {
             TaleRecorder.RecordTale(TaleDefOf.Downed, new object[]
             {
                 this.pawn,
                 (dinfo == null) ? null : (dinfo.Value.Instigator as Pawn),
                 (dinfo == null) ? null : dinfo.Value.Weapon
             });
             Find.BattleLog.Add(new BattleLogEntry_StateTransition(this.pawn, RulePackDefOf.Transition_Downed, (dinfo == null) ? null : (dinfo.Value.Instigator as Pawn), hediff, (dinfo == null) ? null : dinfo.Value.HitPart));
         }
     }
 }
예제 #2
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            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;
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false);
                }
                List <Thing> ingredients        = Toils_Recipe.CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = Toils_Recipe.CalculateDominantIngredient(curJob, ingredients);
                List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList <Thing>();
                Toils_Recipe.ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);
                curJob.bill.Notify_IterationCompleted(actor, ingredients);
                RecordsUtility.Notify_BillDone(actor, list);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff) >= 10000f && list.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, new object[]
                    {
                        actor,
                        list[0].def
                    });
                }
                if (list.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    return;
                }
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null, null))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[i],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    return;
                }
                if (list.Count > 1)
                {
                    for (int j = 1; j < list.Count; j++)
                    {
                        if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null, null))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[j],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                }
                IntVec3 invalid = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out invalid, true);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out invalid, true);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246, false);
                }
                if (invalid.IsValid)
                {
                    actor.carryTracker.TryStartCarry(list[0]);
                    curJob.targetB = invalid;
                    curJob.targetA = list[0];
                    curJob.count   = 99999;
                    return;
                }
                if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null))
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Bill doer could not drop product ",
                        list[0],
                        " near ",
                        actor.Position
                    }), false);
                }
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
            };
            return(toil);
        }
        public static Toil FinishRecipeAndStartStoringCorpse(TargetIndex corpseIndex)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn   actor  = toil.actor;
                Job    curJob = actor.jobs.curJob;
                Corpse corpse = actor.jobs.curJob.GetTarget(TargetIndex.B).Thing as Corpse;

                actor.skills.GetSkill(SkillDefOf.Medicine).Learn(Dissection.Singleton.ExpPerCorpse, Dissection.Singleton.IgnoreDailyLimit);

                ApplyThoughts(actor, corpse);
                RecordTale(actor, corpse);

                bool destroyedBody = RemoveDissectedBodyParts(actor, corpse);

                curJob.bill.Notify_IterationCompleted(actor, new List <Thing>()
                {
                    corpse
                });
                RecordsUtility.Notify_BillDone(actor, new List <Thing>()
                {
                    corpse
                });

                if (destroyedBody)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                IntVec3 bestStoreCell = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(corpse, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out bestStoreCell, true);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(corpse, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out bestStoreCell, true);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246, false);
                }

                if (bestStoreCell.IsValid)
                {
                    corpse.DeSpawn();
                    actor.carryTracker.TryStartCarry(corpse);
                    curJob.targetC = bestStoreCell;
                    curJob.targetB = corpse;
                    curJob.count   = 99999;

                    curJob.placedThings?.Clear();
                }
                else
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
            };
            return(toil);
        }
        private Toil FinishRecipeAndStartStoringProduct()
        {
            //Reflection info
            MethodInfo CalculateIngredientsInfo        = AccessTools.Method(typeof(Toils_Recipe), "CalculateIngredients", new Type[] { typeof(Job), typeof(Pawn) });
            MethodInfo CalculateDominantIngredientInfo = AccessTools.Method(typeof(Toils_Recipe), "CalculateDominantIngredient", new Type[] { typeof(Job), typeof(List <Thing>) });
            MethodInfo ConsumeIngredientsInfo          = AccessTools.Method(typeof(Toils_Recipe), "ConsumeIngredients", new Type[] { typeof(List <Thing>), typeof(RecipeDef), typeof(Map) });
            //

            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;
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false);
                }
                List <Thing> ingredients        = (List <Thing>)CalculateIngredientsInfo.Invoke(this, new object[] { curJob, actor });
                Thing        dominantIngredient = (Thing)CalculateDominantIngredientInfo.Invoke(this, new object[] { curJob, ingredients });
                List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList <Thing>();
                ConsumeIngredientsInfo.Invoke(this, new object[] { ingredients, curJob.RecipeDef, actor.Map });
                curJob.bill.Notify_IterationCompleted(actor, ingredients);
                RecordsUtility.Notify_BillDone(actor, list);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing != null) ? unfinishedThing.Stuff : null) >= 10000f && list.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, new object[]
                    {
                        actor,
                        list[0].GetInnerIfMinified().def
                    });
                }
                if (list.Any <Thing>())
                {
                    Find.QuestManager.Notify_ThingsProduced(actor, list);
                    techComp.homework.Remove(project);
                }
                if (list.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                    return;
                }
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4)))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[i],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                    return;
                }
                if (list.Count > 1)
                {
                    for (int j = 1; j < list.Count; j++)
                    {
                        if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4)))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[j],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                }
                IHaulDestination destination;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterNonSlotGroupStorageFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out destination);
                    curJob.targetB = destination as Thing;
                    curJob.targetA = list[0];
                    curJob.count   = 1;
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246, false);
                }
                if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4)))
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Bill doer could not drop product ",
                        list[0],
                        " near ",
                        actor.Position
                    }), false);
                }
            };
            return(toil);
        }
 private void MakeDowned(DamageInfo?dinfo, Hediff hediff)
 {
     if (Downed)
     {
         Log.Error(string.Concat(this.pawn, " tried to do MakeDowned while already downed."));
         return;
     }
     if (this.pawn.guilt != null && this.pawn.GetLord() != null && this.pawn.GetLord().LordJob != null && this.pawn.GetLord().LordJob.GuiltyOnDowned)
     {
         this.pawn.guilt.Notify_Guilty();
     }
     healthState = PawnHealthState.Down;
     PawnDiedOrDownedThoughtsUtility.TryGiveThoughts(this.pawn, dinfo, PawnDiedOrDownedThoughtsKind.Downed);
     if (this.pawn.InMentalState && this.pawn.MentalStateDef.recoverFromDowned)
     {
         this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState();
     }
     if (this.pawn.Spawned)
     {
         this.pawn.DropAndForbidEverything(keepInventoryAndEquipmentIfInBed: true);
         this.pawn.stances.CancelBusyStanceSoft();
     }
     this.pawn.ClearMind(ifLayingKeepLaying: true, clearInspiration: false, clearMentalState: false);
     if (Current.ProgramState == ProgramState.Playing)
     {
         Lord lord = this.pawn.GetLord();
         if (lord != null && (lord.LordJob == null || lord.LordJob.RemoveDownedPawns))
         {
             lord.Notify_PawnLost(this.pawn, PawnLostCondition.IncappedOrKilled, dinfo);
         }
     }
     if (this.pawn.Drafted)
     {
         this.pawn.drafter.Drafted = false;
     }
     PortraitsCache.SetDirty(this.pawn);
     if (this.pawn.SpawnedOrAnyParentSpawned)
     {
         GenHostility.Notify_PawnLostForTutor(this.pawn, this.pawn.MapHeld);
     }
     if (this.pawn.RaceProps.Humanlike && Current.ProgramState == ProgramState.Playing && this.pawn.SpawnedOrAnyParentSpawned)
     {
         if (this.pawn.HostileTo(Faction.OfPlayer))
         {
             LessonAutoActivator.TeachOpportunity(ConceptDefOf.Capturing, this.pawn, OpportunityType.Important);
         }
         if (this.pawn.Faction == Faction.OfPlayer)
         {
             LessonAutoActivator.TeachOpportunity(ConceptDefOf.Rescuing, this.pawn, OpportunityType.Critical);
         }
     }
     if (dinfo.HasValue && dinfo.Value.Instigator != null)
     {
         Pawn pawn = dinfo.Value.Instigator as Pawn;
         if (pawn != null)
         {
             RecordsUtility.Notify_PawnDowned(this.pawn, pawn);
         }
     }
     if (this.pawn.Spawned)
     {
         TaleRecorder.RecordTale(TaleDefOf.Downed, this.pawn, dinfo.HasValue ? (dinfo.Value.Instigator as Pawn) : null, dinfo.HasValue ? dinfo.Value.Weapon : null);
         Find.BattleLog.Add(new BattleLogEntry_StateTransition(this.pawn, RulePackDefOf.Transition_Downed, dinfo.HasValue ? (dinfo.Value.Instigator as Pawn) : null, hediff, dinfo.HasValue ? dinfo.Value.HitPart : null));
     }
     Find.Storyteller.Notify_PawnEvent(this.pawn, AdaptationEvent.Downed, dinfo);
 }
예제 #6
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                var actor  = toil.actor;
                var curJob = actor.jobs.curJob;
                var driver = ((JobDriver_DoBill)actor.jobs.curDriver);

                //Learn (if the recipe doesn't use unfinished thing)
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = driver.ticksSpentDoingRecipeWork * SkillTuning.XpPerTickRecipeBase * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp);
                }

                //Calculate ingredients
                List <Thing> ingredients        = CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = CalculateDominantIngredient(curJob, ingredients);

                //Make the products
                var products = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, driver.BillGiver).ToList();

                //Consume the ingredients
                ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);

                //Notify bill
                curJob.bill.Notify_IterationCompleted(actor, ingredients);

                //Add records
                RecordsUtility.Notify_BillDone(actor, products);

                //Add tale
                var uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal(uft != null ? uft.Stuff : null) >= LongCraftingProjectThreshold && products.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, products[0].GetInnerIfMinified().def);
                }

                //----------------------------------------------------
                //Rearrange the job so the bill doer goes and stores the product
                //----------------------------------------------------

                //Nothing to store? End the job now
                if (products.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                //Bill is set to drop-on-floor mode?
                //Drop everything and end the job now
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < products.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position);
                        }
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                //Place all products except the first one on the ground
                if (products.Count > 1)
                {
                    for (int i = 1; i < products.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position);
                        }
                    }
                }

                //Try find a cell to take the product to
                IntVec3 storeCell = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out storeCell);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out storeCell);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246);
                }

                if (storeCell.IsValid)
                {
                    //Start carrying the first product and proceed to the storage toils
                    actor.carryTracker.TryStartCarry(products[0]);

                    curJob.targetB = storeCell;
                    curJob.targetA = products[0];
                    curJob.count   = 99999;
                }
                else
                {
                    //No store cell? Drop the product; we're done.
                    if (!GenPlace.TryPlaceThing(products[0], actor.Position, actor.Map, ThingPlaceMode.Near))
                    {
                        Log.Error("Bill doer could not drop product " + products[0] + " near " + actor.Position);
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }
            };

            return(toil);
        }
예제 #7
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            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;
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = (float)((float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.10999999940395355 * curJob.RecipeDef.workSkillLearnFactor);
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false);
                }
                List <Thing> ingredients        = Toils_Recipe.CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = Toils_Recipe.CalculateDominantIngredient(curJob, ingredients);
                List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient).ToList();
                Toils_Recipe.ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);
                curJob.bill.Notify_IterationCompleted(actor, ingredients);
                RecordsUtility.Notify_BillDone(actor, list);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff) >= 20000.0 && list.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, list[0].def);
                }
                if (list.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                        {
                            Log.Error(actor + " could not drop recipe product " + list[i] + " near " + actor.Position);
                        }
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
                else
                {
                    if (list.Count > 1)
                    {
                        for (int j = 1; j < list.Count; j++)
                        {
                            if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                            {
                                Log.Error(actor + " could not drop recipe product " + list[j] + " near " + actor.Position);
                            }
                        }
                    }
                    list[0].SetPositionDirect(actor.Position);
                    IntVec3 c = default(IntVec3);
                    if (StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true))
                    {
                        actor.carryTracker.TryStartCarry(list[0]);
                        curJob.targetB = c;
                        curJob.targetA = list[0];
                        curJob.count   = 99999;
                    }
                    else
                    {
                        if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                        {
                            Log.Error("Bill doer could not drop product " + list[0] + " near " + actor.Position);
                        }
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    }
                }
            };
            return(toil);
        }
        // Token: 0x0600002F RID: 47 RVA: 0x00003958 File Offset: 0x00001B58
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            Log.Message("start finish recipe, store product.", false);
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Log.Message("in finishing", false);
                Pawn   actor  = toil.actor;
                Job    curJob = actor.jobs.curJob;
                string str    = "curJob";
                Job    job    = curJob;
                string str2   = (job != null) ? job.ToString() : null;
                string str3   = " actor ";
                Pawn   pawn   = actor;
                Log.Message(str + str2 + str3 + ((pawn != null) ? pawn.ToString() : null), false);
                JobDriver_WPDoBill jobDriver_WPDoBill = (JobDriver_WPDoBill)actor.jobs.curDriver;
                List <Thing>       list = Toils_WPRecipe.CalculateIngredients(curJob, actor);
                for (int i = 0; i < list.Count; i++)
                {
                    string str4  = "toils_wprecipe: ingredient[i] ";
                    Thing  thing = list[i];
                    Log.Message(str4 + ((thing != null) ? thing.ToString() : null), false);
                }
                Thing    thing2 = Toils_WPRecipe.CalculateDominantIngredient(curJob, list);
                string[] array  = new string[8];
                array[0] = "finishing: curJob.RecipeDef ";
                int       num       = 1;
                RecipeDef recipeDef = curJob.RecipeDef;
                array[num] = ((recipeDef != null) ? recipeDef.ToString() : null);
                array[2]   = " actor ";
                int  num2  = 3;
                Pawn pawn2 = actor;
                array[num2] = ((pawn2 != null) ? pawn2.ToString() : null);
                array[4]    = " ingredients ";
                int          num3  = 5;
                List <Thing> list2 = list;
                array[num3] = ((list2 != null) ? list2.ToString() : null);
                array[6]    = " dominantIngredient ";
                int   num4   = 7;
                Thing thing3 = thing2;
                array[num4] = ((thing3 != null) ? thing3.ToString() : null);
                Log.Message(string.Concat(array), false);
                List <Thing> list3 = WPGenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, list, thing2).ToList <Thing>();
                Toils_WPRecipe.ConsumeIngredients(list, curJob.RecipeDef, actor.Map);
                curJob.bill.Notify_IterationCompleted(actor, list);
                RecordsUtility.Notify_BillDone(actor, list3);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                bool            flag            = list3.Count == 0;
                if (flag)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                }
                else
                {
                    bool flag2 = curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor;
                    if (flag2)
                    {
                        for (int j = 0; j < list3.Count; j++)
                        {
                            bool flag3 = !GenPlace.TryPlaceThing(list3[j], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4));
                            if (flag3)
                            {
                                Log.Error(string.Concat(new object[]
                                {
                                    actor,
                                    " could not drop recipe product ",
                                    list3[j],
                                    " near ",
                                    actor.Position
                                }), false);
                            }
                        }
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                    }
                    else
                    {
                        bool flag4 = list3.Count > 1;
                        if (flag4)
                        {
                            for (int k = 1; k < list3.Count; k++)
                            {
                                bool flag5 = !GenPlace.TryPlaceThing(list3[k], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4));
                                if (flag5)
                                {
                                    Log.Error(string.Concat(new object[]
                                    {
                                        actor,
                                        " could not drop recipe product ",
                                        list3[k],
                                        " near ",
                                        actor.Position
                                    }), false);
                                }
                            }
                        }
                        list3[0].SetPositionDirect(actor.Position);
                        IntVec3 c;
                        bool    flag6 = StoreUtility.TryFindBestBetterStoreCellFor(list3[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true);
                        if (flag6)
                        {
                            actor.carryTracker.TryStartCarry(list3[0]);
                            curJob.targetB = c;
                            curJob.targetA = list3[0];
                            curJob.count   = 99999;
                        }
                        else
                        {
                            bool flag7 = !GenPlace.TryPlaceThing(list3[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4));
                            if (flag7)
                            {
                                Log.Error(string.Concat(new object[]
                                {
                                    "Bill doer could not drop product ",
                                    list3[0],
                                    " near ",
                                    actor.Position
                                }), false);
                            }
                            actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                        }
                    }
                }
            };
            return(toil);
        }
예제 #9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //This toil is yielded later
            var gotoBillGiver = Toils_Goto.GotoThing(TI_REPBENCH, PathEndMode.InteractionCell);

            this.FailOnDestroyedNullOrForbidden(TI_REPBENCH);
            this.FailOnBurningImmobile(TI_REPBENCH);

            //Reserve the bill giver and all the ingredients
            yield return(Toils_Reserve.Reserve(TI_REPBENCH));

            yield return(Toils_Reserve.ReserveQueue(TI_ITEM));

            //these are initially set up by workgiver
            var itemTargetQueue = job.GetTargetQueue(TI_ITEM);

            if (itemTargetQueue.NullOrEmpty())
            {
                Log.Warning("RepBench: JobDriver - itemTargetQueue was null.");
                yield return(Toils_Reserve.Release(TI_REPBENCH));

                yield return(Toils_Reserve.Release(TI_ITEM));

                yield break;
            }

            var firstTargetInfo = itemTargetQueue.First();
            var item            = firstTargetInfo.Thing;

            var table = job.GetTarget(TI_REPBENCH).Thing as Building_WorkTable;

            if (table == null)
            {
                Log.Warning("RepBench: JobDriver - RepairTable was null.");
                yield return(Toils_Reserve.Release(TI_REPBENCH));

                yield return(Toils_Reserve.Release(TI_ITEM));

                yield break;
            }

            //Gather ingredients
            {
                //Extract an ingredient into TargetB
                var extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TI_ITEM);
                yield return(extract);

                //Get to ingredient and pick it up
                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.
                var getToHaulTarget = Toils_Goto.GotoThing(TI_ITEM, PathEndMode.ClosestTouch)
                                      .FailOnDespawnedNullOrForbidden(TI_ITEM);
                yield return(getToHaulTarget);

                yield return(Toils_Haul.StartCarryThing(TI_ITEM));

                //Jump to pick up more in this run if we're collecting from multiple stacks at once
                yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B));

                //Carry ingredient to the bill giver and put it on the square
                yield return(Toils_Goto.GotoThing(TI_REPBENCH, PathEndMode.InteractionCell)
                             .FailOnDestroyedOrNull(TI_ITEM));

                var findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TI_REPBENCH, TI_ITEM, TI_CELL);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TI_CELL, findPlaceTarget, false));

                //Jump back if there is another ingredient needed
                //Can happen if you can't carry all the ingredients in one run
                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TI_ITEM, extract));
            }

            //For it no ingredients needed, just go to the bill giver
            //This will do nothing if we took ingredients and are thus already at the bill giver
            yield return(gotoBillGiver);

            var controller = new ItemRepairProgress(pawn,
                                                    table.IngredientStackCells,
                                                    WorkGiver_Repair.CalculateTotalIngredients(item),
                                                    item.MaxHitPoints - item.HitPoints);

            float ticksToNextRepair = Settings.RepairRate;
            var   repairedAmount    = 0;
            var   repairToil        = new Toil
            {
                initAction = () =>
                {
                    Debug.PrintLine("repairToil.PreInit");
                    job.bill.Notify_DoBillStarted(pawn);
                    Debug.PrintLine("repairToil.PostInit");
                },

                tickAction = () =>
                {
//                    Debug.PrintLine("repairToil.tick.Check");
//                    pawn.jobs.CheckForJobOverride();

                    job.bill.Notify_PawnDidWork(pawn);
                    job.SetTarget(TargetIndex.B, item);

                    pawn.skills.Learn(SkillDefOf.Crafting, Settings.SkillGain);
                    pawn.GainComfortFromCellIfPossible();

                    ticksToNextRepair -= pawn.GetStatValue(StatDefOf.WorkSpeedGlobal) * table.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor);
                    if (ticksToNextRepair > 0.0)
                    {
                        return;
                    }

                    ticksToNextRepair = Settings.RepairRate;
                    item.HitPoints   += Settings.HP_GAIN;
                    repairedAmount   += Settings.HP_GAIN;

                    if (!controller.AddRepairedAmount(Settings.HP_GAIN))
                    {
                        //Technically we did not Succeed, but the job itself did not fail, we just ran out of kits.
                        EndJobWith(JobCondition.Succeeded);
                        return;
                    }

                    if (item.HitPoints < item.MaxHitPoints)
                    {
                        return;
                    }

                    // break
                    ReadyForNextToil();
                },
                defaultCompleteMode = ToilCompleteMode.Never
            };

            repairToil.WithEffect(item.def.repairEffect, TI_ITEM);
            yield return(repairToil);

            var itemRepairedToil = new Toil
            {
                initAction = () =>
                {
                    var list = new List <Thing> {
                        item
                    };
                    job.bill.Notify_IterationCompleted(pawn, list);
                    RecordsUtility.Notify_BillDone(pawn, list);
                }
            };

            yield return(itemRepairedToil);

            yield return(Toils_Haul.StartCarryThing(TI_ITEM));

            if (job.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
            {
                yield return(new Toil
                {
                    initAction = () =>
                    {
                        if (!StoreUtility.TryFindBestBetterStoreCellFor(item, pawn, pawn.Map, StoragePriority.Unstored,
                                                                        pawn.Faction, out var foundCell))
                        {
                            return;
                        }
                        pawn.Reserve(foundCell, job);
                        job.SetTarget(TI_CELL, foundCell);
                    }
                });