예제 #1
0
 private void DeregisterTarget(IAttackTarget target)
 {
     if (!allTargets.Contains(target))
     {
         Log.Warning("Tried to deregister " + target + " but it's not in " + GetType());
     }
     else
     {
         allTargets.Remove(target);
         foreach (KeyValuePair <Faction, HashSet <IAttackTarget> > item in targetsHostileToFaction)
         {
             HashSet <IAttackTarget> value = item.Value;
             value.Remove(target);
         }
         Pawn pawn = target as Pawn;
         if (pawn != null)
         {
             pawnsInAggroMentalState.Remove(pawn);
         }
     }
 }
예제 #2
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;
            if (target is Pawn pawn && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num -= 50f;
            }
            num += PCF_AttackTargetFinder.FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb);
            return(num + PCF_AttackTargetFinder.FriendlyFireConeTargetScoreOffset(target, searcher, verb));
        }
예제 #3
0
        private int GetMaxPreferredReservationsCount(IAttackTarget target)
        {
            int      num      = 0;
            Thing    thing    = target.Thing;
            CellRect cellRect = thing.OccupiedRect();

            foreach (IntVec3 c in cellRect.ExpandedBy(1))
            {
                if (!cellRect.Contains(c))
                {
                    if (c.InBounds(this.map))
                    {
                        if (c.Standable(this.map))
                        {
                            num++;
                        }
                    }
                }
            }
            return(num);
        }
예제 #4
0
        public AttackTask(IActor actor,
                          IActorTaskContext context,
                          IAttackTarget target,
                          ICombatAct tacticalAct,
                          ITacticalActUsageService actService) :
            base(actor, context)
        {
            _actService = actService;

            TargetObject = target ?? throw new ArgumentNullException(nameof(target));
            TacticalAct  = tacticalAct ?? throw new ArgumentNullException(nameof(tacticalAct));

            TargetNode = target.Node;

            var combatActDuration = tacticalAct.Stats.Duration.GetValueOrDefault(1);
            var durationBonus     = GetDurationBonus(actor);
            var durationWithBonus =
                (int)Math.Round(GlobeMetrics.OneIterationLength * combatActDuration * durationBonus);

            Cost = durationWithBonus;
        }
예제 #5
0
 private void RegisterTarget(IAttackTarget target)
 {
     if (allTargets.Contains(target))
     {
         Log.Warning("Tried to register the same target twice " + target.ToStringSafe() + " in " + GetType());
     }
     else
     {
         Thing thing = target.Thing;
         if (!thing.Spawned)
         {
             Log.Warning("Tried to register unspawned thing " + thing.ToStringSafe() + " in " + GetType());
         }
         else if (thing.Map != map)
         {
             Log.Warning("Tried to register attack target " + thing.ToStringSafe() + " but its Map is not this one.");
         }
         else
         {
             allTargets.Add(target);
             List <Faction> allFactionsListForReading = Find.FactionManager.AllFactionsListForReading;
             for (int i = 0; i < allFactionsListForReading.Count; i++)
             {
                 if (thing.HostileTo(allFactionsListForReading[i]))
                 {
                     if (!targetsHostileToFaction.ContainsKey(allFactionsListForReading[i]))
                     {
                         targetsHostileToFaction.Add(allFactionsListForReading[i], new HashSet <IAttackTarget>());
                     }
                     targetsHostileToFaction[allFactionsListForReading[i]].Add(target);
                 }
             }
             Pawn pawn = target as Pawn;
             if (pawn != null && pawn.InAggroMentalState)
             {
                 pawnsInAggroMentalState.Add(pawn);
             }
         }
     }
 }
예제 #6
0
        private static float FriendlyFireBlastRadiusTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            if (verb.verbProps.ai_AvoidFriendlyFireRadius <= 0f)
            {
                return(0f);
            }
            Map     map      = target.Thing.Map;
            IntVec3 position = target.Thing.Position;
            int     num      = GenRadial.NumCellsInRadius(verb.verbProps.ai_AvoidFriendlyFireRadius);
            float   num2     = 0f;

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = position + GenRadial.RadialPattern[i];
                if (!intVec.InBounds(map))
                {
                    continue;
                }
                bool         flag      = true;
                List <Thing> thingList = intVec.GetThingList(map);
                for (int j = 0; j < thingList.Count; j++)
                {
                    if (!(thingList[j] is IAttackTarget) || thingList[j] == target)
                    {
                        continue;
                    }
                    if (flag)
                    {
                        if (!GenSight.LineOfSight(position, intVec, map, skipFirstCell: true))
                        {
                            break;
                        }
                        flag = false;
                    }
                    float num3 = (thingList[j] == searcher) ? 40f : ((!(thingList[j] is Pawn)) ? 10f : (thingList[j].def.race.Animal ? 7f : 18f));
                    num2 = ((!searcher.Thing.HostileTo(thingList[j])) ? (num2 - num3) : (num2 + num3 * 0.6f));
                }
            }
            return(num2);
        }
예제 #7
0
        public static bool IsActiveThreatTo(IAttackTarget target, Faction faction)
        {
            if (!target.Thing.HostileTo(faction))
            {
                return(false);
            }
            if (!(target.Thing is IAttackTargetSearcher))
            {
                return(false);
            }
            if (target.ThreatDisabled(null))
            {
                return(false);
            }
            Pawn pawn = target.Thing as Pawn;

            if (pawn != null)
            {
                Lord lord = pawn.GetLord();
                if (lord != null && lord.LordJob is LordJob_DefendAndExpandHive && (pawn.mindState.duty == null || pawn.mindState.duty.def != DutyDefOf.AssaultColony))
                {
                    return(false);
                }
            }
            Pawn pawn2 = target.Thing as Pawn;

            if (pawn2 != null && (pawn2.MentalStateDef == MentalStateDefOf.PanicFlee || pawn2.IsPrisoner))
            {
                return(false);
            }
            if (target.Thing.Spawned)
            {
                TraverseParms traverseParms = (pawn2 == null) ? TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false) : TraverseParms.For(pawn2, Danger.Deadly, TraverseMode.ByPawn, false);
                if (!target.Thing.Map.reachability.CanReachUnfogged(target.Thing.Position, traverseParms))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #8
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            IntVec3 intVec = (IntVec3)pawn.mindState.duty.focus;

            if (intVec.IsValid && (float)intVec.DistanceToSquared(pawn.Position) < 100.0 && intVec.GetRoom(pawn.Map, RegionType.Set_Passable) == pawn.GetRoom(RegionType.Set_Passable) && intVec.WithinRegions(pawn.Position, pawn.Map, 9, TraverseMode.NoPassClosedDoors, RegionType.Set_Passable))
            {
                pawn.GetLord().Notify_ReachedDutyLocation(pawn);
                return(null);
            }
            if (!intVec.IsValid)
            {
                IAttackTarget attackTarget = default(IAttackTarget);
                if (!(from x in pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn)
                      where !x.ThreatDisabled() && x.Thing.Faction == Faction.OfPlayer && pawn.CanReach(x.Thing, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.PassAllDestroyableThings)
                      select x).TryRandomElement <IAttackTarget>(out attackTarget))
                {
                    return(null);
                }
                intVec = attackTarget.Thing.Position;
            }
            if (!pawn.CanReach(intVec, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.PassAllDestroyableThings))
            {
                return(null);
            }
            using (PawnPath path = pawn.Map.pathFinder.FindPath(pawn.Position, intVec, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassAllDestroyableThings, false), PathEndMode.OnCell))
            {
                IntVec3 cellBeforeBlocker = default(IntVec3);
                Thing   thing             = path.FirstBlockingBuilding(out cellBeforeBlocker, pawn);
                if (thing != null)
                {
                    Job job = DigUtility.PassBlockerJob(pawn, thing, cellBeforeBlocker, this.canMineMineables, this.canMineNonMineables);
                    if (job != null)
                    {
                        return(job);
                    }
                }
            }
            return(new Job(JobDefOf.Goto, intVec, 500, true));
        }
        public static bool ShouldFleeFrom(Thing t, Pawn pawn, bool checkDistance, bool checkLOS)
        {
            if (t == pawn || (checkDistance && !t.Position.InHorDistOf(pawn.Position, 8f)))
            {
                return(false);
            }
            if (t.def.alwaysFlee)
            {
                return(true);
            }
            if (!t.HostileTo(pawn))
            {
                return(false);
            }
            IAttackTarget attackTarget = t as IAttackTarget;

            if (attackTarget == null || attackTarget.ThreatDisabled(pawn) || !(t is IAttackTargetSearcher) || (checkLOS && !GenSight.LineOfSight(pawn.Position, t.Position, pawn.Map)))
            {
                return(false);
            }
            return(true);
        }
예제 #10
0
        private static void RemoveAllReservationsAndDesignationsOnThis(Thing __instance)
        {
            if (__instance.def.category == ThingCategory.Mote)
            {
                return;
            }

            List <Map> maps = Find.Maps;

            for (int i = 0; i < maps.Count; i++)
            {
                maps[i].reservationManager.ReleaseAllForTarget(__instance);
                maps[i].physicalInteractionReservationManager.ReleaseAllForTarget(__instance);
                IAttackTarget attackTarget = __instance as IAttackTarget;
                if (attackTarget != null)
                {
                    maps[i].attackTargetReservationManager.ReleaseAllForTarget(attackTarget);
                }

                maps[i].designationManager.RemoveAllDesignationsOn(__instance);
            }
        }
예제 #11
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 == (LocalTargetInfo)searcher.Thing)
            {
                num = (float)(num + 10.0);
            }
            if (searcher.LastAttackedTarget == (LocalTargetInfo)target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num = (float)(num + 40.0);
            }
            num = (float)(num - CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10.0);
            Pawn pawn = target as Pawn;

            if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num = (float)(num - 50.0);
            }
            return(num + AttackTargetFinder.FriendlyFireShootingTargetScoreOffset(target, searcher, verb));
        }
        private AttackParams CheckAttackAvailability(IActor actor, IAttackTarget target)
        {
            if (actor.Person.GetModuleSafe <ICombatActModule>() is null)
            {
                throw new NotSupportedException();
            }

            var inventory = actor.Person.GetModuleSafe <IInventoryModule>();

            var act = SelectActHelper.SelectBestAct(actor.Person.GetModule <ICombatActModule>().CalcCombatActs(), inventory);

            var isInDistance   = act.CheckDistance(actor.Node, target.Node, _map);
            var targetIsOnLine = _map.TargetIsOnLine(actor.Node, target.Node);

            var attackParams = new AttackParams
            {
                IsAvailable = isInDistance && targetIsOnLine,
                TacticalAct = act
            };

            return(attackParams);
        }
 static bool CanShootAtShieldFromCurrentPosition(bool __result, IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
 {
     if (!Mod.Settings.EnableAIAttackTargetFinder)
     {
         return(__result);
     }
     if (__result == false)
     {
         try
         {
             var result = new FieldQuery(searcher.Thing.Map)
                          .IsActive()
                          .HostileTo(searcher.Thing.Faction)
                          .Intersects(
                 PositionUtility.ToVector3(searcher.Thing.Position),
                 PositionUtility.ToVector3(target.Thing.Position))
                          .GetWithIntersects()
                          .First();
             if (result.Second == null)
             {
                 return(false);
             }
             var distance = Vector3.Distance(searcher.Thing.TrueCenter(), result.Second.Value);
             var range    = verb.verbProps.range;
             var isTarget = result.First.Emitters
                            .Select(emitter => emitter.Thing)
                            .Any(thing => thing == target.Thing);
             if (distance <= range && isTarget)
             {
                 return(true);
             }
         }
         catch (InvalidOperationException)
         {
         }
     }
     return(__result);
 }
예제 #14
0
        private static float FriendlyFireShootingTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            if (verb.verbProps.ai_AvoidFriendlyFireRadius <= 0.0)
            {
                return(0f);
            }
            Map     map      = target.Thing.Map;
            IntVec3 position = target.Thing.Position;
            int     num      = GenRadial.NumCellsInRadius(verb.verbProps.ai_AvoidFriendlyFireRadius);
            float   num2     = 0f;

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = position + GenRadial.RadialPattern[i];
                if (intVec.InBounds(map))
                {
                    bool         flag      = true;
                    List <Thing> thingList = intVec.GetThingList(map);
                    for (int j = 0; j < thingList.Count; j++)
                    {
                        if (thingList[j] is IAttackTarget && thingList[j] != target)
                        {
                            if (flag)
                            {
                                if (!GenSight.LineOfSight(position, intVec, map, true, null, 0, 0))
                                {
                                    break;
                                }
                                flag = false;
                            }
                            float num3 = (float)((thingList[j] != searcher) ? ((!(thingList[j] is Pawn)) ? 10.0 : ((!thingList[j].def.race.Animal) ? 18.0 : 7.0)) : 40.0);
                            num2 = (float)((!searcher.Thing.HostileTo(thingList[j])) ? (num2 - num3) : (num2 + num3 * 0.60000002384185791));
                        }
                    }
                }
            }
            return(Mathf.Min(num2, 0f));
        }
        private static Thing FindTargetFor(Pawn pawn)
        {
            List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);
            int   min         = int.MaxValue;
            Thing targetFound = null;

            for (int i = 0; i < potentialTargetsFor.Count; i++)
            {
                IAttackTarget attackTarget = potentialTargetsFor[i];
                if (!attackTarget.ThreatDisabled(pawn))
                {
                    Thing target   = (Thing)attackTarget;
                    int   distance = target.Position.DistanceToSquared(pawn.Position);
                    if (distance < min && pawn.CanReach(target, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        min         = distance;
                        targetFound = target;
                    }
                }
            }

            return(targetFound);
        }
예제 #16
0
 public static bool AnyHostileActiveThreatTo(Map map, Faction faction, out IAttackTarget threat, bool countDormantPawnsAsHostile = false)
 {
     foreach (IAttackTarget item in map.attackTargetsCache.TargetsHostileToFaction(faction))
     {
         if (IsActiveThreatTo(item, faction))
         {
             threat = item;
             return(true);
         }
         Pawn pawn;
         if (countDormantPawnsAsHostile && item.Thing.HostileTo(faction) && !item.Thing.Fogged() && !item.ThreatDisabled(null) && (pawn = item.Thing as Pawn) != null)
         {
             CompCanBeDormant comp = pawn.GetComp <CompCanBeDormant>();
             if (comp != null && !comp.Awake)
             {
                 threat = item;
                 return(true);
             }
         }
     }
     threat = null;
     return(false);
 }
예제 #17
0
        public static bool ShouldFleeFrom(Thing t, Pawn pawn, bool checkDistance, bool checkLOS)
        {
            bool result;

            if (t == pawn || (checkDistance && !t.Position.InHorDistOf(pawn.Position, 8f)))
            {
                result = false;
            }
            else if (t.def.alwaysFlee)
            {
                result = true;
            }
            else if (!t.HostileTo(pawn))
            {
                result = false;
            }
            else
            {
                IAttackTarget attackTarget = t as IAttackTarget;
                result = (attackTarget != null && !attackTarget.ThreatDisabled(pawn) && t is IAttackTargetSearcher && (!checkLOS || GenSight.LineOfSight(pawn.Position, t.Position, pawn.Map, false, null, 0, 0)));
            }
            return(result);
        }
예제 #18
0
        /// <summary>
        /// Get target score
        /// </summary>
        /// <param name="target"></param>
        /// <param name="searcher"></param>
        private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher)
        {
            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;
            }
            //num += _  - add additional cost based on how close to friendly fire
            return(num * target.TargetPriorityFactor);
        }
예제 #19
0
        private static float GetShootingTargetScore(
            IAttackTarget target,
            IAttackTargetSearcher searcher,
            Verb verb)
        {
            float num1 = 60f - Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);

            if (target.TargetCurrentlyAimingAt == (LocalTargetInfo)searcher.Thing)
            {
                num1 += 10f;
            }
            if (searcher.LastAttackedTarget == (LocalTargetInfo)target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num1 += 40f;
            }
            float num2 = num1 - CoverUtility.CalculateOverallBlockChance((LocalTargetInfo)target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f;

            if (target is Pawn pawn && pawn.RaceProps.Animal && (pawn.Faction != null && !pawn.IsFighting()))
            {
                num2 -= 50f;
            }
            return((num2 + FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb) + FriendlyFireConeTargetScoreOffset(target, searcher, verb)) * target.TargetPriorityFactor);
        }
예제 #20
0
        public IActorTask GetCurrentTask()
        {
            // На каждом шаге осматриваем окрестности
            // напредмет нарушителей.
            var intruders = CheckForIntruders();

            var nearbyIntruder = intruders.FirstOrDefault();

            if (nearbyIntruder != null)
            {
                _mode             = PatrolMode.Pursuit;
                _targetIntruder   = nearbyIntruder;
                _idleTask         = null;
                _patrolPointIndex = null;
            }
            else if (_idleTask?.IsComplete == true)
            {
                _mode           = PatrolMode.Bypass;
                _targetIntruder = null;
                _idleTask       = null;
            }

            switch (_mode)
            {
            case PatrolMode.Bypass:
                return(HandleBypassMode());

            case PatrolMode.Pursuit:
                return(HandlePersiutMode());

            case PatrolMode.Idle:
                return(HandleIdleMode());

            default:
                throw new InvalidOperationException($"Неизвестный режим патруллирования {_mode}");
            }
        }
예제 #21
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            float num   = float.MaxValue;
            Thing thing = null;
            List <IAttackTarget> potentialTargetsFor = pawn.Map.attackTargetsCache.GetPotentialTargetsFor(pawn);

            for (int i = 0; i < potentialTargetsFor.Count; i++)
            {
                IAttackTarget attackTarget = potentialTargetsFor[i];
                if (!attackTarget.ThreatDisabled(pawn))
                {
                    Thing thing2 = (Thing)attackTarget;
                    int   num2   = thing2.Position.DistanceToSquared(pawn.Position);
                    if ((float)num2 < num && pawn.CanReach(thing2, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        num   = (float)num2;
                        thing = thing2;
                    }
                }
            }
            Job result;

            if (thing != null)
            {
                result = new Job(JobDefOf.Goto, thing)
                {
                    checkOverrideOnExpire = true,
                    expiryInterval        = 500,
                    collideWithPawns      = true
                };
            }
            else
            {
                result = null;
            }
            return(result);
        }
예제 #22
0
        public void StartAttacking(IAttackTarget attackTarget, object locker)
        {
            IsAttacking = true;
            var attackCooldown = Convert.ToInt32(1000 / Monster.AttackSpeed);

            while (IsAttacking)
            {
                Thread.Sleep(attackCooldown);

                lock (locker)
                {
                    if (Monster.IsDead || attackTarget.IsDead)
                    {
                        break;
                    }

                    var dealtDamage = AttackManager.Attack(attackTarget);
                    if (attackTarget.IsDead)
                    {
                        break;
                    }
                }
            }
        }
        private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            if (!(searcher.Thing is Pawn pawn))
            {
                return(0f);
            }
            if (pawn.RaceProps.intelligence < Intelligence.ToolUser)
            {
                return(0f);
            }
            if (pawn.RaceProps.IsMechanoid)
            {
                return(0f);
            }
            if (!(verb is Verb_Shoot verb_Shoot))
            {
                return(0f);
            }
            ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile;

            if (defaultProjectile == null)
            {
                return(0f);
            }
            if (defaultProjectile.projectile.flyOverhead)
            {
                return(0f);
            }
            Map                     map        = pawn.Map;
            ShotReport              report     = ShotReport.HitReportFor(pawn, verb, (Thing)target);
            float                   a          = VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source);
            float                   radius     = Mathf.Max(a, 1.5f);
            IntVec3                 dest2      = report.ShootLine.Dest;
            IEnumerable <IntVec3>   source     = from dest in GenRadial.RadialCellsAround(dest2, radius, true) where dest.InBounds(map) select dest;
            IEnumerable <ShootLine> source2    = from dest in source select new ShootLine(report.ShootLine.Source, dest);
            IEnumerable <IntVec3>   source3    = source2.SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map)));
            IEnumerable <IntVec3>   enumerable = source3.Distinct <IntVec3>();
            float                   num        = 0f;

            foreach (IntVec3 c in enumerable)
            {
                float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), c);
                if (num2 > 0f)
                {
                    List <Thing> thingList = c.GetThingList(map);
                    for (int i = 0; i < thingList.Count; i++)
                    {
                        Thing thing = thingList[i];
                        if (thing is IAttackTarget && thing != target)
                        {
                            float num3;
                            if (thing == searcher)
                            {
                                num3 = 40f;
                            }
                            else if (thing is Pawn)
                            {
                                num3 = ((!thing.def.race.Animal) ? 18f : 7f);
                            }
                            else
                            {
                                num3 = 10f;
                            }
                            num3 *= num2;
                            if (searcher.Thing.HostileTo(thing))
                            {
                                num3 *= 0.6f;
                            }
                            else
                            {
                                num3 *= -1f;
                            }
                            num += num3;
                        }
                    }
                }
            }
            return(num);
        }
 private static bool CanShootAtFromCurrentPosition(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
 {
     return(verb != null && verb.CanHitTargetFrom(searcher.Thing.Position, target.Thing));
 }
        private static IAttackTarget FindBestReachableMeleeTarget(Predicate <IAttackTarget> validator, Pawn searcherPawn, float maxTargDist, bool canBash)
        {
            maxTargDist = Mathf.Min(maxTargDist, 30f);
            IAttackTarget reachableTarget = null;

            IAttackTarget bestTargetOnCell(IntVec3 x)
            {
                List <Thing> thingList = x.GetThingList(searcherPawn.Map);

                for (int i = 0; i < thingList.Count; i++)
                {
                    Thing thing = thingList[i];
                    if (thing is IAttackTarget attackTarget)
                    {
                        if (validator(attackTarget))
                        {
                            if (ReachabilityImmediate.CanReachImmediate(x, thing, searcherPawn.Map, PathEndMode.Touch, searcherPawn))
                            {
                                if (searcherPawn.CanReachImmediate(thing, PathEndMode.Touch) || searcherPawn.Map.attackTargetReservationManager.CanReserve(searcherPawn, attackTarget))
                                {
                                    return(attackTarget);
                                }
                            }
                        }
                    }
                }
                return(null);
            }

            searcherPawn.Map.floodFiller.FloodFill(searcherPawn.Position, delegate(IntVec3 x)
            {
                if (!x.Walkable(searcherPawn.Map))
                {
                    return(false);
                }
                if ((float)x.DistanceToSquared(searcherPawn.Position) > maxTargDist * maxTargDist)
                {
                    return(false);
                }
                if (!canBash)
                {
                    if (x.GetEdifice(searcherPawn.Map) is Building_Door building_Door && !building_Door.CanPhysicallyPass(searcherPawn))
                    {
                        return(false);
                    }
                }
                return(!PawnUtility.AnyPawnBlockingPathAt(x, searcherPawn, true, false, false));
            }, delegate(IntVec3 x)
            {
                for (int i = 0; i < 8; i++)
                {
                    IntVec3 intVec = x + GenAdj.AdjacentCells[i];
                    if (intVec.InBounds(searcherPawn.Map))
                    {
                        IAttackTarget attackTarget = bestTargetOnCell(intVec);
                        if (attackTarget != null)
                        {
                            reachableTarget = attackTarget;
                            break;
                        }
                    }
                }
                return(reachableTarget != null);
            }, int.MaxValue, false, null);
            return(reachableTarget);
        }
        public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, Verb verb, 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;

            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);
                }
                if (onlyTargetMachines && t is Pawn pawn && 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;
                    foreach (IntVec3 cellRect in thing.OccupiedRect())
                    {
                        if (cellRect.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (PCF_AttackTargetFinder.HasRangedAttack(searcher, verb))
            {
                PCF_AttackTargetFinder.tmpTargets.Clear();
                PCF_AttackTargetFinder.tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                if ((byte)(flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(t) && PCF_AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash));
                }
                bool flag = false;
                for (int i = 0; i < PCF_AttackTargetFinder.tmpTargets.Count; i++)
                {
                    IAttackTarget attackTarget = PCF_AttackTargetFinder.tmpTargets[i];
                    if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && PCF_AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb))
                    {
                        flag = true;
                        break;
                    }
                }
                IAttackTarget result;
                if (flag)
                {
                    PCF_AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    result = PCF_AttackTargetFinder.GetRandomShootingTargetByScore(PCF_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) && (PCF_AttackTargetFinder.CanReach(searcherThing, t, canBash) || PCF_AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)));
                    }
                    else
                    {
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t));
                    }
                    result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, PCF_AttackTargetFinder.tmpTargets, maxDist, validator2, null);
                }
                PCF_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;

            bool 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 = PCF_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);
        }
예제 #27
0
        private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            Pawn pawn = searcher.Thing as Pawn;

            if (pawn == null)
            {
                return(0f);
            }
            if ((int)pawn.RaceProps.intelligence < 1)
            {
                return(0f);
            }
            if (pawn.RaceProps.IsMechanoid)
            {
                return(0f);
            }
            Verb_Shoot verb_Shoot = verb as Verb_Shoot;

            if (verb_Shoot == null)
            {
                return(0f);
            }
            ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile;

            if (defaultProjectile == null)
            {
                return(0f);
            }
            if (defaultProjectile.projectile.flyOverhead)
            {
                return(0f);
            }
            Map                   map        = pawn.Map;
            ShotReport            report     = ShotReport.HitReportFor(pawn, verb, (Thing)target);
            float                 radius     = Mathf.Max(VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source), 1.5f);
            IEnumerable <IntVec3> enumerable = (from dest in GenRadial.RadialCellsAround(report.ShootLine.Dest, radius, useCenter: true)
                                                where dest.InBounds(map)
                                                select new ShootLine(report.ShootLine.Source, dest)).SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map))).Distinct();
            float num = 0f;

            foreach (IntVec3 item in enumerable)
            {
                float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), item);
                if (!(num2 <= 0f))
                {
                    List <Thing> thingList = item.GetThingList(map);
                    for (int i = 0; i < thingList.Count; i++)
                    {
                        Thing thing = thingList[i];
                        if (thing is IAttackTarget && thing != target)
                        {
                            float num3 = (thing == searcher) ? 40f : ((!(thing is Pawn)) ? 10f : (thing.def.race.Animal ? 7f : 18f));
                            num3 *= num2;
                            num3  = ((!searcher.Thing.HostileTo(thing)) ? (num3 * -1f) : (num3 * 0.6f));
                            num  += num3;
                        }
                    }
                }
            }
            return(num);
        }
예제 #28
0
        public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = float.MaxValue, 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() + " who has no attack verb.");
                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 ((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 ((flags & TargetScanFlags.NeedLOSToAll) != 0)
                {
                    if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position)))
                    {
                        return(false);
                    }
                    if (!searcherThing.CanSee(thing, losValidator))
                    {
                        if (t is Pawn)
                        {
                            if ((flags & TargetScanFlags.NeedLOSToPawns) != 0)
                            {
                                return(false);
                            }
                        }
                        else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != 0)
                        {
                            return(false);
                        }
                    }
                }
                if (((flags & TargetScanFlags.NeedThreat) != 0 || (flags & TargetScanFlags.NeedAutoTargetable) != 0) && t.ThreatDisabled(searcher))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedAutoTargetable) != 0 && !IsAutoTargetable(t))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedActiveThreat) != 0 && !GenHostility.IsActiveThreatTo(t, searcher.Thing.Faction))
                {
                    return(false);
                }
                Pawn pawn = t as Pawn;
                if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh)
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning())
                {
                    return(false);
                }
                if (searcherThing.def.race != null && (int)searcherThing.def.race.intelligence >= 2)
                {
                    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;
                    foreach (IntVec3 item in thing.OccupiedRect())
                    {
                        if (!item.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState))
            {
                tmpTargets.Clear();
                tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                if ((flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator2 = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator2(t) && CanReach(searcherThing, t.Thing, canBash));
                }
                bool flag = false;
                for (int i = 0; i < tmpTargets.Count; i++)
                {
                    IAttackTarget attackTarget = tmpTargets[i];
                    if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && CanShootAtFromCurrentPosition(attackTarget, searcher, verb))
                    {
                        flag = true;
                        break;
                    }
                }
                IAttackTarget result;
                if (flag)
                {
                    tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    result = GetRandomShootingTargetByScore(tmpTargets, searcher, verb);
                }
                else
                {
                    result = (IAttackTarget)GenClosest.ClosestThing_Global(validator: ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) == 0 || (flags & TargetScanFlags.NeedReachable) != 0) ? ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t))) : ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t) && (CanReach(searcherThing, t, canBash) || CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)))), center: searcherThing.Position, searchSet: tmpTargets, maxDistance: maxDist);
                }
                tmpTargets.Clear();
                return(result);
            }
            if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState)
            {
                Predicate <IAttackTarget> oldValidator = innerValidator;
                innerValidator = delegate(IAttackTarget t)
                {
                    if (!oldValidator(t))
                    {
                        return(false);
                    }
                    return(t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius) ? true : false);
                };
            }
            IAttackTarget attackTarget2 = (IAttackTarget)GenClosest.ClosestThingReachable(searcherThing.Position, searcherThing.Map, ThingRequest.ForGroup(ThingRequestGroup.AttackTarget), PathEndMode.Touch, TraverseParms.For(searcherPawn, Danger.Deadly, TraverseMode.ByPawn, canBash), maxDist, (Thing x) => innerValidator((IAttackTarget)x), null, 0, (maxDist > 800f) ? (-1) : 40);

            if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn))
            {
                IAttackTarget attackTarget3 = 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);
        }
 public void ReleaseAllForTarget(IAttackTarget target)
 {
     reservations.RemoveAll((AttackTargetReservation x) => x.target == target);
 }
예제 #30
0
        /// <summary>
        /// Best attack target for VehicleTurret
        /// </summary>
        /// <param name="cannon"></param>
        /// <param name="flags"></param>
        /// <param name="validator"></param>
        /// <param name="minDist"></param>
        /// <param name="maxDist"></param>
        /// <param name="locus"></param>
        /// <param name="maxTravelRadiusFromLocus"></param>
        /// <param name="canBash"></param>
        /// <param name="canTakeTargetsCloserThanEffectiveMinRange"></param>
        /// <returns></returns>
        public static IAttackTarget BestAttackTarget(VehicleTurret cannon, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.4028235E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true)
        {
            VehiclePawn searcherPawn = cannon.vehicle;

            float minDistSquared              = minDist * minDist;
            float num                         = maxTravelRadiusFromLocus + cannon.MaxRange;
            float maxLocusDistSquared         = num * num;
            Func <IntVec3, bool> losValidator = null;

            if ((flags & TargetScanFlags.LOSBlockableByGas) != TargetScanFlags.None)
            {
                losValidator = delegate(IntVec3 vec3)
                {
                    Gas gas = vec3.GetGas(searcherPawn.Map);
                    return(gas == null || !gas.def.gas.blockTurretTracking);
                };
            }
            Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t)
            {
                Thing thing = t.Thing;
                if (t == searcherPawn)
                {
                    return(false);
                }
                if (minDistSquared > 0f && (float)(searcherPawn.Position - thing.Position).LengthHorizontalSquared < minDistSquared)
                {
                    return(false);
                }
                if (!canTakeTargetsCloserThanEffectiveMinRange)
                {
                    float num2 = cannon.MinRange;
                    if (num2 > 0f && (float)(cannon.vehicle.Position - thing.Position).LengthHorizontalSquared < num2 * num2)
                    {
                        return(false);
                    }
                }
                if (maxTravelRadiusFromLocus < 9999f && (thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared)
                {
                    return(false);
                }
                if (!searcherPawn.HostileTo(thing))
                {
                    return(false);
                }
                if (validator != null && !validator(thing))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedLOSToAll) != TargetScanFlags.None)
                {
                    if (losValidator != null && (!losValidator(searcherPawn.Position) || !losValidator(thing.Position)))
                    {
                        return(false);
                    }
                    if (!searcherPawn.CanSee(thing, losValidator))
                    {
                        if (t is Pawn)
                        {
                            if ((flags & TargetScanFlags.NeedLOSToPawns) != TargetScanFlags.None)
                            {
                                return(false);
                            }
                        }
                        else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != TargetScanFlags.None)
                        {
                            return(false);
                        }
                    }
                }
                if (((flags & TargetScanFlags.NeedThreat) != TargetScanFlags.None || (flags & TargetScanFlags.NeedAutoTargetable) != TargetScanFlags.None) && t.ThreatDisabled(searcherPawn))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedAutoTargetable) != TargetScanFlags.None && !AttackTargetFinder.IsAutoTargetable(t))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedActiveThreat) != TargetScanFlags.None && !GenHostility.IsActiveThreatTo(t, searcherPawn.Faction))
                {
                    return(false);
                }
                Pawn pawn = t as Pawn;
                if ((flags & TargetScanFlags.NeedNonBurning) != TargetScanFlags.None && thing.IsBurning())
                {
                    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;
                    using (CellRect.Enumerator enumerator = thing.OccupiedRect().GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            if (!enumerator.Current.Fogged(thing.Map))
                            {
                                flag2 = true;
                                break;
                            }
                        }
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            List <IAttackTarget> tmpTargets = new List <IAttackTarget>();

            tmpTargets.AddRange(searcherPawn.Map.attackTargetsCache.GetPotentialTargetsFor(searcherPawn));

            bool flag = false;

            for (int i = 0; i < tmpTargets.Count; i++)
            {
                IAttackTarget attackTarget = tmpTargets[i];
                if (attackTarget.Thing.Position.InHorDistOf(searcherPawn.Position, maxDist) && innerValidator(attackTarget) && VehicleTurret.TryFindShootLineFromTo(searcherPawn.Position, new LocalTargetInfo(attackTarget.Thing), out ShootLine resultingLine))
                {
                    flag = true;
                    break;
                }
            }
            IAttackTarget result;

            if (flag)
            {
                tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherPawn.Position, maxDist) || !innerValidator(x));
                result = GetRandomShootingTargetByScore(tmpTargets, searcherPawn);
            }
            else
            {
                Predicate <Thing> validator2;
                if ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != TargetScanFlags.None && (flags & TargetScanFlags.NeedReachable) == TargetScanFlags.None)
                {
                    validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && VehicleTurret.TryFindShootLineFromTo(searcherPawn.Position, new LocalTargetInfo(t), out ShootLine resultingLine));
                }
                else
                {
                    validator2 = ((Thing t) => innerValidator((IAttackTarget)t));
                }
                result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherPawn.Position, tmpTargets, maxDist, validator2, null);
            }
            tmpTargets.Clear();
            return(result);
        }