public static void DebugDrawAttackTargetScores_Update()
        {
            IAttackTargetSearcher attackTargetSearcher = Find.Selector.SingleSelectedThing as IAttackTargetSearcher;

            if (attackTargetSearcher == null)
            {
                return;
            }
            if (attackTargetSearcher.Thing.Map != Find.CurrentMap)
            {
                return;
            }
            Verb currentEffectiveVerb = attackTargetSearcher.CurrentEffectiveVerb;

            if (currentEffectiveVerb == null)
            {
                return;
            }
            AttackTargetFinder.tmpTargets.Clear();
            List <Thing> list = attackTargetSearcher.Thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);

            for (int i = 0; i < list.Count; i++)
            {
                AttackTargetFinder.tmpTargets.Add((IAttackTarget)list[i]);
            }
            List <Pair <IAttackTarget, float> > availableShootingTargetsByScore = AttackTargetFinder.GetAvailableShootingTargetsByScore(AttackTargetFinder.tmpTargets, attackTargetSearcher, currentEffectiveVerb);

            for (int j = 0; j < availableShootingTargetsByScore.Count; j++)
            {
                GenDraw.DrawLineBetween(attackTargetSearcher.Thing.DrawPos, availableShootingTargetsByScore[j].First.Thing.DrawPos);
            }
        }
        private static List <Pair <IAttackTarget, float> > GetAvailableShootingTargetsByScore(List <IAttackTarget> rawTargets, IAttackTargetSearcher searcher, Verb verb)
        {
            AttackTargetFinder.availableShootingTargets.Clear();
            if (rawTargets.Count == 0)
            {
                return(AttackTargetFinder.availableShootingTargets);
            }
            AttackTargetFinder.tmpTargetScores.Clear();
            AttackTargetFinder.tmpCanShootAtTarget.Clear();
            float         num          = 0f;
            IAttackTarget attackTarget = null;

            for (int i = 0; i < rawTargets.Count; i++)
            {
                AttackTargetFinder.tmpTargetScores.Add(float.MinValue);
                AttackTargetFinder.tmpCanShootAtTarget.Add(false);
                if (rawTargets[i] != searcher)
                {
                    bool flag = AttackTargetFinder.CanShootAtFromCurrentPosition(rawTargets[i], searcher, verb);
                    AttackTargetFinder.tmpCanShootAtTarget[i] = flag;
                    if (flag)
                    {
                        float shootingTargetScore = AttackTargetFinder.GetShootingTargetScore(rawTargets[i], searcher, verb);
                        AttackTargetFinder.tmpTargetScores[i] = shootingTargetScore;
                        if (attackTarget == null || shootingTargetScore > num)
                        {
                            attackTarget = rawTargets[i];
                            num          = shootingTargetScore;
                        }
                    }
                }
            }
            if (num < 1f)
            {
                if (attackTarget != null)
                {
                    AttackTargetFinder.availableShootingTargets.Add(new Pair <IAttackTarget, float>(attackTarget, 1f));
                }
            }
            else
            {
                float num2 = num - 30f;
                for (int j = 0; j < rawTargets.Count; j++)
                {
                    if (rawTargets[j] != searcher)
                    {
                        if (AttackTargetFinder.tmpCanShootAtTarget[j])
                        {
                            float num3 = AttackTargetFinder.tmpTargetScores[j];
                            if (num3 >= num2)
                            {
                                float second = Mathf.InverseLerp(num - 30f, num, num3);
                                AttackTargetFinder.availableShootingTargets.Add(new Pair <IAttackTarget, float>(rawTargets[j], second));
                            }
                        }
                    }
                }
            }
            return(AttackTargetFinder.availableShootingTargets);
        }
        private static IAttackTarget GetRandomShootingTargetByScore(List <IAttackTarget> targets, IAttackTargetSearcher searcher, Verb verb)
        {
            Pair <IAttackTarget, float> pair;

            if (AttackTargetFinder.GetAvailableShootingTargetsByScore(targets, searcher, verb).TryRandomElementByWeight((Pair <IAttackTarget, float> x) => x.Second, out pair))
            {
                return(pair.First);
            }
            return(null);
        }
예제 #4
0
        private static IAttackTarget GetRandomShootingTargetByScore(List <IAttackTarget> targets, IAttackTargetSearcher searcher, Verb verb)
        {
            Pair <IAttackTarget, float> pair = default(Pair <IAttackTarget, float>);

            if (((IEnumerable <Pair <IAttackTarget, float> >)AttackTargetFinder.GetAvailableShootingTargetsByScore(targets, searcher, verb)).TryRandomElementByWeight <Pair <IAttackTarget, float> >((Func <Pair <IAttackTarget, float>, float>)((Pair <IAttackTarget, float> x) => x.Second), out pair))
            {
                return(pair.First);
            }
            return(null);
        }
        public static IAttackTarget BestShootTargetFromCurrentPosition(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDistance = 0f, float maxDistance = 9999f)
        {
            Verb currentEffectiveVerb = searcher.CurrentEffectiveVerb;

            if (currentEffectiveVerb == null)
            {
                Log.Error("BestShootTargetFromCurrentPosition with " + searcher.ToStringSafe <IAttackTargetSearcher>() + " who has no attack verb.", false);
                return(null);
            }
            return(AttackTargetFinder.BestAttackTarget(searcher, flags, validator, Mathf.Max(minDistance, currentEffectiveVerb.verbProps.minRange), Mathf.Min(maxDistance, currentEffectiveVerb.verbProps.range), default(IntVec3), float.MaxValue, false, false));
        }
        public static void DebugDrawAttackTargetScores_OnGUI()
        {
            IAttackTargetSearcher attackTargetSearcher = Find.Selector.SingleSelectedThing as IAttackTargetSearcher;

            if (attackTargetSearcher == null)
            {
                return;
            }
            if (attackTargetSearcher.Thing.Map != Find.CurrentMap)
            {
                return;
            }
            Verb currentEffectiveVerb = attackTargetSearcher.CurrentEffectiveVerb;

            if (currentEffectiveVerb == null)
            {
                return;
            }
            List <Thing> list = attackTargetSearcher.Thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.AttackTarget);

            Text.Anchor = TextAnchor.MiddleCenter;
            Text.Font   = GameFont.Tiny;
            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                if (thing != attackTargetSearcher)
                {
                    string text;
                    Color  red;
                    if (!AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)thing, attackTargetSearcher, currentEffectiveVerb))
                    {
                        text = "out of range";
                        red  = Color.red;
                    }
                    else
                    {
                        text = AttackTargetFinder.GetShootingTargetScore((IAttackTarget)thing, attackTargetSearcher, currentEffectiveVerb).ToString("F0");
                        red  = new Color(0.25f, 1f, 0.25f);
                    }
                    Vector2 screenPos = thing.DrawPos.MapToUIPosition();
                    GenMapUI.DrawThingLabel(screenPos, text, red);
                }
            }
            Text.Anchor = TextAnchor.UpperLeft;
            Text.Font   = GameFont.Small;
        }
예제 #7
0
        private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            float num = 60f;

            num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);
            if (target.TargetCurrentlyAimingAt == searcher.Thing)
            {
                num += 10f;
            }
            if (searcher.LastAttackedTarget == target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num += 40f;
            }
            num -= CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f;
            Pawn pawn = target as Pawn;

            if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num -= 50f;
            }
            return(num + AttackTargetFinder.FriendlyFireShootingTargetScoreOffset(target, searcher, verb));
        }
예제 #8
0
        // Token: 0x0600004A RID: 74 RVA: 0x00003EE8 File Offset: 0x000020E8
        private void CheckForAutoAttack()
        {
            bool downed = this.pawn.Downed;

            if (!downed)
            {
                bool fullBodyBusy = this.pawn.stances.FullBodyBusy;
                if (!fullBodyBusy)
                {
                    bool flag = this.pawn.jobs.jobQueue != null;
                    if (!flag)
                    {
                        bool flag2 = this.pawn.Faction != null && this.pawn.jobs.curJob.def == WPJobDefOf.ArtyWaitCombat;
                        if (flag2)
                        {
                            Verb currentEffectiveVerb = this.pawn.CurrentEffectiveVerb;
                            bool flag3 = currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack;
                            if (flag3)
                            {
                                TargetScanFlags targetScanFlags = TargetScanFlags.None;
                                bool            flag4           = currentEffectiveVerb.IsIncendiary();
                                if (flag4)
                                {
                                    targetScanFlags |= TargetScanFlags.NeedNonBurning;
                                }
                                Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this.pawn, targetScanFlags, null, 0f, 9999f);
                                bool  flag5 = thing != null;
                                if (flag5)
                                {
                                    this.pawn.TryStartAttack(thing);
                                    this.collideWithPawns = true;
                                }
                            }
                        }
                    }
                }
            }
        }
        private void CheckForAutoAttack()
        {
            if (this.pawn.Downed)
            {
                return;
            }
            if (this.pawn.stances.FullBodyBusy)
            {
                return;
            }
            this.collideWithPawns = false;
            bool flag  = this.pawn.story == null || !this.pawn.story.WorkTagIsDisabled(WorkTags.Violent);
            bool flag2 = this.pawn.RaceProps.ToolUser && this.pawn.Faction == Faction.OfPlayer && !this.pawn.story.WorkTagIsDisabled(WorkTags.Firefighting);

            if (flag || flag2)
            {
                Fire fire = null;
                for (int i = 0; i < 9; i++)
                {
                    IntVec3 c = this.pawn.Position + GenAdj.AdjacentCellsAndInside[i];
                    if (c.InBounds(this.pawn.Map))
                    {
                        List <Thing> thingList = c.GetThingList(base.Map);
                        for (int j = 0; j < thingList.Count; j++)
                        {
                            if (flag)
                            {
                                Pawn pawn = thingList[j] as Pawn;
                                if (pawn != null && !pawn.Downed && this.pawn.HostileTo(pawn))
                                {
                                    this.pawn.meleeVerbs.TryMeleeAttack(pawn, null, false);
                                    this.collideWithPawns = true;
                                    return;
                                }
                            }
                            if (flag2)
                            {
                                Fire fire2 = thingList[j] as Fire;
                                if (fire2 != null && (fire == null || fire2.fireSize < fire.fireSize || i == 8) && (fire2.parent == null || fire2.parent != this.pawn))
                                {
                                    fire = fire2;
                                }
                            }
                        }
                    }
                }
                if (fire != null && (!this.pawn.InMentalState || this.pawn.MentalState.def.allowBeatfire))
                {
                    this.pawn.natives.TryBeatFire(fire);
                    return;
                }
                if (flag && this.pawn.Faction != null && this.job.def == JobDefOf.Wait_Combat && (this.pawn.drafter == null || this.pawn.drafter.FireAtWill))
                {
                    Verb currentEffectiveVerb = this.pawn.CurrentEffectiveVerb;
                    if (currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack)
                    {
                        TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat;
                        if (currentEffectiveVerb.IsIncendiary())
                        {
                            targetScanFlags |= TargetScanFlags.NeedNonBurning;
                        }
                        Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this.pawn, targetScanFlags, null, 0f, 9999f);
                        if (thing != null)
                        {
                            this.pawn.TryStartAttack(thing);
                            this.collideWithPawns = true;
                            return;
                        }
                    }
                }
            }
        }
 internal bool <> m__3(Thing t)
 {
     return(this.innerValidator((IAttackTarget)t) && (AttackTargetFinder.CanReach(this.searcherThing, t, this.canBash) || AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, this.searcher, this.verb)));
 }
        public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true)
        {
            Thing searcherThing = searcher.Thing;
            Pawn  searcherPawn  = searcher as Pawn;
            Verb  verb          = searcher.CurrentEffectiveVerb;

            if (verb == null)
            {
                Log.Error("BestAttackTarget with " + searcher.ToStringSafe <IAttackTargetSearcher>() + " who has no attack verb.", false);
                return(null);
            }
            bool  onlyTargetMachines = verb.IsEMP();
            float minDistSquared     = minDist * minDist;
            float num = maxTravelRadiusFromLocus + verb.verbProps.range;
            float maxLocusDistSquared         = num * num;
            Func <IntVec3, bool> losValidator = null;

            if ((byte)(flags & TargetScanFlags.LOSBlockableByGas) != 0)
            {
                losValidator = delegate(IntVec3 vec3)
                {
                    Gas gas = vec3.GetGas(searcherThing.Map);
                    return(gas == null || !gas.def.gas.blockTurretTracking);
                };
            }
            Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t)
            {
                Thing thing = t.Thing;
                if (t == searcher)
                {
                    return(false);
                }
                if (minDistSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistSquared)
                {
                    return(false);
                }
                if (!canTakeTargetsCloserThanEffectiveMinRange)
                {
                    float num2 = verb.verbProps.EffectiveMinRange(thing, searcherThing);
                    if (num2 > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < num2 * num2)
                    {
                        return(false);
                    }
                }
                if (maxTravelRadiusFromLocus < 9999f && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared)
                {
                    return(false);
                }
                if (!searcherThing.HostileTo(thing))
                {
                    return(false);
                }
                if (validator != null && !validator(thing))
                {
                    return(false);
                }
                if (searcherPawn != null)
                {
                    Lord lord = searcherPawn.GetLord();
                    if (lord != null && !lord.LordJob.ValidateAttackTarget(searcherPawn, thing))
                    {
                        return(false);
                    }
                }
                if ((byte)(flags & TargetScanFlags.NeedLOSToAll) != 0 && !searcherThing.CanSee(thing, losValidator))
                {
                    if (t is Pawn)
                    {
                        if ((byte)(flags & TargetScanFlags.NeedLOSToPawns) != 0)
                        {
                            return(false);
                        }
                    }
                    else if ((byte)(flags & TargetScanFlags.NeedLOSToNonPawns) != 0)
                    {
                        return(false);
                    }
                }
                if ((byte)(flags & TargetScanFlags.NeedThreat) != 0 && t.ThreatDisabled(searcher))
                {
                    return(false);
                }
                Pawn pawn = t as Pawn;
                if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh)
                {
                    return(false);
                }
                if ((byte)(flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning())
                {
                    return(false);
                }
                if (searcherThing.def.race != null && searcherThing.def.race.intelligence >= Intelligence.Humanlike)
                {
                    CompExplosive compExplosive = thing.TryGetComp <CompExplosive>();
                    if (compExplosive != null && compExplosive.wickStarted)
                    {
                        return(false);
                    }
                }
                if (thing.def.size.x == 1 && thing.def.size.z == 1)
                {
                    if (thing.Position.Fogged(thing.Map))
                    {
                        return(false);
                    }
                }
                else
                {
                    bool flag2 = false;
                    CellRect.CellRectIterator iterator = thing.OccupiedRect().GetIterator();
                    while (!iterator.Done())
                    {
                        if (!iterator.Current.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                        iterator.MoveNext();
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (AttackTargetFinder.HasRangedAttack(searcher))
            {
                AttackTargetFinder.tmpTargets.Clear();
                AttackTargetFinder.tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                if ((byte)(flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(t) && AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash));
                }
                bool flag = false;
                for (int i = 0; i < AttackTargetFinder.tmpTargets.Count; i++)
                {
                    IAttackTarget attackTarget = AttackTargetFinder.tmpTargets[i];
                    if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb))
                    {
                        flag = true;
                        break;
                    }
                }
                IAttackTarget result;
                if (flag)
                {
                    AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    result = AttackTargetFinder.GetRandomShootingTargetByScore(AttackTargetFinder.tmpTargets, searcher, verb);
                }
                else
                {
                    Predicate <Thing> validator2;
                    if ((byte)(flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != 0 && (byte)(flags & TargetScanFlags.NeedReachable) == 0)
                    {
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (AttackTargetFinder.CanReach(searcherThing, t, canBash) || AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)));
                    }
                    else
                    {
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t));
                    }
                    result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, AttackTargetFinder.tmpTargets, maxDist, validator2, null);
                }
                AttackTargetFinder.tmpTargets.Clear();
                return(result);
            }
            if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState)
            {
                Predicate <IAttackTarget> oldValidator = innerValidator;
                innerValidator = ((IAttackTarget t) => oldValidator(t) && t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius));
            }
            IntVec3           position         = searcherThing.Position;
            Map               map              = searcherThing.Map;
            ThingRequest      thingReq         = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget);
            PathEndMode       peMode           = PathEndMode.Touch;
            Pawn              searcherPawn2    = searcherPawn;
            Danger            maxDanger        = Danger.Deadly;
            bool              canBash2         = canBash;
            TraverseParms     traverseParams   = TraverseParms.For(searcherPawn2, maxDanger, TraverseMode.ByPawn, canBash2);
            float             maxDist2         = maxDist;
            Predicate <Thing> validator3       = (Thing x) => innerValidator((IAttackTarget)x);
            int               searchRegionsMax = (maxDist <= 800f) ? 40 : -1;
            IAttackTarget     attackTarget2    = (IAttackTarget)GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, maxDist2, validator3, null, 0, searchRegionsMax, false, RegionType.Set_Passable, false);

            if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn))
            {
                IAttackTarget attackTarget3 = AttackTargetFinder.FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash);
                if (attackTarget3 != null)
                {
                    float lengthHorizontal  = (searcherPawn.Position - attackTarget2.Thing.Position).LengthHorizontal;
                    float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal;
                    if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f)
                    {
                        attackTarget2 = attackTarget3;
                    }
                }
            }
            return(attackTarget2);
        }
예제 #12
0
        private void CheckForAutoAttack()
        {
            if (pawn.Downed)
            {
                return;
            }

            //Don't auto-attack while warming up etc
            if (pawn.stances.FullBodyBusy)
            {
                return;
            }

            collideWithPawns = false;

            //Note: While bursting, there seems to be a gap where the pawn becomes mobile?
            bool canDoViolence = pawn.story == null || !pawn.story.WorkTagIsDisabled(WorkTags.Violent);

            bool shouldFightFires = pawn.RaceProps.ToolUser &&
                                    pawn.Faction == Faction.OfPlayer &&
                                    !pawn.story.WorkTagIsDisabled(WorkTags.Firefighting);

            if (canDoViolence || shouldFightFires)
            {
                //Melee attack adjacent enemy pawns
                //Barring that, put out fires
                Fire targetFire = null;
                for (int i = 0; i < 9; i++)
                {
                    IntVec3 neigh = pawn.Position + GenAdj.AdjacentCellsAndInside[i];

                    if (!neigh.InBounds(pawn.Map))
                    {
                        continue;
                    }

                    var things = neigh.GetThingList(Map);
                    for (int j = 0; j < things.Count; j++)
                    {
                        if (canDoViolence)
                        {
                            //We just hit the first pawn we see (north first)
                            Pawn otherPawn = things[j] as Pawn;
                            if (otherPawn != null &&
                                !otherPawn.Downed &&
                                pawn.HostileTo(otherPawn))
                            {
                                pawn.meleeVerbs.TryMeleeAttack(otherPawn);
                                collideWithPawns = true;
                                return;
                            }
                        }

                        //Prioritize the fire we're standing on.
                        //If there isn't one, prioritize the smallest fire
                        //This algorithm assumes that the inside cell is last
                        if (shouldFightFires)
                        {
                            Fire fire = things[j] as Fire;
                            if (fire != null &&
                                (targetFire == null || fire.fireSize < targetFire.fireSize || i == 8) &&
                                (fire.parent == null || fire.parent != pawn))
                            {
                                targetFire = fire;
                            }
                        }
                    }
                }

                //We didn't do a melee attack, so see if we found a fire to beat
                if (targetFire != null && (!pawn.InMentalState || pawn.MentalState.def.allowBeatfire))
                {
                    pawn.natives.TryBeatFire(targetFire);
                    return;
                }

                //Shoot at the closest enemy in range
                if (canDoViolence &&
                    pawn.Faction != null &&
                    job.def == JobDefOf.Wait_Combat &&
                    (pawn.drafter == null || pawn.drafter.FireAtWill))
                {
                    var attackVerb = pawn.CurrentEffectiveVerb;

                    if (attackVerb != null && !attackVerb.verbProps.IsMeleeAttack)
                    {
                        //We increase the range because we can hit targets slightly outside range by shooting at their ShootableSquares
                        //We could just put the range at int.MaxValue but this is slightly more optimized so whatever
                        var flags = TargetScanFlags.NeedLOSToAll | TargetScanFlags.NeedThreat;
                        if (attackVerb.IsIncendiary())
                        {
                            flags |= TargetScanFlags.NeedNonBurning;
                        }

                        var curTarg = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(pawn, flags);

                        if (curTarg != null)
                        {
                            pawn.TryStartAttack(curTarg);
                            collideWithPawns = true;
                            return;
                        }
                    }
                }
            }
        }
예제 #13
0
 public static IAttackTarget BestShootTargetFromCurrentPosition(IAttackTargetSearcher searcher, Predicate <Thing> validator, float maxDistance, float minDistance, TargetScanFlags flags)
 {
     return(AttackTargetFinder.BestAttackTarget(searcher, flags, validator, minDistance, maxDistance, default(IntVec3), 3.40282347E+38f, false));
 }
 private void CheckForAutoAttack()
 {
     if (!base.pawn.Downed && !base.pawn.stances.FullBodyBusy)
     {
         bool flag  = base.pawn.story == null || !base.pawn.story.WorkTagIsDisabled(WorkTags.Violent);
         bool flag2 = base.pawn.RaceProps.ToolUser && base.pawn.Faction == Faction.OfPlayer && !base.pawn.story.WorkTagIsDisabled(WorkTags.Firefighting);
         if (!flag && !flag2)
         {
             return;
         }
         Fire fire = null;
         for (int i = 0; i < 9; i++)
         {
             IntVec3 c = base.pawn.Position + GenAdj.AdjacentCellsAndInside[i];
             if (c.InBounds(base.pawn.Map))
             {
                 List <Thing> thingList = c.GetThingList(base.Map);
                 for (int j = 0; j < thingList.Count; j++)
                 {
                     if (flag)
                     {
                         Pawn pawn = thingList[j] as Pawn;
                         if (pawn != null && !pawn.Downed && base.pawn.HostileTo(pawn))
                         {
                             base.pawn.meleeVerbs.TryMeleeAttack(pawn, null, false);
                             return;
                         }
                     }
                     if (flag2)
                     {
                         Fire fire2 = thingList[j] as Fire;
                         if (fire2 != null && (fire == null || fire2.fireSize < fire.fireSize || i == 8) && (fire2.parent == null || fire2.parent != base.pawn))
                         {
                             fire = fire2;
                         }
                     }
                 }
             }
         }
         if (fire != null && (!base.pawn.InMentalState || base.pawn.MentalState.def.allowBeatfire))
         {
             base.pawn.natives.TryBeatFire(fire);
         }
         else if (flag && base.pawn.Faction != null && base.job.def == JobDefOf.WaitCombat)
         {
             if (base.pawn.drafter != null && !base.pawn.drafter.FireAtWill)
             {
                 return;
             }
             bool allowManualCastWeapons = !base.pawn.IsColonist;
             Verb verb = base.pawn.TryGetAttackVerb(allowManualCastWeapons);
             if (verb != null && !verb.verbProps.MeleeRange)
             {
                 TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat;
                 if (verb.IsIncendiary())
                 {
                     targetScanFlags |= TargetScanFlags.NeedNonBurning;
                 }
                 Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(base.pawn, null, verb.verbProps.range, verb.verbProps.minRange, targetScanFlags);
                 if (thing != null)
                 {
                     base.pawn.TryStartAttack(thing);
                 }
             }
         }
     }
 }
        private void CheckForAutoAttack()
        {
            if (base.pawn.Downed || base.pawn.stances.FullBodyBusy)
            {
                return;
            }
            collideWithPawns = false;
            bool flag  = !base.pawn.WorkTagIsDisabled(WorkTags.Violent);
            bool flag2 = base.pawn.RaceProps.ToolUser && base.pawn.Faction == Faction.OfPlayer && !base.pawn.WorkTagIsDisabled(WorkTags.Firefighting);

            if (!(flag || flag2))
            {
                return;
            }
            Fire fire = null;

            for (int i = 0; i < 9; i++)
            {
                IntVec3 c = base.pawn.Position + GenAdj.AdjacentCellsAndInside[i];
                if (!c.InBounds(base.pawn.Map))
                {
                    continue;
                }
                List <Thing> thingList = c.GetThingList(base.Map);
                for (int j = 0; j < thingList.Count; j++)
                {
                    if (flag)
                    {
                        Pawn pawn = thingList[j] as Pawn;
                        if (pawn != null && !pawn.Downed && base.pawn.HostileTo(pawn) && GenHostility.IsActiveThreatTo(pawn, base.pawn.Faction))
                        {
                            base.pawn.meleeVerbs.TryMeleeAttack(pawn);
                            collideWithPawns = true;
                            return;
                        }
                    }
                    if (flag2)
                    {
                        Fire fire2 = thingList[j] as Fire;
                        if (fire2 != null && (fire == null || fire2.fireSize < fire.fireSize || i == 8) && (fire2.parent == null || fire2.parent != base.pawn))
                        {
                            fire = fire2;
                        }
                    }
                }
            }
            if (fire != null && (!base.pawn.InMentalState || base.pawn.MentalState.def.allowBeatfire))
            {
                base.pawn.natives.TryBeatFire(fire);
            }
            else
            {
                if (!flag || !job.canUseRangedWeapon || base.pawn.Faction == null || job.def != JobDefOf.Wait_Combat || (base.pawn.drafter != null && !base.pawn.drafter.FireAtWill))
                {
                    return;
                }
                Verb currentEffectiveVerb = base.pawn.CurrentEffectiveVerb;
                if (currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack)
                {
                    TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToAll | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable;
                    if (currentEffectiveVerb.IsIncendiary())
                    {
                        targetScanFlags |= TargetScanFlags.NeedNonBurning;
                    }
                    Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(base.pawn, targetScanFlags);
                    if (thing != null)
                    {
                        base.pawn.TryStartAttack(thing);
                        collideWithPawns = true;
                    }
                }
            }
        }