Beispiel #1
0
 public static void SetWindExposureColors(Color32[] colors, Plant plant)
 {
     colors[1].a = (colors[2].a = GenPlant.GetWindExposure(plant));
     colors[0].a = (colors[3].a = 0);
 }
 private static void CacheAccessibleThings(int nearTile)
 {
     if (nearTile != cachedAccessibleThingsForTile || RealTime.frameCount != cachedAccessibleThingsForFrame)
     {
         cachedAccessibleThings.Clear();
         cachedPossiblyAccessibleThings.Clear();
         cachedMakeableItemDefs.Clear();
         WorldGrid  worldGrid = Find.WorldGrid;
         List <Map> maps      = Find.Maps;
         for (int i = 0; i < maps.Count; i++)
         {
             float num = worldGrid.ApproxDistanceInTiles(nearTile, maps[i].Tile);
             if (!(num > 5f))
             {
                 ThingOwnerUtility.GetAllThingsRecursively(maps[i], tmpThings, allowUnreal: false);
                 cachedAccessibleThings.AddRange(tmpThings);
             }
         }
         List <Caravan> caravans = Find.WorldObjects.Caravans;
         for (int j = 0; j < caravans.Count; j++)
         {
             if (caravans[j].IsPlayerControlled)
             {
                 float num2 = worldGrid.ApproxDistanceInTiles(nearTile, caravans[j].Tile);
                 if (!(num2 > 5f))
                 {
                     ThingOwnerUtility.GetAllThingsRecursively(caravans[j], tmpThings, allowUnreal: false);
                     cachedAccessibleThings.AddRange(tmpThings);
                 }
             }
         }
         for (int k = 0; k < cachedAccessibleThings.Count; k++)
         {
             Thing thing = cachedAccessibleThings[k];
             cachedPossiblyAccessibleThings.Add(new ThingDefCount(thing.def, thing.stackCount));
             if (GenLeaving.CanBuildingLeaveResources(thing, DestroyMode.Deconstruct))
             {
                 List <ThingDefCountClass> list = thing.CostListAdjusted();
                 for (int l = 0; l < list.Count; l++)
                 {
                     int num3 = Mathf.RoundToInt((float)list[l].count * thing.def.resourcesFractionWhenDeconstructed);
                     if (num3 > 0)
                     {
                         cachedPossiblyAccessibleThings.Add(new ThingDefCount(list[l].thingDef, num3));
                         cachedMakeableItemDefs.Add(list[l].thingDef);
                     }
                 }
             }
             Plant plant = thing as Plant;
             if (plant != null && (plant.HarvestableNow || plant.HarvestableSoon))
             {
                 int num4 = Mathf.RoundToInt(plant.def.plant.harvestYield * Find.Storyteller.difficulty.cropYieldFactor);
                 if (num4 > 0)
                 {
                     cachedPossiblyAccessibleThings.Add(new ThingDefCount(plant.def.plant.harvestedThingDef, num4));
                     cachedMakeableItemDefs.Add(plant.def.plant.harvestedThingDef);
                 }
             }
             if (!thing.def.butcherProducts.NullOrEmpty())
             {
                 for (int m = 0; m < thing.def.butcherProducts.Count; m++)
                 {
                     cachedPossiblyAccessibleThings.Add(thing.def.butcherProducts[m]);
                     cachedMakeableItemDefs.Add(thing.def.butcherProducts[m].thingDef);
                 }
             }
             Pawn pawn = thing as Pawn;
             if (pawn != null)
             {
                 if (pawn.RaceProps.meatDef != null)
                 {
                     int num5 = Mathf.RoundToInt(pawn.GetStatValue(StatDefOf.MeatAmount));
                     if (num5 > 0)
                     {
                         cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.meatDef, num5));
                         cachedMakeableItemDefs.Add(pawn.RaceProps.meatDef);
                     }
                 }
                 if (pawn.RaceProps.leatherDef != null)
                 {
                     int num6 = GenMath.RoundRandom(pawn.GetStatValue(StatDefOf.LeatherAmount));
                     if (num6 > 0)
                     {
                         cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.leatherDef, num6));
                         cachedMakeableItemDefs.Add(pawn.RaceProps.leatherDef);
                     }
                 }
                 if (!pawn.RaceProps.Humanlike)
                 {
                     PawnKindLifeStage curKindLifeStage = pawn.ageTracker.CurKindLifeStage;
                     if (curKindLifeStage.butcherBodyPart != null)
                     {
                         cachedPossiblyAccessibleThings.Add(new ThingDefCount(curKindLifeStage.butcherBodyPart.thing, 1));
                         cachedMakeableItemDefs.Add(curKindLifeStage.butcherBodyPart.thing);
                     }
                 }
             }
             if (thing.def.smeltable)
             {
                 List <ThingDefCountClass> list2 = thing.CostListAdjusted();
                 for (int n = 0; n < list2.Count; n++)
                 {
                     if (!list2[n].thingDef.intricate)
                     {
                         int num7 = Mathf.RoundToInt((float)list2[n].count * 0.25f);
                         if (num7 > 0)
                         {
                             cachedPossiblyAccessibleThings.Add(new ThingDefCount(list2[n].thingDef, num7));
                             cachedMakeableItemDefs.Add(list2[n].thingDef);
                         }
                     }
                 }
             }
             if (thing.def.smeltable && !thing.def.smeltProducts.NullOrEmpty())
             {
                 for (int num8 = 0; num8 < thing.def.smeltProducts.Count; num8++)
                 {
                     cachedPossiblyAccessibleThings.Add(thing.def.smeltProducts[num8]);
                     cachedMakeableItemDefs.Add(thing.def.smeltProducts[num8].thingDef);
                 }
             }
         }
         int num9 = 0;
         for (int num10 = 0; num10 < cachedAccessibleThings.Count; num10++)
         {
             Pawn pawn2 = cachedAccessibleThings[num10] as Pawn;
             if (pawn2 != null && pawn2.IsFreeColonist && !pawn2.Dead && !pawn2.Downed && pawn2.workSettings.WorkIsActive(WorkTypeDefOf.Crafting))
             {
                 num9++;
             }
         }
         if (num9 > 0)
         {
             tmpWorkTables.Clear();
             for (int num11 = 0; num11 < cachedAccessibleThings.Count; num11++)
             {
                 Building_WorkTable building_WorkTable = cachedAccessibleThings[num11] as Building_WorkTable;
                 if (building_WorkTable != null && building_WorkTable.Spawned && tmpWorkTables.Add(building_WorkTable.def))
                 {
                     List <RecipeDef> allRecipes = building_WorkTable.def.AllRecipes;
                     for (int num12 = 0; num12 < allRecipes.Count; num12++)
                     {
                         if (allRecipes[num12].AvailableNow && allRecipes[num12].products.Any() && !allRecipes[num12].PotentiallyMissingIngredients(null, building_WorkTable.Map).Any())
                         {
                             ThingDef stuffDef = (!allRecipes[num12].products[0].thingDef.MadeFromStuff) ? null : GenStuff.DefaultStuffFor(allRecipes[num12].products[0].thingDef);
                             float    num13    = allRecipes[num12].WorkAmountTotal(stuffDef);
                             if (!(num13 <= 0f))
                             {
                                 int num14 = Mathf.FloorToInt((float)(num9 * 60000 * 5) * 0.09f / num13);
                                 if (num14 > 0)
                                 {
                                     for (int num15 = 0; num15 < allRecipes[num12].products.Count; num15++)
                                     {
                                         cachedPossiblyAccessibleThings.Add(new ThingDefCount(allRecipes[num12].products[num15].thingDef, allRecipes[num12].products[num15].count * num14));
                                         cachedMakeableItemDefs.Add(allRecipes[num12].products[num15].thingDef);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         cachedAccessibleThingsForTile  = nearTile;
         cachedAccessibleThingsForFrame = RealTime.frameCount;
     }
 }
        public static bool TryFindReproductionDestination(IntVec3 source, ThingDef plantDef, SeedTargFindMode mode, Map map, out IntVec3 foundCell)
        {
            float radius = -1f;

            switch (mode)
            {
            case SeedTargFindMode.Reproduce:
                radius = plantDef.plant.reproduceRadius;
                break;

            case SeedTargFindMode.MapGenCluster:
                radius = plantDef.plant.WildClusterRadiusActual;
                break;

            case SeedTargFindMode.MapEdge:
                radius = 40f;
                break;

            case SeedTargFindMode.Cave:
                radius = plantDef.plant.WildClusterRadiusActual;
                break;
            }
            int      num      = 0;
            int      num2     = 0;
            float    num3     = 0f;
            CellRect cellRect = CellRect.CenteredOn(source, Mathf.RoundToInt(radius));

            cellRect.ClipInsideMap(map);
            for (int i = cellRect.minZ; i <= cellRect.maxZ; i++)
            {
                for (int j = cellRect.minX; j <= cellRect.maxX; j++)
                {
                    IntVec3 c2    = new IntVec3(j, 0, i);
                    Plant   plant = c2.GetPlant(map);
                    if (plant != null && (mode != SeedTargFindMode.Cave || plant.def.plant.cavePlant))
                    {
                        num++;
                        if (plant.def == plantDef)
                        {
                            num2++;
                        }
                    }
                    num3 += c2.GetTerrain(map).fertility;
                }
            }
            float num4 = (float)((mode != SeedTargFindMode.Cave) ? map.Biome.plantDensity : 0.5);
            float num5 = num3 * num4;
            bool  flag = (float)num > num5;

            if ((float)num > num5 * 1.25)
            {
                foundCell = IntVec3.Invalid;
                return(false);
            }
            if (mode != 0 && mode != SeedTargFindMode.Cave)
            {
                BiomeDef curBiome = map.Biome;
                float    num6     = curBiome.AllWildPlants.Sum((ThingDef pd) => curBiome.CommonalityOfPlant(pd));
                float    num7     = curBiome.CommonalityOfPlant(plantDef) / num6;
                float    num8     = curBiome.CommonalityOfPlant(plantDef) * plantDef.plant.wildCommonalityMaxFraction / num6;
                float    num9     = num5 * num8;
                if ((float)num2 > num9)
                {
                    foundCell = IntVec3.Invalid;
                    return(false);
                }
                float num10 = num5 * num7;
                bool  flag2 = (float)num2 < num10 * 0.5;
                if (flag && !flag2)
                {
                    foundCell = IntVec3.Invalid;
                    return(false);
                }
            }
            Predicate <IntVec3> validator = delegate(IntVec3 c)
            {
                if (!plantDef.CanEverPlantAt(c, map))
                {
                    return(false);
                }
                if (plantDef.plant.cavePlant && !GenPlantReproduction.GoodRoofForCavePlantReproduction(c, map))
                {
                    return(false);
                }
                if (!GenPlant.SnowAllowsPlanting(c, map))
                {
                    return(false);
                }
                if (!source.InHorDistOf(c, radius))
                {
                    return(false);
                }
                if (!GenSight.LineOfSight(source, c, map, true, null, 0, 0))
                {
                    return(false);
                }
                return(true);
            };

            return(CellFinder.TryFindRandomCellNear(source, map, Mathf.CeilToInt(radius), validator, out foundCell));
        }
Beispiel #4
0
 public static byte GetWindExposure(Plant plant)
 {
     return((byte)Mathf.Min(255f * plant.def.plant.topWindExposure, 255f));
 }
        public override bool HasJobOnCell(Pawn pawn, IntVec3 c)
        {
            Plant plant = c.GetPlant(pawn.Map);

            return(plant != null && !plant.IsForbidden(pawn) && plant.HarvestableNow && plant.LifeStage == PlantLifeStage.Mature && plant.YieldNow() > 0 && pawn.CanReserve(plant, 1, -1, null, false));
        }
Beispiel #6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil meditate = new Toil
            {
                socialMode = RandomSocialMode.Off
            };

            if (FromBed)
            {
                this.KeepLyingDown(TargetIndex.B);
                meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false);
            }
            else
            {
                yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell));

                meditate.initAction = delegate
                {
                    LocalTargetInfo target = job.GetTarget(TargetIndex.C);
                    if (target.IsValid)
                    {
                        faceDir = target.Cell - pawn.Position;
                    }
                    else
                    {
                        faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell;
                    }
                };
                if (Focus != null)
                {
                    meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C);
                    if (pawn.HasPsylink && Focus.Thing != null)
                    {
                        meditate.FailOn(() => Focus.Thing.GetStatValueForPawn(StatDefOf.MeditationFocusStrength, pawn) < float.Epsilon);
                    }
                }
                meditate.handlingFacing = true;
            }
            meditate.defaultCompleteMode = ToilCompleteMode.Delay;
            meditate.defaultDuration     = job.def.joyDuration;
            meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map));
            meditate.AddPreTickAction(delegate
            {
                bool flag = pawn.GetTimeAssignment() == TimeAssignmentDefOf.Meditate;
                if (job.ignoreJoyTimeAssignment)
                {
                    Pawn_PsychicEntropyTracker psychicEntropy = pawn.psychicEntropy;
                    if (!flag && psychicEntropy.TargetPsyfocus < psychicEntropy.CurrentPsyfocus && (psychicEntropy.TargetPsyfocus < job.psyfocusTargetLast || job.wasOnMeditationTimeAssignment))
                    {
                        EndJobWith(JobCondition.InterruptForced);
                        return;
                    }
                    job.psyfocusTargetLast            = psychicEntropy.TargetPsyfocus;
                    job.wasOnMeditationTimeAssignment = flag;
                }
                if (faceDir.IsValid && !FromBed)
                {
                    pawn.rotationTracker.FaceCell(pawn.Position + faceDir);
                }
                MeditationTick();
                if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn))
                {
                    int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius);
                    for (int i = 0; i < num; i++)
                    {
                        IntVec3 c = pawn.Position + GenRadial.RadialPattern[i];
                        if (c.InBounds(pawn.Map))
                        {
                            Plant plant = c.GetPlant(pawn.Map);
                            if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima)
                            {
                                plant.TryGetComp <CompSpawnSubplant>()?.AddProgress_NewTmp(AnimaTreeSubplantProgressPerTick);
                            }
                        }
                    }
                }
            });
            yield return(meditate);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Init();
            yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A));

            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, (RequiredDesignation != null) ? ((Func <Thing, bool>)((Thing t) => base.Map.designationManager.DesignationOn(t, RequiredDesignation) != null)) : null);

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A));

            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A));

            Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue);

            if (RequiredDesignation != null)
            {
                toil.FailOnThingMissingDesignation(TargetIndex.A, RequiredDesignation);
            }
            yield return(toil);

            Toil cut = new Toil();

            cut.tickAction = delegate
            {
                Pawn actor = cut.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Plants, xpPerTick);
                }
                float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed);
                Plant plant     = Plant;
                statValue *= Mathf.Lerp(3.3f, 1f, plant.Growth);
                workDone  += statValue;
                if (workDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && !plant.Blighted && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield))
                        {
                            MoteMaker.ThrowText((pawn.DrawPos + plant.DrawPos) / 2f, base.Map, "TextMote_HarvestFailed".Translate(), 3.65f);
                        }
                        else
                        {
                            int num = plant.YieldNow();
                            if (num > 0)
                            {
                                Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef);
                                thing.stackCount = num;
                                if (actor.Faction != Faction.OfPlayer)
                                {
                                    thing.SetForbidden(value: true);
                                }
                                Find.QuestManager.Notify_PlantHarvested(actor, thing);
                                GenPlace.TryPlaceThing(thing, actor.Position, base.Map, ThingPlaceMode.Near);
                                actor.records.Increment(RecordDefOf.PlantsHarvested);
                            }
                        }
                    }
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    plant.PlantCollected();
                    workDone = 0f;
                    ReadyForNextToil();
                }
            };
            cut.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            if (RequiredDesignation != null)
            {
                cut.FailOnThingMissingDesignation(TargetIndex.A, RequiredDesignation);
            }
            cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            cut.defaultCompleteMode = ToilCompleteMode.Never;
            cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            cut.WithProgressBar(TargetIndex.A, () => workDone / Plant.def.plant.harvestWork, interpolateBetweenActorAndTarget: true);
            cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting);
            cut.activeSkill = () => SkillDefOf.Plants;
            yield return(cut);

            Toil toil2 = PlantWorkDoneToil();

            if (toil2 != null)
            {
                yield return(toil2);
            }
            yield return(Toils_Jump.Jump(initExtractTargetFromQueue));
        }
Beispiel #8
0
        private static bool IsSafeDropSpot(IntVec3 cell, Map map, Faction faction, IntVec2?size = null, int distToEdge = 25, int distToHostiles = 35, int distToFires = 15)
        {
            Faction factionBaseFaction = map.ParentFaction ?? Faction.OfPlayer;

            if (size.HasValue)
            {
                foreach (IntVec3 item in GenAdj.OccupiedRect(cell, Rot4.North, size.Value))
                {
                    if (!IsGoodDropSpot(item, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
                    {
                        return(false);
                    }
                }
            }
            else if (!IsGoodDropSpot(cell, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
            {
                return(false);
            }
            if (distToEdge > 0 && cell.CloseToEdge(map, distToEdge))
            {
                return(false);
            }
            if (faction != null)
            {
                foreach (IAttackTarget item2 in map.attackTargetsCache.TargetsHostileToFaction(faction))
                {
                    if (!item2.ThreatDisabled(null) && item2.Thing.Position.InHorDistOf(cell, distToHostiles))
                    {
                        return(false);
                    }
                }
            }
            if (!map.reachability.CanReachFactionBase(cell, factionBaseFaction))
            {
                return(false);
            }
            if (size.HasValue)
            {
                foreach (IntVec3 cell2 in CellRect.CenteredOn(cell, size.Value.x, size.Value.z).Cells)
                {
                    if (CellHasCrops(cell2))
                    {
                        return(false);
                    }
                }
            }
            else if (CellHasCrops(cell))
            {
                return(false);
            }
            float minDistToFiresSq = distToFires * distToFires;
            float closestDistSq    = float.MaxValue;
            int   firesCount       = 0;

            RegionTraverser.BreadthFirstTraverse(cell, map, (Region from, Region to) => true, delegate(Region x)
            {
                List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list.Count; i++)
                {
                    float num = cell.DistanceToSquared(list[i].Position);
                    if (!(num > minDistToFiresSq))
                    {
                        if (num < closestDistSq)
                        {
                            closestDistSq = num;
                        }
                        firesCount++;
                    }
                }
                return(closestDistSq <= minDistToFiresSq && firesCount >= 5);
            }, 15);
            if (closestDistSq <= minDistToFiresSq && firesCount >= 5)
            {
                return(false);
            }
            return(true);

            bool CellHasCrops(IntVec3 c)
            {
                Plant plant = c.GetPlant(map);

                if (plant != null && plant.sown)
                {
                    return(map.zoneManager.ZoneAt(c) is Zone_Growing);
                }
                return(false);
            }
        }
Beispiel #9
0
        public override Job JobOnCell(Pawn pawn, IntVec3 c)
        {
            Map map = pawn.Map;

            if (c.IsForbidden(pawn))
            {
                return(null);
            }
            if (!GenPlant.GrowthSeasonNow(c, map))
            {
                return(null);
            }
            if (WorkGiver_Grower.wantedPlantDef == null)
            {
                WorkGiver_Grower.wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, map);
                if (WorkGiver_Grower.wantedPlantDef == null)
                {
                    return(null);
                }
            }
            List <Thing> thingList = c.GetThingList(map);
            bool         flag      = false;

            for (int i = 0; i < thingList.Count; i++)
            {
                Thing thing = thingList[i];
                if (thing.def == WorkGiver_Grower.wantedPlantDef)
                {
                    return(null);
                }
                if ((thing is Blueprint || thing is Frame) && thing.Faction == pawn.Faction)
                {
                    flag = true;
                }
            }
            if (flag)
            {
                Thing edifice = c.GetEdifice(map);
                if (edifice != null && !(edifice.def.fertility < 0.0))
                {
                    goto IL_00dc;
                }
                return(null);
            }
            goto IL_00dc;
IL_00dc:
            if (WorkGiver_Grower.wantedPlantDef.plant.cavePlant)
            {
                if (!c.Roofed(map))
                {
                    JobFailReason.Is(WorkGiver_GrowerSow.CantSowCavePlantBecauseUnroofedTrans);
                    return(null);
                }
                if (map.glowGrid.GameGlowAt(c, true) > 0.0)
                {
                    JobFailReason.Is(WorkGiver_GrowerSow.CantSowCavePlantBecauseOfLightTrans);
                    return(null);
                }
            }
            Plant plant = c.GetPlant(map);

            if (plant != null && plant.def.plant.blockAdjacentSow)
            {
                if (pawn.CanReserve(plant, 1, -1, null, false) && !plant.IsForbidden(pawn))
                {
                    return(new Job(JobDefOf.CutPlant, plant));
                }
                return(null);
            }
            Thing thing2 = GenPlant.AdjacentSowBlocker(WorkGiver_Grower.wantedPlantDef, c, map);

            if (thing2 != null)
            {
                Plant plant2 = thing2 as Plant;
                if (plant2 != null && pawn.CanReserve(plant2, 1, -1, null, false) && !plant2.IsForbidden(pawn))
                {
                    IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map);
                    if (plantToGrowSettable != null && plantToGrowSettable.GetPlantDefToGrow() == plant2.def)
                    {
                        goto IL_0211;
                    }
                    return(new Job(JobDefOf.CutPlant, plant2));
                }
                goto IL_0211;
            }
            if (WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill > 0 && pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Growing).Level < WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill)
            {
                return(null);
            }
            for (int j = 0; j < thingList.Count; j++)
            {
                Thing thing3 = thingList[j];
                if (thing3.def.BlockPlanting)
                {
                    if (!pawn.CanReserve(thing3, 1, -1, null, false))
                    {
                        return(null);
                    }
                    if (thing3.def.category == ThingCategory.Plant)
                    {
                        if (!thing3.IsForbidden(pawn))
                        {
                            return(new Job(JobDefOf.CutPlant, thing3));
                        }
                        return(null);
                    }
                    if (thing3.def.EverHaulable)
                    {
                        return(HaulAIUtility.HaulAsideJobFor(pawn, thing3));
                    }
                    return(null);
                }
            }
            if (WorkGiver_Grower.wantedPlantDef.CanEverPlantAt(c, map) && GenPlant.GrowthSeasonNow(c, map) && pawn.CanReserve(c, 1, -1, null, false))
            {
                Job job = new Job(JobDefOf.Sow, c);
                job.plantDefToSow = WorkGiver_Grower.wantedPlantDef;
                return(job);
            }
            return(null);

IL_0211:
            return(null);
        }
Beispiel #10
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.Init();
            yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A));

            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, (this.RequiredDesignation == null) ? null : new Func <Thing, bool>((Thing t) => this.$this.Map.designationManager.DesignationOn(t, this.$this.RequiredDesignation) != null));

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A));

            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

            Toil gotoThing = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue);

            if (this.RequiredDesignation != null)
            {
                gotoThing.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation);
            }
            yield return(gotoThing);

            Toil cut = new Toil();

            cut.tickAction = delegate
            {
                Pawn actor = cut.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Plants, this.$this.xpPerTick, false);
                }
                float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                float num       = statValue;
                Plant plant     = this.$this.Plant;
                num *= Mathf.Lerp(3.3f, 1f, plant.Growth);
                this.$this.workDone += num;
                if (this.$this.workDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true))
                        {
                            Vector3 loc = (this.$this.pawn.DrawPos + plant.DrawPos) / 2f;
                            MoteMaker.ThrowText(loc, this.$this.Map, "TextMote_HarvestFailed".Translate(), 3.65f);
                        }
                        else
                        {
                            int num2 = plant.YieldNow();
                            if (num2 > 0)
                            {
                                Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);
                                thing.stackCount = num2;
                                if (actor.Faction != Faction.OfPlayer)
                                {
                                    thing.SetForbidden(true, true);
                                }
                                GenPlace.TryPlaceThing(thing, actor.Position, this.$this.Map, ThingPlaceMode.Near, null, null);
                                actor.records.Increment(RecordDefOf.PlantsHarvested);
                            }
                        }
                    }
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    plant.PlantCollected();
                    this.$this.workDone = 0f;
                    this.$this.ReadyForNextToil();
                    return;
                }
            };
            cut.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            if (this.RequiredDesignation != null)
            {
                cut.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation);
            }
            cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            cut.defaultCompleteMode = ToilCompleteMode.Never;
            cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            cut.WithProgressBar(TargetIndex.A, () => this.$this.workDone / this.$this.Plant.def.plant.harvestWork, true, -0.5f);
            cut.PlaySustainerOrSound(() => this.$this.Plant.def.plant.soundHarvesting);
            cut.activeSkill = (() => SkillDefOf.Plants);
            yield return(cut);

            Toil plantWorkDoneToil = this.PlantWorkDoneToil();

            if (plantWorkDoneToil != null)
            {
                yield return(plantWorkDoneToil);
            }
            yield return(Toils_Jump.Jump(initExtractTargetFromQueue));
        }
Beispiel #11
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil meditate = new Toil
            {
                socialMode = RandomSocialMode.Off
            };

            if (FromBed)
            {
                this.KeepLyingDown(TargetIndex.B);
                meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false);
            }
            else
            {
                yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell));

                meditate.initAction = delegate
                {
                    LocalTargetInfo target = job.GetTarget(TargetIndex.C);
                    if (target.IsValid)
                    {
                        faceDir = target.Cell - pawn.Position;
                    }
                    else
                    {
                        faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell;
                    }
                };
                if (Focus != null)
                {
                    meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C);
                }
                meditate.handlingFacing = true;
            }
            meditate.defaultCompleteMode = ToilCompleteMode.Delay;
            meditate.defaultDuration     = job.def.joyDuration;
            meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map));
            meditate.AddPreTickAction(delegate
            {
                if (faceDir.IsValid && !FromBed)
                {
                    pawn.rotationTracker.FaceCell(pawn.Position + faceDir);
                }
                pawn.GainComfortFromCellIfPossible();
                MeditationTick();
                if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn))
                {
                    int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius);
                    for (int i = 0; i < num; i++)
                    {
                        IntVec3 c = pawn.Position + GenRadial.RadialPattern[i];
                        if (c.InBounds(pawn.Map))
                        {
                            Plant plant = c.GetPlant(pawn.Map);
                            if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima)
                            {
                                plant.TryGetComp <CompSpawnSubplant>()?.AddProgress(AnimaTreeSubplantProgressPerTick);
                            }
                        }
                    }
                }
            });
            meditate.AddFinishAction(delegate
            {
                if (sustainer != null)
                {
                    sustainer.End();
                }
            });
            yield return(meditate);
        }
Beispiel #12
0
 public override void TickRare()
 {
     base.TickRare();
     this.SpreadTick--;
     if (this.growthPercent >= 1)
     {
         //check things in cell and react
         CheckThings(Position);
     }
     if (this.SpreadTick == 0)
     {
         //Pick a random direction cell
         IntVec3 dir = new IntVec3();
         dir = GenAdj.RandomAdjSquareCardinal(Position);
         //If in bounds
         if (dir.InBounds())
         {
             //If we find a tasty floor lets eat it nomnomnom
             TerrainDef terrain = dir.GetTerrain();
             if (terrain != null)
             {
                 //Only eat floor if not natural
                 if (terrain.defName != "Sand" &&
                     terrain.defName != "Soil" &&
                     terrain.defName != "MarshyTerrain" &&
                     terrain.defName != "SoilRich" &&
                     terrain.defName != "Mud" &&
                     terrain.defName != "Marsh" &&
                     terrain.defName != "Gravel" &&
                     terrain.defName != "RoughStone" &&
                     terrain.defName != "WaterDeep" &&
                     terrain.defName != "WaterShallow" &&
                     terrain.defName != "RoughHewnRock")
                 {
                     //And by eat i mean replace - TODO can you damage floors over time?
                     //Replace with soil - TODO for now, maybe change to regen tile later if possible
                     Find.TerrainGrid.SetTerrain(dir, TerrainDef.Named("Soil"));
                     //if theres no ivy here
                     if (!IvyInCell(dir))
                     {
                         if (dir.GetPlant() == null)
                         {
                             //no plant, move on
                         }
                         else
                         {
                             //Found plant, Kill it
                             Plant plant = dir.GetPlant();
                             plant.Destroy();
                         }
                         //Spawn more Ivy
                         SpawnIvy(dir);
                     }
                 }
                 //Its natural floor
                 else if (terrain.defName != "WaterDeep" &&
                          terrain.defName != "WaterShallow" &&
                          terrain.defName != "MarshyTerrain")
                 {
                     //if theres no ivy here
                     if (!IvyInCell(dir))
                     {
                         if (dir.GetPlant() == null)
                         {
                             //no plant, move on
                         }
                         else
                         {
                             //Found plant, Kill it
                             Plant plant = dir.GetPlant();
                             plant.Destroy();
                         }
                         //Spawn more Ivy
                         SpawnIvy(dir);
                     }
                 }
                 //its water or something I dont know of
                 else
                 {
                 }
             }
         }
         SpreadTick = OrigSpreadTick;
     }
     if (this.MutateTry == true)
     {
         Random random     = new Random();
         int    MutateRate = random.Next(1, 200);
         if (MutateRate == 3 || MutateRate == 23)
         {
             Building_GasPump GasPump = (Building_GasPump)ThingMaker.MakeThing(ThingDef.Named("GasPump"));
             GasPump.SetFactionDirect(factionDirect);
             if (hasNoBuildings(Position))
             {
                 GenSpawn.Spawn(GasPump, Position);
             }
             this.MutateTry = false;
             //Find.History.AddGameEvent("Gas here", GameEventType.BadNonUrgent, true, Position, string.Empty);
         }
         else if (MutateRate == 4 || MutateRate == 24)
         {
             Building_EggSac EggSac = (Building_EggSac)ThingMaker.MakeThing(ThingDef.Named("EggSac"));
             EggSac.SetFactionDirect(factionDirect);
             if (hasNoBuildings(Position))
             {
                 GenSpawn.Spawn(EggSac, Position);
             }
             this.MutateTry = false;
             //Find.History.AddGameEvent("Egg here", GameEventType.BadNonUrgent, true, Position, string.Empty);
         }
         else if (MutateRate == 5)
         {
             Building_Turret GenMortar = (Building_Turret)ThingMaker.MakeThing(ThingDef.Named("Turret_GenMortarSeed"));
             GenMortar.SetFactionDirect(factionDirect);
             if (hasNoBuildings(Position))
             {
                 GenSpawn.Spawn(GenMortar, Position);
             }
             this.MutateTry = false;
             //Find.History.AddGameEvent("Mortar here", GameEventType.BadNonUrgent, true, Position, string.Empty);
         }
         else if (MutateRate == 6)
         {
             Building_Turret GenTurret = (Building_Turret)ThingMaker.MakeThing(ThingDef.Named("GenTurretBase"));
             GenTurret.SetFactionDirect(factionDirect);
             if (hasNoBuildings(Position))
             {
                 GenSpawn.Spawn(GenTurret, Position);
             }
             this.MutateTry = false;
             //Find.History.AddGameEvent("Turret here", GameEventType.BadNonUrgent, true, Position, string.Empty);
         }
         else
         {
             this.MutateTry = false;
         }
     }
     if (stuckPawn != null)
     {
         int        damageAmountBase = 1;
         DamageInfo damageInfo       = new DamageInfo(this.dmgdef, damageAmountBase, this, null, null);
         stuckPawn.TakeDamage(damageInfo);
         stuckPawn = null;
     }
     if (stuckCorpse != null)
     {
         stuckCorpse.Destroy();
         stuckCorpse = null;
     }
 }
Beispiel #13
0
        public static Thing BestFoodSourceOnMap(Pawn getter, Pawn eater, bool desperate, out ThingDef foodDef, FoodPreferability maxPref = FoodPreferability.MealLavish, bool allowPlant = true, bool allowDrug = true, bool allowCorpse = true, bool allowDispenserFull = true, bool allowDispenserEmpty = true, bool allowForbidden = false, bool allowSociallyImproper = false, bool allowHarvest = false, bool forceScanWholeMap = false)
        {
            foodDef = null;
            bool getterCanManipulate = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);

            if (!getterCanManipulate && getter != eater)
            {
                Log.Error(getter + " tried to find food to bring to " + eater + " but " + getter + " is incapable of Manipulation.");
                return(null);
            }
            FoodPreferability minPref;

            if (eater.NonHumanlikeOrWildMan())
            {
                minPref = FoodPreferability.NeverForNutrition;
            }
            else if (desperate)
            {
                minPref = FoodPreferability.DesperateOnly;
            }
            else
            {
                minPref = (((int)eater.needs.food.CurCategory < 2) ? FoodPreferability.MealAwful : FoodPreferability.RawBad);
            }
            Predicate <Thing> foodValidator = delegate(Thing t)
            {
                Building_NutrientPasteDispenser building_NutrientPasteDispenser = t as Building_NutrientPasteDispenser;
                if (building_NutrientPasteDispenser != null)
                {
                    if (!allowDispenserFull || !getterCanManipulate || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability < (int)minPref || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability > (int)maxPref || !eater.WillEat(ThingDefOf.MealNutrientPaste, getter) || (t.Faction != getter.Faction && t.Faction != getter.HostFaction) || (!allowForbidden && t.IsForbidden(getter)) || !building_NutrientPasteDispenser.powerComp.PowerOn || (!allowDispenserEmpty && !building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers()) || !t.InteractionCell.Standable(t.Map) || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || getter.IsWildMan() || !getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some)))
                    {
                        return(false);
                    }
                }
                else if ((int)t.def.ingestible.preferability < (int)minPref || (int)t.def.ingestible.preferability > (int)maxPref || !eater.WillEat(t, getter) || !t.def.IsNutritionGivingIngestible || !t.IngestibleNow || (!allowCorpse && t is Corpse) || (!allowDrug && t.def.IsDrug) || (!allowForbidden && t.IsForbidden(getter)) || (!desperate && t.IsNotFresh()) || t.IsDessicated() || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || (!getter.AnimalAwareOf(t) && !forceScanWholeMap) || !getter.CanReserve(t))
                {
                    return(false);
                }
                return(true);
            };
            ThingRequest thingRequest = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == FoodTypeFlags.None || !allowPlant) ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource);
            Thing        bestThing;

            if (getter.RaceProps.Humanlike)
            {
                Pawn              eater2         = eater;
                IntVec3           position       = getter.Position;
                List <Thing>      searchSet      = getter.Map.listerThings.ThingsMatching(thingRequest);
                PathEndMode       peMode         = PathEndMode.ClosestTouch;
                TraverseParms     traverseParams = TraverseParms.For(getter);
                Predicate <Thing> validator      = foodValidator;
                bestThing = SpawnedFoodSearchInnerScan(eater2, position, searchSet, peMode, traverseParams, 9999f, validator);
                if (allowHarvest && getterCanManipulate)
                {
                    Thing thing = GenClosest.ClosestThingReachable(searchRegionsMax : (!forceScanWholeMap || bestThing != null) ? 30 : (-1), root : getter.Position, map : getter.Map, thingReq : ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), peMode : PathEndMode.Touch, traverseParams : TraverseParms.For(getter), maxDistance : 9999f, validator : delegate(Thing x)
                    {
                        Plant plant = (Plant)x;
                        if (!plant.HarvestableNow)
                        {
                            return(false);
                        }
                        ThingDef harvestedThingDef = plant.def.plant.harvestedThingDef;
                        if (!harvestedThingDef.IsNutritionGivingIngestible)
                        {
                            return(false);
                        }
                        if (!eater.WillEat(harvestedThingDef, getter))
                        {
                            return(false);
                        }
                        if (!getter.CanReserve(plant))
                        {
                            return(false);
                        }
                        if (!allowForbidden && plant.IsForbidden(getter))
                        {
                            return(false);
                        }
                        if (bestThing != null && (int)GetFinalIngestibleDef(bestThing).ingestible.preferability >= (int)harvestedThingDef.ingestible.preferability)
                        {
                            return(false);
                        }
                        return(true);
                    });
                    if (thing != null)
                    {
                        bestThing = thing;
                        foodDef   = GetFinalIngestibleDef(thing, harvest: true);
                    }
                }
                if (foodDef == null && bestThing != null)
                {
                    foodDef = GetFinalIngestibleDef(bestThing);
                }
            }
            else
            {
                int maxRegionsToScan = GetMaxRegionsToScan(getter, forceScanWholeMap);
                filtered.Clear();
                foreach (Thing item in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, useCenter: true))
                {
                    Pawn pawn = item as Pawn;
                    if (pawn != null && pawn != getter && pawn.RaceProps.Animal && pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Ingest && pawn.CurJob.GetTarget(TargetIndex.A).HasThing)
                    {
                        filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing);
                    }
                }
                bool flag = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, cellTarget: true) && getter.playerSettings != null && getter.playerSettings.EffectiveAreaRestrictionInPawnCurrentMap != null;
                Predicate <Thing> predicate = delegate(Thing t)
                {
                    if (!foodValidator(t))
                    {
                        return(false);
                    }
                    if (filtered.Contains(t))
                    {
                        return(false);
                    }
                    if (!(t is Building_NutrientPasteDispenser) && (int)t.def.ingestible.preferability <= 2)
                    {
                        return(false);
                    }
                    if (t.IsNotFresh())
                    {
                        return(false);
                    }
                    return(true);
                };
                IntVec3           position       = getter.Position;
                Map               map            = getter.Map;
                ThingRequest      thingReq       = thingRequest;
                PathEndMode       peMode         = PathEndMode.ClosestTouch;
                TraverseParms     traverseParams = TraverseParms.For(getter);
                Predicate <Thing> validator      = predicate;
                bool              ignoreEntirelyForbiddenRegions = flag;
                bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, maxRegionsToScan, forceGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                filtered.Clear();
                if (bestThing == null)
                {
                    desperate      = true;
                    position       = getter.Position;
                    map            = getter.Map;
                    thingReq       = thingRequest;
                    peMode         = PathEndMode.ClosestTouch;
                    traverseParams = TraverseParms.For(getter);
                    validator      = foodValidator;
                    ignoreEntirelyForbiddenRegions = flag;
                    bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, maxRegionsToScan, forceGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                }
                if (bestThing != null)
                {
                    foodDef = GetFinalIngestibleDef(bestThing);
                }
            }
            return(bestThing);
        }