Example #1
0
 public virtual bool Valid(LocalTargetInfo target, bool throwMessages = false)
 {
     return(true);
 }
Example #2
0
        private void FindTargets()
        {
            bool flag = this.UseAbilityProps.AbilityTargetCategory == AbilityTargetCategory.TargetAoE;

            if (flag)
            {
                bool flag2 = this.UseAbilityProps.TargetAoEProperties == null;
                if (flag2)
                {
                    Log.Error("Tried to Cast AoE-Ability without defining a target class");
                }
                List <Thing> list             = new List <Thing>();
                IntVec3      aoeStartPosition = this.caster.PositionHeld;
                bool         flag3            = !this.UseAbilityProps.TargetAoEProperties.startsFromCaster;
                if (flag3)
                {
                    aoeStartPosition = this.currentTarget.Cell;
                }
                bool flag4 = !this.UseAbilityProps.TargetAoEProperties.friendlyFire;
                if (flag4)
                {
                    list = (from x in this.caster.Map.listerThings.AllThings
                            where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType()) && x.Faction != Faction.OfPlayer
                            select x).ToList <Thing>();
                }
                else
                {
                    bool flag5 = this.UseAbilityProps.TargetAoEProperties.targetClass == typeof(Plant) || this.UseAbilityProps.TargetAoEProperties.targetClass == typeof(Building);
                    if (flag5)
                    {
                        list = (from x in this.caster.Map.listerThings.AllThings
                                where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType())
                                select x).ToList <Thing>();
                        foreach (Thing current in list)
                        {
                            LocalTargetInfo item = new LocalTargetInfo(current);
                            this.TargetsAoE.Add(item);
                        }
                        return;
                    }
                    list.Clear();
                    list = (from x in this.caster.Map.listerThings.AllThings
                            where x.Position.InHorDistOf(aoeStartPosition, (float)this.UseAbilityProps.TargetAoEProperties.range) && this.UseAbilityProps.TargetAoEProperties.targetClass.IsAssignableFrom(x.GetType()) && (x.HostileTo(Faction.OfPlayer) || this.UseAbilityProps.TargetAoEProperties.friendlyFire)
                            select x).ToList <Thing>();
                }
                int          maxTargets = this.UseAbilityProps.abilityDef.MainVerb.TargetAoEProperties.maxTargets;
                List <Thing> list2      = new List <Thing>(list.InRandomOrder(null));
                int          num        = 0;
                while (num < maxTargets && num < list2.Count <Thing>())
                {
                    TargetInfo targ  = new TargetInfo(list2[num]);
                    bool       flag6 = this.UseAbilityProps.targetParams.CanTarget(targ);
                    if (flag6)
                    {
                        this.TargetsAoE.Add(new LocalTargetInfo(list2[num]));
                    }
                    num++;
                }
            }
            else
            {
                this.TargetsAoE.Clear();
                this.TargetsAoE.Add(this.currentTarget);
            }
        }
Example #3
0
 internal void Notify_AttackedTarget(LocalTargetInfo target)
 {
     lastAttackTargetTick = Find.TickManager.TicksGame;
     lastAttackedTarget   = target;
 }
Example #4
0
 public void AddQueuedTarget(TargetIndex ind, LocalTargetInfo target)
 {
     this.GetTargetQueue(ind).Add(target);
 }
Example #5
0
        static public void OptimizePath(List <LocalTargetInfo> q, Thing Starter)
        {
            if (q.Count > 0)
            {
                int             x   = 0;
                int             idx = 0;
                int             n   = 0;
                LocalTargetInfo out_of_all_things_they_didnt_add_a_simple_swap = null;

                if (Starter != null)
                {
                    if (q[0].Cell == null)
                    {
                        n = int.MaxValue;
                    }
                    else
                    {
                        n = q[0].Cell.DistanceToSquared(Starter.Position);
                    }

                    for (int i = 1; i < q.Count(); i++)
                    {
                        if (q[i].Cell == null)
                        {
                            continue;
                        }
                        x = q[i].Cell.DistanceToSquared(Starter.Position);
                        if (Math.Abs(x) < Math.Abs(n))
                        {
                            n   = x;
                            idx = i;
                        }
                    }

                    if (idx != 0)
                    {
                        out_of_all_things_they_didnt_add_a_simple_swap = q[idx];
                        q[idx] = q[0];
                        q[0]   = out_of_all_things_they_didnt_add_a_simple_swap;
                    }
                }

                for (int i = 0; i < q.Count() - 1; i++)
                {
                    if (q[i + 1].Cell == null)
                    {
                        continue;
                    }

                    n   = q[i].Cell.DistanceToSquared(q[i + 1].Cell);
                    idx = i + 1;
                    for (int c = i + 2; c < q.Count(); c++)
                    {
                        if (q[c].Cell == null)
                        {
                            continue;
                        }

                        x = q[i].Cell.DistanceToSquared(q[c].Cell);
                        if (Math.Abs(x) < Math.Abs(n))
                        {
                            n   = x;
                            idx = c;
                        }
                    }

                    if (idx != i + 1)
                    {
                        out_of_all_things_they_didnt_add_a_simple_swap = q[idx];
                        q[idx]   = q[i + 1];
                        q[i + 1] = out_of_all_things_they_didnt_add_a_simple_swap;
                    }
                }
            }
        }
 public override void DrawEffectPreview(LocalTargetInfo target)
 {
     GenDraw.DrawFieldEdges(this.AffectedCells(target, this.parent.pawn.Map).ToList <IntVec3>(), this.Valid(target, false) ? Color.white : Color.red);
 }
        //public override bool TryMakePreToilReservations(bool errorOnFailed)
        //{
        //    if(TargetA.Thing != null)
        //    {
        //        return true;
        //    }
        //    if (pawn.Reserve(TargetA, this.job, 1, 1, null, errorOnFailed))
        //    {
        //        return true;
        //    }
        //    return false;
        //}

        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A));

            this.verb = this.pawn.CurJob.verbToUse as Verb_UseAbility;
            if (base.TargetA.HasThing && base.TargetA.Thing is Pawn && (!pawn.Position.InHorDistOf(base.TargetA.Cell, pawn.CurJob.verbToUse.verbProps.range) || !Verb.UseAbilityProps.canCastInMelee))
            {
                //if (!base.GetActor().IsFighting() ? true : !verb.UseAbilityProps.canCastInMelee && !this.job.endIfCantShootTargetFromCurPos)
                //{
                Toil toil = Toils_Combat.GotoCastPosition(TargetIndex.A, false);
                yield return(toil);
                //toil = null;
                //}
            }
            if (this.Context == AbilityContext.Player)
            {
                Find.Targeter.targetingSource = this.verb;
            }
            Pawn targetPawn = null;

            if (this.TargetThingA != null)
            {
                targetPawn = TargetThingA as Pawn;
            }

            if (targetPawn != null)
            {
                //yield return Toils_Combat.CastVerb(TargetIndex.A, false);
                Toil combatToil = new Toil();
                //combatToil.FailOnDestroyedOrNull(TargetIndex.A);
                //combatToil.FailOnDespawnedOrNull(TargetIndex.A);
                //combatToil.FailOnDowned(TargetIndex.A);
                //CompAbilityUserMagic comp = this.pawn.GetComp<CompAbilityUserMagic>();
                //JobDriver curDriver = this.pawn.jobs.curDriver;
                combatToil.initAction = delegate
                {
                    this.verb = combatToil.actor.jobs.curJob.verbToUse as Verb_UseAbility;
                    if (verb != null && verb.verbProps != null)
                    {
                        this.duration = (int)((this.verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false));

                        if (this.pawn.RaceProps.Humanlike)
                        {
                            //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                            //{
                            //    RemoveMimicAbility(verb);
                            //}

                            if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic))
                            {
                                PsionicEnergyCost(verb);
                            }

                            if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.DeathKnight))
                            {
                                HateCost(verb);
                            }

                            if (verb.Ability?.CooldownTicksLeft != -1)
                            {
                                this.EndJobWith(JobCondition.Incompletable);
                            }
                        }


                        LocalTargetInfo target = combatToil.actor.jobs.curJob.GetTarget(TargetIndex.A);
                        if (target != null)
                        {
                            verb.TryStartCastOn(target, false, true);
                        }
                        using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
                        {
                            while (enumerator.MoveNext())
                            {
                                Hediff rec = enumerator.Current;
                                if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III)
                                {
                                    this.pawn.health.RemoveHediff(rec);
                                }
                            }
                        }
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Errored);
                    }
                };
                combatToil.tickAction = delegate
                {
                    if (this.pawn.Downed)
                    {
                        EndJobWith(JobCondition.InterruptForced);
                    }
                    if (Find.TickManager.TicksGame % 12 == 0)
                    {
                        if (verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitThief || verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitInfuse)
                        {
                            float direction = Rand.Range(0, 360);
                            TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_Psi_Arcane"), pawn.DrawPos, pawn.Map, Rand.Range(.1f, .4f), 0.2f, .02f, .1f, 0, Rand.Range(8, 10), direction, direction);
                        }
                        else
                        {
                            TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f));
                        }
                    }

                    this.duration--;
                    if (!wildCheck && this.duration <= 6)
                    {
                        wildCheck = true;
                        if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f))
                        {
                            verb.Ability.PostAbilityAttempt();
                            TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA);
                            EndJobWith(JobCondition.InterruptForced);
                        }
                    }
                };
                combatToil.AddFinishAction(delegate
                {
                    if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed)
                    {
                        //ShootLine shootLine;
                        //bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine);
                        //bool inRange = (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range;
                        //if (inRange && validTarg)
                        //{
                        TMAbilityDef tmad = (TMAbilityDef)(verb.Ability.Def);
                        if (tmad != null && tmad.relationsAdjustment != 0 && targetPawn.Faction != null && targetPawn.Faction != this.pawn.Faction && !targetPawn.Faction.HostileTo(this.pawn.Faction))
                        {
                            targetPawn.Faction.TryAffectGoodwillWith(this.pawn.Faction, tmad.relationsAdjustment, true, false, null, null);
                        }
                        verb.Ability.PostAbilityAttempt();
                        this.pawn.ClearReservationsForJob(this.job);
                        //}
                    }
                });
                //if (combatToil.actor.CurJob != this.job)
                //{
                //    curDriver.ReadyForNextToil();
                //}
                combatToil.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                this.pawn.ClearReservationsForJob(this.job);
                yield return(combatToil);
                //Toil toil2 = new Toil()
                //{
                //    initAction = () =>
                //    {
                //        if (curJob.UseAbilityProps.isViolent)
                //        {
                //            JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn);
                //        }
                //    },
                //    defaultCompleteMode = ToilCompleteMode.Instant
                //};
                //yield return toil2;
                //Toil toil1 = new Toil()
                //{
                //    initAction = () => curJob.Ability.PostAbilityAttempt(),
                //    defaultCompleteMode = ToilCompleteMode.Instant
                //};
                //yield return toil1;
            }
            else
            {
                if (verb != null && verb.verbProps != null && (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range)
                {
                    if (TargetLocA.IsValid && TargetLocA.InBounds(pawn.Map) && !TargetLocA.Fogged(pawn.Map))  //&& TargetLocA.Walkable(pawn.Map)
                    {
                        ShootLine shootLine;
                        bool      validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine);
                        if (validTarg)
                        {
                            //yield return Toils_Combat.CastVerb(TargetIndex.A, false);
                            //Toil toil2 = new Toil()
                            //{
                            //    initAction = () =>
                            //    {
                            //        if (curJob.UseAbilityProps.isViolent)
                            //        {
                            //            JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn);
                            //        }

                            //    },
                            //    defaultCompleteMode = ToilCompleteMode.Instant
                            //};
                            //yield return toil2;
                            this.duration = (int)((verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false));
                            Toil toil = new Toil();
                            toil.initAction = delegate
                            {
                                this.verb = toil.actor.jobs.curJob.verbToUse as Verb_UseAbility;
                                if (this.pawn.RaceProps.Humanlike)
                                {
                                    //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                                    //{
                                    //    RemoveMimicAbility(verb);
                                    //}

                                    if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic))
                                    {
                                        PsionicEnergyCost(verb);
                                    }

                                    if (verb.Ability?.CooldownTicksLeft != -1)
                                    {
                                        this.EndJobWith(JobCondition.Incompletable);
                                    }
                                }
                                LocalTargetInfo target            = toil.actor.jobs.curJob.GetTarget(TargetIndex.A); //TargetLocA;  //
                                bool            canFreeIntercept2 = false;
                                if (target != null)
                                {
                                    verb.TryStartCastOn(target, false, canFreeIntercept2);
                                }
                                using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
                                {
                                    while (enumerator.MoveNext())
                                    {
                                        Hediff rec = enumerator.Current;
                                        if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III)
                                        {
                                            this.pawn.health.RemoveHediff(rec);
                                        }
                                    }
                                }
                            };
                            toil.tickAction = delegate
                            {
                                if (Find.TickManager.TicksGame % 12 == 0)
                                {
                                    TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f));
                                }
                                this.duration--;
                                if (!wildCheck && this.duration <= 6)
                                {
                                    wildCheck = true;
                                    if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f))
                                    {
                                        bool completeJob = TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA);
                                        if (!completeJob)
                                        {
                                            verb.Ability.PostAbilityAttempt();
                                            EndJobWith(JobCondition.InterruptForced);
                                        }
                                    }
                                }
                            };
                            toil.AddFinishAction(delegate
                            {
                                if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed)
                                {
                                    verb.Ability.PostAbilityAttempt();
                                }
                                this.pawn.ClearReservationsForJob(this.job);
                            });
                            toil.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                            yield return(toil);

                            //Toil toil1 = new Toil()
                            //{
                            //    initAction = () => curJob.Ability.PostAbilityAttempt(),
                            //    defaultCompleteMode = ToilCompleteMode.Instant
                            //};
                            //yield return toil1;
                        }
                        else
                        {
                            //No LoS
                            if (pawn.IsColonist)
                            {
                                Messages.Message("TM_OutOfLOS".Translate(
                                                     pawn.LabelShort
                                                     ), MessageTypeDefOf.RejectInput);
                            }
                            pawn.ClearAllReservations(false);
                        }
                    }
                    else
                    {
                        pawn.ClearAllReservations(false);
                    }
                }
                else
                {
                    if (pawn.IsColonist)
                    {
                        //out of range
                        Messages.Message("TM_OutOfRange".Translate(), MessageTypeDefOf.RejectInput);
                    }
                }
            }
        }
 protected override bool RemoveAllDesignationsAffects(LocalTargetInfo target)
 {
     return(target.Thing.def.plant.harvestTag == "Standard");
 }
Example #9
0
        /// <summary>
        /// Checks for cover along the flight path of the bullet, doesn't check for walls or trees, only intended for cover with partial fillPercent
        /// </summary>
        /// <param name="target">The target of which to find cover of</param>
        /// <param name="cover">Output parameter, filled with the highest cover object found</param>
        /// <returns>True if cover was found, false otherwise</returns>
        private bool GetHighestCoverAndSmokeForTarget(LocalTargetInfo target, out Thing cover, out float smokeDensity)
        {
            Map   map                = caster.Map;
            Thing targetThing        = target.Thing;
            Thing highestCover       = null;
            float highestCoverHeight = 0f;

            smokeDensity = 0;

            // Iterate through all cells on line of sight and check for cover and smoke
            var cells = GenSight.PointsOnLineOfSight(target.Cell, caster.Position).ToArray();

            if (cells.Length < 3)
            {
                cover = null;
                return(false);
            }
            for (int i = 0; i <= cells.Length / 2; i++)
            {
                var cell = cells[i];

                if (cell.AdjacentTo8Way(caster.Position))
                {
                    continue;
                }

                // Check for smoke
                var gas = cell.GetGas(map);
                if (gas != null)
                {
                    smokeDensity += gas.def.gas.accuracyPenalty;
                }

                // Check for cover in the second half of LoS
                if (i <= cells.Length / 2)
                {
                    Pawn  pawn     = cell.GetFirstPawn(map);
                    Thing newCover = pawn == null?cell.GetCover(map) : pawn;

                    float newCoverHeight = new CollisionVertical(newCover).Max;

                    // Cover check, if cell has cover compare collision height and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc)
                    if (newCover != null &&
                        (targetThing == null || !newCover.Equals(targetThing)) &&
                        (highestCover == null || highestCoverHeight < newCoverHeight) &&
                        newCover.def.Fillage == FillCategory.Partial &&
                        !newCover.IsPlant())
                    {
                        highestCover       = newCover;
                        highestCoverHeight = newCoverHeight;
                        if (Controller.settings.DebugDrawTargetCoverChecks)
                        {
                            map.debugDrawer.FlashCell(cell, highestCoverHeight, highestCoverHeight.ToString());
                        }
                    }
                }
            }
            cover = highestCover;

            //Report success if found cover
            return(cover != null);
        }
Example #10
0
 public static bool CanReachShip(this Pawn pawn, LocalTargetInfo dest, PathEndMode peMode, Danger maxDanger, bool canBash = false, TraverseMode mode = TraverseMode.ByPawn)
 {
     return(pawn.Spawned && MapExtensionUtility.GetExtensionToMap(pawn.Map).getShipReachability.CanReachShip(pawn.Position, dest, peMode, TraverseParms.For(pawn, maxDanger, mode, canBash)));
 }
 public static void Impact_DistortWeapon_Postfix(ref Projectile __instance, ref Thing ___launcher, ref LocalTargetInfo ___intendedTarget, Thing hitThing)
 {
     if (hitThing != null)
     {
         if (hitThing.def.thingClass == typeof(Pawn))
         {
             Pawn hitPawn = (Pawn)hitThing;
             if (hitPawn != null)
             {
                 if (__instance.def.projectile.damageDef == OGDamageDefOf.OG_E_Distortion_Damage)
                 {
                     bool explode = Rand.Chance(0.167f);
                     if (explode)
                     {
                         MoteMaker.ThrowText(hitPawn.Position.ToVector3(), hitPawn.Map, "AMA_Distorting_Shot".Translate(__instance.LabelCap, hitPawn.LabelShortCap), 3f);
                         WarpRift(__instance, ___launcher, hitPawn);
                     }
                 }
                 else
                 {
                     //    Log.Message(string.Format("damageDef not OG_E_Distortion_Damage: {0}", __instance.def.projectile.damageDef));
                 }
             }
             else
             {
                 //    Log.Message(string.Format("hitPawn is null: {0}", hitThing.def.thingClass));
             }
         }
         else
         {
             //    Log.Message(string.Format("Hitthing not pawn: {0}", hitThing.def.thingClass));
         }
     }
 }
        public override void CompTick()
        {
            if (this.age > 0)
            {
                if (!this.initialized)
                {
                    if (this.Props.alwaysManhunter || this.Pawn.Faction != Faction.OfPlayer)
                    {
                        this.Pawn.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.ManhunterPermanent, null, true, false, null);
                    }
                    if (this.Pawn.def.defName == "TM_DemonR" || this.Pawn.def.defName == "TM_LesserDemonR")
                    {
                        HealthUtility.AdjustSeverity(this.Pawn, HediffDef.Named("TM_DemonHD"), .5f);
                    }
                    this.initialized = true;
                }

                if (this.Pawn.Spawned)
                {
                    if (!this.Pawn.Downed)
                    {
                        if (this.NextTaunt < Find.TickManager.TicksGame)
                        {
                            DoTaunt(this.Pawn.Map);
                            this.nextTaunt = this.Props.tauntCooldownTicks + Find.TickManager.TicksGame;
                        }

                        if (this.rangedBurstShots > 0 && this.rangedNextBurst < Find.TickManager.TicksGame)
                        {
                            DoRangedAttack(this.rangedTarget);
                            this.rangedBurstShots--;
                            this.rangedNextBurst = Find.TickManager.TicksGame + this.Props.rangedTicksBetweenBursts;
                        }

                        if (Find.TickManager.TicksGame % 30 == 0)
                        {
                            if (this.buildingThreats.Count() > 0)
                            {
                                Building randomBuildingThreat = this.buildingThreats.RandomElement();
                                if ((randomBuildingThreat.Position - this.Pawn.Position).LengthHorizontal < 50 && this.NextRangedAttack < Find.TickManager.TicksGame && TargetIsValid(randomBuildingThreat))
                                {
                                    this.rangedTarget = randomBuildingThreat;
                                    StartRangedAttack();
                                }
                            }

                            Thing currentTargetThing = this.Pawn.CurJob.targetA.Thing;
                            if (currentTargetThing != null && this.Pawn.TargetCurrentlyAimingAt == null)
                            {
                                if ((currentTargetThing.Position - this.Pawn.Position).LengthHorizontal > (this.Props.maxRangeForCloseThreat * 2))
                                {
                                    if (Rand.Chance(.6f) && this.NextRangedAttack < Find.TickManager.TicksGame && TargetIsValid(currentTargetThing))
                                    {
                                        this.rangedTarget = currentTargetThing;
                                        StartRangedAttack();
                                    }
                                    else if (this.NextChargeAttack < Find.TickManager.TicksGame && TargetIsValid(currentTargetThing))
                                    {
                                        DoChargeAttack(currentTargetThing);
                                        goto exitTick;
                                    }
                                }
                            }
                            else if (this.Pawn.TargetCurrentlyAimingAt != null && this.closeThreats.Count() > 1)
                            {
                                if (Rand.Chance(.2f) && this.NextAoEAttack < Find.TickManager.TicksGame)
                                {
                                    DoAoEAttack(this.Pawn.Position, true, 2f, DamageDefOf.Stun, Rand.Range(4, 8));
                                }

                                if (Rand.Chance(.2f) && this.farThreats.Count() > (3 * this.closeThreats.Count()))
                                {
                                    this.Pawn.CurJob.targetA = this.farThreats.RandomElement();
                                }
                            }

                            if (this.closeThreats.Count() > 1 && ((this.closeThreats.Count() * 2) > this.farThreats.Count() || Rand.Chance(.3f)))
                            {
                                if (Rand.Chance(.8f) && this.NextKnockbackAttack < Find.TickManager.TicksGame)
                                {
                                    Pawn randomClosePawn = this.closeThreats.RandomElement();
                                    if ((randomClosePawn.Position - this.Pawn.Position).LengthHorizontal < 3 && TargetIsValid(randomClosePawn))
                                    {
                                        DoKnockbackAttack(this.Pawn.Position, randomClosePawn.Position, 1.4f, Rand.Range(3, 5f));
                                    }
                                }
                            }

                            if (this.farThreats.Count() > 2 * this.closeThreats.Count() && Rand.Chance(.3f))
                            {
                                if (this.NextChargeAttack < Find.TickManager.TicksGame)
                                {
                                    Thing tempTarget = this.farThreats.RandomElement();
                                    if (TargetIsValid(tempTarget))
                                    {
                                        this.Pawn.TryStartAttack(tempTarget);
                                        DoChargeAttack(tempTarget);
                                        goto exitTick;
                                    }
                                }
                            }

                            if (this.farThreats.Count() > 2)
                            {
                                if (Rand.Chance(.4f) && this.NextRangedAttack < Find.TickManager.TicksGame)
                                {
                                    Pawn randomRangedPawn = this.farThreats.RandomElement();
                                    if ((randomRangedPawn.Position - this.Pawn.Position).LengthHorizontal < this.Props.maxRangeForFarThreat * 1.2f)
                                    {
                                        this.rangedTarget = randomRangedPawn;
                                        StartRangedAttack();
                                    }
                                }
                            }

                            if (currentTargetThing == null || currentTargetThing == this.Pawn)
                            {
                                if (this.closeThreats.Count() > 0)
                                {
                                    Thing tempTarget = this.closeThreats.RandomElement();
                                    if (TargetIsValid(tempTarget))
                                    {
                                        this.Pawn.CurJob.targetA = tempTarget;
                                        this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA);
                                    }
                                }
                                else if (this.farThreats.Count() > 0)
                                {
                                    Thing tempTarget = this.farThreats.RandomElement();
                                    if (TargetIsValid(tempTarget))
                                    {
                                        this.Pawn.CurJob.targetA = tempTarget;
                                        this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA);
                                    }
                                }
                                else if (this.buildingThreats.Count() > 0)
                                {
                                    Thing tempTarget = this.buildingThreats.RandomElement();
                                    if (TargetIsValid(tempTarget))
                                    {
                                        this.Pawn.CurJob.targetA = tempTarget;
                                        this.Pawn.TryStartAttack(this.Pawn.CurJob.targetA);
                                    }
                                }
                            }
                        }

                        if (this.Pawn.Faction != Faction.OfPlayer && Find.TickManager.TicksGame % 300 == 0)
                        {
                            if (this.Props.alwaysManhunter)
                            {
                                this.Pawn.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.ManhunterPermanent, null, true, false, null);
                            }
                        }

                        if (Find.TickManager.TicksGame % 120 == 0)
                        {
                            DetermineThreats();
                        }
                    }

                    if (this.Pawn.Downed && this.Pawn.def.defName == "TM_DemonR" && Find.TickManager.TicksGame % 18 == 0)
                    {
                        CellRect cellRect = CellRect.CenteredOn(this.Pawn.Position, 3);
                        cellRect.ClipInsideMap(this.Pawn.Map);
                        GenExplosion.DoExplosion(cellRect.RandomCell, this.Pawn.Map, 2f, DamageDefOf.Burn, this.Pawn, Rand.Range(6, 12), -1, DamageDefOf.Bomb.soundExplosion, null, null, null, null, 0f, 1, false, null, 0f, 0, 0.2f, true);
                        DamageEntities(this.Pawn, 10f, TMDamageDefOf.DamageDefOf.TM_Shadow, this.Pawn);
                    }
                }
            }
            exitTick :;
            age++;
        }
Example #13
0
 public void Launch(Thing launcher, LocalTargetInfo targ, Thing flyingThing)
 {
     this.Launch(launcher, base.Position.ToVector3Shifted(), targ, flyingThing, null);
 }
Example #14
0
 public void Launch(Thing launcher, LocalTargetInfo targ, Thing flyingThing, DamageInfo?impactDamage)
 {
     this.Launch(launcher, base.Position.ToVector3Shifted(), targ, flyingThing, impactDamage);
 }
 private bool IsValidForestryTarget( LocalTargetInfo t )
 {
     return t.HasThing
            && IsValidForestryTarget( t.Thing );
 }
Example #16
0
        /// <summary>
        /// Checks if the shooter can hit the target from a certain position with regards to cover height
        /// </summary>
        /// <param name="root">The position from which to check</param>
        /// <param name="targ">The target to check for line of sight</param>
        /// <returns>True if shooter can hit target from root position, false otherwise</returns>
        public override bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ)
        {
            string unused;

            return(CanHitTargetFrom(root, targ, out unused));
        }
 public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
 {
     return(this.Valid(target, true));
 }
Example #18
0
 public bool CanHitTarget(LocalTargetInfo targ, out string report)
 {
     return(CanHitTargetFrom(caster.Position, targ, out report));
 }
Example #19
0
        public static IEnumerable <Toil> MakeFeedToils(JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition)
        {
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

            Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);

            yield return(gotoToil);

            Toil grappleToil = new Toil()
            {
                initAction = delegate
                {
                    MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking);

                    workLeft = JobDriver_Feed.BaseFeedTime;
                    Pawn victim = (Pawn)TargetA.Thing;
                    if (victim != null)
                    {
                        if (victim.InAggroMentalState || victim.Faction != actor.Faction)
                        {
                            if (!actor.CanGrapple(victim))
                            {
                                thisDriver.EndJobWith(JobCondition.Incompletable);
                            }
                        }
                        GenClamor.DoClamor(actor, 10f, ClamorType.Harm);
                        if (!AllowFeeding(actor, victim))
                        {
                            actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        }
                        if (actor?.VampComp()?.Bloodline?.bloodlineHediff?.CompProps <HediffCompProperties_VerbGiver>()?.verbs is List <VerbProperties> verbProps)
                        {
                            if (actor?.VerbTracker?.AllVerbs is List <Verb> verbs)
                            {
                                if (verbs.Find(x => verbProps.Contains(x.verbProps)) is Verb_MeleeAttack v)
                                {
                                    victim.TakeDamage(new DamageInfo(v.verbProps.meleeDamageDef, v.verbProps.meleeDamageBaseAmount, -1, actor));
                                }
                            }
                        }
                        victim.stances.stunner.StunFor((int)BaseFeedTime);
                    }
                }
            };

            yield return(grappleToil);

            Toil feedToil = new Toil()
            {
                tickAction = delegate
                {
                    Pawn victim = (Pawn)TargetA.Thing;
                    if (victim == null || !victim.Spawned || victim.Dead)
                    {
                        thisDriver.ReadyForNextToil();
                    }
                    workLeft--;

                    if (workLeft <= 0f)
                    {
                        if (actor?.VampComp() is CompVampire v && v.IsVampire && actor.Faction == Faction.OfPlayer)
                        {
                            MoteMaker.ThrowText(actor.DrawPos, actor.Map, "XP +" + 15, -1f);
                            v.XP += 15;
                        }
                        workLeft = BaseFeedTime;
                        MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking);
                        effect();
                        if ((victim.HostileTo(actor.Faction) || victim.IsPrisoner) && !actor.CanGrapple(victim))
                        {
                            thisDriver.EndJobWith(JobCondition.Incompletable);
                        }

                        if (!stopCondition(actor, victim))
                        {
                            thisDriver.ReadyForNextToil();
                        }
                        else
                        {
                            if (victim != null && !victim.Dead)
                            {
                                victim.stances.stunner.StunFor((int)BaseFeedTime);
                                PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor);
                            }
                        }
                    }
                },
Example #20
0
        public virtual bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ, out string report)
        {
            report = "";
            if (caster?.Map == null || !targ.Cell.InBounds(caster.Map) || !root.InBounds(caster.Map))
            {
                report = "Out of bounds";
                return(false);
            }
            // Check target self
            if (targ.Thing != null && targ.Thing == caster)
            {
                if (!verbProps.targetParams.canTargetSelf)
                {
                    report = "Can't target self";
                    return(false);
                }
                return(true);
            }
            // Check thick roofs
            if (Projectile.projectile.flyOverhead)
            {
                RoofDef roofDef = caster.Map.roofGrid.RoofAt(targ.Cell);
                if (roofDef != null && roofDef.isThickRoof)
                {
                    report = "Blocked by roof";
                    return(false);
                }
            }
            if (ShooterPawn != null)
            {
                // Check for capable of violence
                if (ShooterPawn.story != null && ShooterPawn.WorkTagIsDisabled(WorkTags.Violent))
                {
                    report = "IsIncapableOfViolenceLower".Translate(ShooterPawn.Name.ToStringShort);
                    return(false);
                }

                // Check for apparel
                bool isTurretOperator = caster.def.building?.IsTurret ?? false;
                if (ShooterPawn.apparel != null)
                {
                    List <Apparel> wornApparel = ShooterPawn.apparel.WornApparel;
                    foreach (Apparel current in wornApparel)
                    {
                        //pawns can use turrets while wearing shield belts, but the shield is disabled for the duration via Harmony patch (see Harmony-ShieldBelt.cs)
                        if (!current.AllowVerbCast(root, caster.Map, targ, this) && !(current is ShieldBelt && isTurretOperator))
                        {
                            report = "Shooting disallowed by " + current.LabelShort;
                            return(false);
                        }
                    }
                }
            }
            // Check for line of sight
            ShootLine shootLine;

            if (!TryFindCEShootLineFromTo(root, targ, out shootLine))
            {
                float lengthHorizontalSquared = (root - targ.Cell).LengthHorizontalSquared;
                if (lengthHorizontalSquared > verbProps.range * verbProps.range)
                {
                    report = "Out of range";
                }
                else if (lengthHorizontalSquared < verbProps.minRange * verbProps.minRange)
                {
                    report = "Within minimum range";
                }
                else
                {
                    report = "No line of sight";
                }
                return(false);
            }
            return(true);
        }
Example #21
0
 public Job(JobDef def, LocalTargetInfo targetA) : this(def, targetA, null)
 {
 }
Example #22
0
        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (verbProps.range <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > verbProps.range * verbProps.range || num < verbProps.minRange * verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }

            // First check current cell for early opt-out
            IntVec3 dest;
            var     shotSource = root.ToVector3Shifted();

            shotSource.y = ShotHeight;

            // Adjust for multi-tile turrets
            if (caster.def.building?.IsTurret ?? false)
            {
                shotSource = ShotSource;
            }

            if (CanHitFromCellIgnoringRange(shotSource, targ, out dest))
            {
                resultingLine = new ShootLine(root, dest);
                return(true);
            }
            // For pawns, calculate possible lean locations
            if (CasterIsPawn)
            {
                // Next check lean sources
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources);
                foreach (var leanLoc in tempLeanShootSources)
                {
                    var leanOffset = (leanLoc - root).ToVector3() * 0.5f;

                    if (CanHitFromCellIgnoringRange(shotSource + leanOffset, targ, out dest))
                    {
                        resultingLine = new ShootLine(leanLoc, dest);
                        return(true);
                    }
                }
            }

            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
Example #23
0
 public bool AnyTargetIs(LocalTargetInfo target)
 {
     return(target.IsValid && (this.targetA == target || this.targetB == target || this.targetC == target || (this.targetQueueA != null && this.targetQueueA.Contains(target)) || (this.targetQueueB != null && this.targetQueueB.Contains(target))));
 }
Example #24
0
        protected string ReportStringProcessed(string str)
        {
            LocalTargetInfo localTargetInfo = LocalTargetInfo.Invalid;

            if (this.job.targetA.IsValid)
            {
                localTargetInfo = this.job.targetA;
            }
            else
            {
                localTargetInfo = this.job.targetQueueA.FirstValid();
            }
            if (!localTargetInfo.IsValid)
            {
                str = str.Replace("TargetA", "UnknownLower".Translate());
            }
            else if (localTargetInfo.HasThing)
            {
                str = str.Replace("TargetA", localTargetInfo.Thing.LabelShort);
            }
            else
            {
                str = str.Replace("TargetA", "AreaLower".Translate());
            }
            LocalTargetInfo localTargetInfo2 = LocalTargetInfo.Invalid;

            if (this.job.targetB.IsValid)
            {
                localTargetInfo2 = this.job.targetB;
            }
            else
            {
                localTargetInfo2 = this.job.targetQueueB.FirstValid();
            }
            if (!localTargetInfo2.IsValid)
            {
                str = str.Replace("TargetB", "UnknownLower".Translate());
            }
            else if (localTargetInfo2.HasThing)
            {
                str = str.Replace("TargetB", localTargetInfo2.Thing.LabelShort);
            }
            else
            {
                str = str.Replace("TargetB", "AreaLower".Translate());
            }
            LocalTargetInfo targetC = this.job.targetC;

            if (!targetC.IsValid)
            {
                str = str.Replace("TargetC", "UnknownLower".Translate());
            }
            else if (targetC.HasThing)
            {
                str = str.Replace("TargetC", targetC.Thing.LabelShort);
            }
            else
            {
                str = str.Replace("TargetC", "AreaLower".Translate());
            }
            return(str);
        }
Example #25
0
        public static IEnumerable <Filth> SelectAllFilth(Pawn pawn, LocalTargetInfo target, int Limit = int.MaxValue)
        {
            Room room = null;

            if (target.Thing == null)
            {
                if (target.Cell == null)
                {
                    Log.Error("Invalid target: cell or thing it must be");
                }
                else
                {
                    room = GridsUtility.GetRoom(target.Cell, pawn.Map);
                }
            }
            else
            {
                room = target.Thing.GetRoom();
            }

            if (room == null)
            {
                return(new List <Filth>());
            }

            PathGrid pathGrid = pawn.Map.pathGrid;

            if (pathGrid == null)
            {
                return(new List <Filth>());
            }

            if (cleanFilth == null)
            {
                cleanFilth = DefDatabase <WorkGiverDef> .GetNamed("CleanFilth");
            }

            if (cleanFilth.Worker == null)
            {
                return(new List <Filth>());
            }

            IEnumerable <Filth> enumerable = null;

            if (room.IsHuge || room.CellCount > largeRoomSize)
            {
                enumerable = new List <Filth>();
                for (int i = 0; i < 200; i++)
                {
                    IntVec3 intVec = target.Cell + GenRadial.RadialPattern[i];
                    if (intVec.InBounds(pawn.Map) && intVec.InAllowedArea(pawn) && intVec.GetRoom(pawn.Map) == room)
                    {
                        ((List <Filth>)enumerable).AddRange(intVec.GetThingList(pawn.Map).OfType <Filth>().Where(f => !f.Destroyed &&
                                                                                                                 ((WorkGiver_Scanner)cleanFilth.Worker).HasJobOnThing(pawn, f)).Take(Limit == 0 ? int.MaxValue : Limit));
                    }
                    if (Limit > 0 && enumerable.Count() >= Limit)
                    {
                        break;
                    }
                }
            }
            else
            {
                enumerable = room.ContainedAndAdjacentThings.OfType <Filth>().Where(delegate(Filth f)
                {
                    if (f == null || f.Destroyed || !f.Position.InAllowedArea(pawn) || !((WorkGiver_Scanner)cleanFilth.Worker).HasJobOnThing(pawn, f))
                    {
                        return(false);
                    }

                    Room room2 = f.GetRoom();
                    if (room2 == null || room2 != room && !room2.IsDoorway)
                    {
                        return(false);
                    }

                    return(true);
                }).Take(Limit == 0 ? int.MaxValue : Limit);
            }
            return(enumerable);
        }
 public virtual bool ValidateTarget(LocalTargetInfo target)
 {
     return(CanHitTarget(target));
 }
Example #27
0
 protected override void ApplyEffects(IEnumerable <CompAbilityEffect> effects, LocalTargetInfo target, LocalTargetInfo dest)
 {
     if (CanApplyPsycastTo(target))
     {
         foreach (CompAbilityEffect effect in effects)
         {
             effect.Apply(target, dest);
         }
     }
     else
     {
         MoteMaker.ThrowText(target.CenterVector3, pawn.Map, "TextMote_Immune".Translate());
     }
 }
 public void OrderForceTarget(LocalTargetInfo target)
 {
     parent.QueueCastingJob(selectedTarget, target);
     selectedTarget = LocalTargetInfo.Invalid;
 }
Example #29
0
 public virtual void DrawEffectPreview(LocalTargetInfo target)
 {
 }
 public void SetTarget(LocalTargetInfo target)
 {
     selectedTarget = target;
 }
Example #31
0
        public override Job JobOnCell(Pawn pawn, IntVec3 c, bool forced = false)
        {
            Map map = pawn.Map;

            if (c.IsForbidden(pawn))
            {
                return(null);
            }
            if (!PlantUtility.GrowthSeasonNow(c, map, forSowing: true))
            {
                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 < 0f)
                {
                    return(null);
                }
            }
            if (WorkGiver_Grower.wantedPlantDef.plant.cavePlant)
            {
                if (!c.Roofed(map))
                {
                    JobFailReason.Is(CantSowCavePlantBecauseUnroofedTrans);
                    return(null);
                }
                if (map.glowGrid.GameGlowAt(c, ignoreCavePlants: true) > 0f)
                {
                    JobFailReason.Is(CantSowCavePlantBecauseOfLightTrans);
                    return(null);
                }
            }
            if (WorkGiver_Grower.wantedPlantDef.plant.interferesWithRoof && c.Roofed(pawn.Map))
            {
                return(null);
            }
            Plant plant = c.GetPlant(map);

            if (plant != null && plant.def.plant.blockAdjacentSow)
            {
                LocalTargetInfo target = plant;
                bool            ignoreOtherReservations = forced;
                if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations) || plant.IsForbidden(pawn))
                {
                    return(null);
                }
                return(new Job(JobDefOf.CutPlant, plant));
            }
            Thing thing2 = PlantUtility.AdjacentSowBlocker(WorkGiver_Grower.wantedPlantDef, c, map);

            if (thing2 != null)
            {
                Plant plant2 = thing2 as Plant;
                if (plant2 != null)
                {
                    LocalTargetInfo target = plant2;
                    bool            ignoreOtherReservations = forced;
                    if (pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations) && !plant2.IsForbidden(pawn))
                    {
                        IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map);
                        if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def)
                        {
                            return(new Job(JobDefOf.CutPlant, plant2));
                        }
                    }
                }
                return(null);
            }
            if (WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill > 0 && pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < WorkGiver_Grower.wantedPlantDef.plant.sowMinSkill)
            {
                return(null);
            }
            for (int j = 0; j < thingList.Count; j++)
            {
                Thing thing3 = thingList[j];
                if (thing3.def.BlockPlanting)
                {
                    LocalTargetInfo target = thing3;
                    bool            ignoreOtherReservations = forced;
                    if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations))
                    {
                        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) && PlantUtility.GrowthSeasonNow(c, map, forSowing: true))
            {
                LocalTargetInfo target = c;
                bool            ignoreOtherReservations = forced;
                if (pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations))
                {
                    Job job = new Job(JobDefOf.Sow, c);
                    job.plantDefToSow = WorkGiver_Grower.wantedPlantDef;
                    return(job);
                }
            }
            return(null);
        }
 private bool IsValidHuntingTarget( LocalTargetInfo t )
 {
     return t.HasThing
            && t.Thing is Pawn
            && IsValidHuntingTarget( (Pawn) t.Thing );
 }