Exemple #1
0
        public static bool BestAttackTarget(ref IAttackTarget __result, 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);
                __result = null;
                return(false);
            }
            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) != TargetScanFlags.None)
            {
                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.NeedNotUnderThickRoof) != TargetScanFlags.None)
                {
                    RoofDef roof = thing.Position.GetRoof(thing.Map);
                    if (roof != null && roof.isThickRoof)
                    {
                        return(false);
                    }
                }
                if ((flags & TargetScanFlags.NeedLOSToAll) != TargetScanFlags.None)
                {
                    if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position)))
                    {
                        return(false);
                    }
                    if (!searcherThing.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(searcher))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedAutoTargetable) != TargetScanFlags.None && !AttackTargetFinder.IsAutoTargetable(t))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedActiveThreat) != TargetScanFlags.None && !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) != TargetScanFlags.None && 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;
                    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);
            };

            if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState))
            {
                List <IAttackTarget> tmpTargets = new List <IAttackTarget>();
                //AttackTargetFinder.tmpTargets.Clear();
                tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                if ((flags & TargetScanFlags.NeedReachable) != TargetScanFlags.None)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(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 = null;
                if (flag)
                {
                    tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    _ = GetRandomShootingTargetByScore(ref result, tmpTargets, searcher, verb);
                }
                else
                {
                    Predicate <Thing> validator2;
                    if ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != TargetScanFlags.None && (flags & TargetScanFlags.NeedReachable) == TargetScanFlags.None)
                    {
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (CanReach(searcherThing, t, canBash) || CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)));
                    }
                    else
                    {
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t));
                    }
                    result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, tmpTargets, maxDist, validator2, null);
                }
                tmpTargets.Clear();
                __result = result;
                return(false);
            }
            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));
            }
            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, false, RegionType.Set_Passable, false);

            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;
                    }
                }
            }
            __result = attackTarget2;
            return(false);
        }
Exemple #2
0
 public bool ThreatDisabled(IAttackTargetSearcher disabledFor)
 {
     return(true);
 }
 private static bool CanShootAtFromCurrentPosition(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
 {
     return(verb?.CanHitTargetFrom(searcher.Thing.Position, target.Thing) ?? false);
 }
Exemple #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 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)
        {
            Thing searcherThing = searcher.Thing;
            Pawn  searcherPawn  = searcher as Pawn;
            Verb  verb          = searcher.CurrentEffectiveVerb;

            if (verb == null)
            {
                //Log.Error("BestAttackTarget with " + searcher + " who has no attack verb.");
                return(null);
            }
            bool  onlyTargetMachines = verb != null && verb.IsEMP();
            float minDistanceSquared = 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 (minDistanceSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistanceSquared)
                {
                    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 ((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.TryGetCompFast <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 (var iterator in thing.OccupiedRect())
                    {
                        if (!iterator.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (AdeptusAttackTargetFinder.HasRangedAttack(searcher))
            {
                //Log.Warning("Finder: Range detected. Verb is " + verb);
                //Log.Warning("Finder: Pawn " + searcherPawn.Faction);
                AdeptusAttackTargetFinder.tmpTargets.Clear();

                //This needs to be fixed. Can't use searcherThing. Doing this the hard way.
                //Set request for all attackable.
                ThingRequest        thingReq  = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget);
                IEnumerable <Thing> searchSet = searcherThing.Map.listerThings.ThingsMatching(thingReq);

                foreach (IAttackTarget iTarget in searchSet)
                {
                    AdeptusAttackTargetFinder.tmpTargets.Add(iTarget);
                }

                if ((byte)(flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(t) && AdeptusAttackTargetFinder.CanReach(searcherThing, t.Thing, canBash));
                }
                bool flag = false;
                if (searcherThing.Faction != Faction.OfPlayer)
                {
                    //Log.Warning("Finder: Target available : " + ARA_AttackTargetFinder.tmpTargets.Count);
                    for (int i = 0; i < AdeptusAttackTargetFinder.tmpTargets.Count; i++)
                    {
                        IAttackTarget attackTarget = AdeptusAttackTargetFinder.tmpTargets[i];
                        if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && AdeptusAttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb))
                        {
                            //Log.Warning("Finder: flag is true");
                            flag = true;
                            break;
                        }
                    }
                }

                IAttackTarget result;
                if (flag)
                {
                    //Log.Warning("Finder: FlagTrue result");
                    AdeptusAttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    //Log.Warning("Finder: Target Avaliable : " + ARA_AttackTargetFinder.tmpTargets.Count);
                    result = AdeptusAttackTargetFinder.GetRandomShootingTargetByScore(AdeptusAttackTargetFinder.tmpTargets, searcher, verb);
                }
                else
                {
                    Predicate <Thing> validator2;
                    if ((byte)(flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != 0 && (byte)(flags & TargetScanFlags.NeedReachable) == 0)
                    {
                        //Log.Warning("Finder: Needs reachable");
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (AdeptusAttackTargetFinder.CanReach(searcherThing, t, canBash) || AdeptusAttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)));
                    }
                    else
                    {
                        //Log.Warning("Finder: Running normal validator");
                        validator2 = ((Thing t) => innerValidator((IAttackTarget)t));
                    }
                    result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, AdeptusAttackTargetFinder.tmpTargets, maxDist, validator2, null);
                }
                AdeptusAttackTargetFinder.tmpTargets.Clear();
                //Log.Warning("Trying to return result " + result);
                return(result);
            }
            //Log.Warning("Returning Null");
            return(null);
        }
 public static IAttackTarget BestShootTargetFromCurrentPosition(IAttackTargetSearcher searcher, Predicate <Thing> validator, float maxDistance, float minDistance, TargetScanFlags flags)
 {
     return(AdeptusAttackTargetFinder.BestAttackTarget(searcher, flags, validator, minDistance, maxDistance, default(IntVec3), 3.40282347E+38f, false));
 }
Exemple #7
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))
                {
                    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, skipFirstCell: true))
                                {
                                    break;
                                }
                                flag = false;
                            }
                            float num3 = (thingList[j] == searcher) ? 40f : ((!(thingList[j] is Pawn)) ? 10f : ((!thingList[j].def.race.Animal) ? 18f : 7f));
                            num2 = ((!searcher.Thing.HostileTo(thingList[j])) ? (num2 - num3) : (num2 + num3 * 0.6f));
                        }
                    }
                }
            }
            return(num2);
        }
        private static IAttackTarget GetRandomShootingTargetByScore(List <IAttackTarget> targets, IAttackTargetSearcher searcher, Verb verb)
        {
            Pair <IAttackTarget, float> pair;

            if (AdeptusAttackTargetFinder.GetAvailableShootingTargetsByScore(targets, searcher, verb).TryRandomElementByWeight((Pair <IAttackTarget, float> x) => x.Second, out pair))
            {
                return(pair.First);
            }
            return(null);
        }
Exemple #9
0
        private static List <Pair <IAttackTarget, float> > GetAvailableShootingTargetsByScore(List <IAttackTarget> rawTargets, IAttackTargetSearcher searcher, Verb verb)
        {
            availableShootingTargets.Clear();
            if (rawTargets.Count == 0)
            {
                return(availableShootingTargets);
            }
            tmpTargetScores.Clear();
            tmpCanShootAtTarget.Clear();
            float         num          = 0f;
            IAttackTarget attackTarget = null;

            for (int i = 0; i < rawTargets.Count; i++)
            {
                tmpTargetScores.Add(float.MinValue);
                tmpCanShootAtTarget.Add(item: false);
                if (rawTargets[i] == searcher)
                {
                    continue;
                }
                bool flag = CanShootAtFromCurrentPosition(rawTargets[i], searcher, verb);
                tmpCanShootAtTarget[i] = flag;
                if (flag)
                {
                    float shootingTargetScore = GetShootingTargetScore(rawTargets[i], searcher, verb);
                    tmpTargetScores[i] = shootingTargetScore;
                    if (attackTarget == null || shootingTargetScore > num)
                    {
                        attackTarget = rawTargets[i];
                        num          = shootingTargetScore;
                    }
                }
            }
            if (num < 1f)
            {
                if (attackTarget != null)
                {
                    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 && tmpCanShootAtTarget[j])
                    {
                        float num3 = tmpTargetScores[j];
                        if (num3 >= num2)
                        {
                            float second = Mathf.InverseLerp(num - 30f, num, num3);
                            availableShootingTargets.Add(new Pair <IAttackTarget, float>(rawTargets[j], second));
                        }
                    }
                }
            }
            return(availableShootingTargets);
        }
Exemple #10
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);
        }
        public static bool GetPotentialTargetsFor(AttackTargetsCache __instance, ref List <IAttackTarget> __result, IAttackTargetSearcher th)
        {
            Thing thing = th.Thing;
            List <IAttackTarget> targets = new List <IAttackTarget>();
            Faction faction = thing.Faction;

            if (faction != null)
            {
                foreach (IAttackTarget attackTarget in TargetsHostileToFaction2(__instance, faction))
                {
                    if (thing.HostileTo(attackTarget.Thing))
                    {
                        targets.Add(attackTarget);
                    }
                }
            }
            foreach (Pawn pawn in pawnsInAggroMentalState(__instance))
            {
                if (thing.HostileTo(pawn))
                {
                    targets.Add(pawn);
                }
            }
            foreach (Pawn pawn2 in factionlessHumanlikes(__instance))
            {
                if (thing.HostileTo(pawn2))
                {
                    targets.Add(pawn2);
                }
            }
            Pawn pawn3 = th as Pawn;

            if (pawn3 != null && PrisonBreakUtility.IsPrisonBreaking(pawn3))
            {
                Faction     hostFaction = pawn3.guest.HostFaction;
                List <Pawn> list        = map(__instance).mapPawns.SpawnedPawnsInFaction(hostFaction);
                for (int i = 0; i < list.Count; i++)
                {
                    if (thing.HostileTo(list[i]))
                    {
                        targets.Add(list[i]);
                    }
                }
            }
            __result = targets;
            return(false);
        }
        public static bool GetPotentialTargetsFor(AttackTargetsCache __instance, ref List <IAttackTarget> __result, IAttackTargetSearcher th)
        {
            Thing thing = th.Thing;
            List <IAttackTarget> targets = new List <IAttackTarget>();
            Faction faction = thing.Faction;

            if (faction != null)
            {
                List <IAttackTarget> snapshotTargetsHostileToFactionList = getTargetsHostileToFactionList(__instance, faction);
                foreach (IAttackTarget item in snapshotTargetsHostileToFactionList)
                {
                    if (thing.HostileTo(item.Thing))
                    {
                        targets.Add(item);
                    }
                }
            }
            if (pawnsInAggroMentalStateDict.TryGetValue(__instance, out List <Pawn> listPawnsInAggroMentalState))
            {
                foreach (Pawn pawn in listPawnsInAggroMentalState)
                {
                    if (thing.HostileTo(pawn))
                    {
                        targets.Add(pawn);
                    }
                }
            }

            if (factionlessHumanlikesDict.TryGetValue(__instance, out List <Pawn> listFactionlessHumanlikes))
            {
                foreach (Pawn pawn2 in listFactionlessHumanlikes)
                {
                    if (thing.HostileTo(pawn2))
                    {
                        targets.Add(pawn2);
                    }
                }
            }

            if (th is Pawn pawn3 && PrisonBreakUtility.IsPrisonBreaking(pawn3))
            {
                Faction     hostFaction = pawn3.guest.HostFaction;
                List <Pawn> list        = map(__instance).mapPawns.SpawnedPawnsInFaction(hostFaction);
                for (int i = 0; i < list.Count; i++)
                {
                    if (thing.HostileTo(list[i]))
                    {
                        targets.Add(list[i]);
                    }
                }
            }
            __result = targets;
            return(false);
        }
Exemple #13
0
 public bool ThreatDisabled(IAttackTargetSearcher disabledFor)
 {
     return(_deployed.ThreatDisabled(disabledFor));
 }
        public static void IgnoreShoulderTurret(Building_Turret_Shoulder __instance, ref bool __result, IAttackTargetSearcher disabledFor)
        {
            bool selected__instance = Find.Selector.SelectedObjects.Contains(__instance);
            bool shouldturret       = false;

            if (__instance != null)
            {
                if (__instance is Building_Turret_Shoulder)
                {
                    shouldturret = true;
                }
            }
            __result = (__result || shouldturret);
        }
 private static float AdjustedRange(float original, Verb verb, IAttackTargetSearcher searcher)
 {
     return(TrenchUtility.FinalAdjustedRangeFromTerrain(original, verb, searcher.Thing));
 }
        private static bool HasRangedAttack(IAttackTargetSearcher t)
        {
            Verb currentEffectiveVerb = t.CurrentEffectiveVerb;

            return(currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack);
        }
        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.");
                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);
        }
        private static List <Pair <IAttackTarget, float> > GetAvailableShootingTargetsByScore(List <IAttackTarget> rawTargets, IAttackTargetSearcher searcher, Verb verb)
        {
            AdeptusAttackTargetFinder.availableShootingTargets.Clear();
            if (rawTargets.Count == 0)
            {
                return(AdeptusAttackTargetFinder.availableShootingTargets);
            }
            AdeptusAttackTargetFinder.tmpTargetScores.Clear();
            AdeptusAttackTargetFinder.tmpCanShootAtTarget.Clear();
            float         num          = 0f;
            IAttackTarget attackTarget = null;

            for (int i = 0; i < rawTargets.Count; i++)
            {
                AdeptusAttackTargetFinder.tmpTargetScores.Add(-3.40282347E+38f);
                AdeptusAttackTargetFinder.tmpCanShootAtTarget.Add(false);
                if (rawTargets[i] != searcher)
                {
                    bool flag = AdeptusAttackTargetFinder.CanShootAtFromCurrentPosition(rawTargets[i], searcher, verb);
                    AdeptusAttackTargetFinder.tmpCanShootAtTarget[i] = flag;
                    if (flag)
                    {
                        float shootingTargetScore = AdeptusAttackTargetFinder.GetShootingTargetScore(rawTargets[i], searcher, verb);
                        AdeptusAttackTargetFinder.tmpTargetScores[i] = shootingTargetScore;
                        if (attackTarget == null || shootingTargetScore > num)
                        {
                            attackTarget = rawTargets[i];
                            num          = shootingTargetScore;
                        }
                    }
                }
            }
            if (num < 1f)
            {
                if (attackTarget != null)
                {
                    AdeptusAttackTargetFinder.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 (AdeptusAttackTargetFinder.tmpCanShootAtTarget[j])
                        {
                            float num3 = AdeptusAttackTargetFinder.tmpTargetScores[j];
                            if (num3 >= num2)
                            {
                                float second = Mathf.InverseLerp(num - 30f, num, num3);
                                AdeptusAttackTargetFinder.availableShootingTargets.Add(new Pair <IAttackTarget, float>(rawTargets[j], second));
                            }
                        }
                    }
                }
            }
            return(AdeptusAttackTargetFinder.availableShootingTargets);
        }
 private static bool HasRangedAttack(IAttackTargetSearcher t, Verb verb)
 {
     return(verb != null && !verb.verbProps.IsMeleeAttack);
 }
        private static float FriendlyFireShootingTargetScoreOffset(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))
                {
                    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;
                            if (thingList[j] == searcher)
                            {
                                num3 = 40f;
                            }
                            else if (thingList[j] is Pawn)
                            {
                                num3 = ((!thingList[j].def.race.Animal) ? 18f : 7f);
                            }
                            else
                            {
                                num3 = 10f;
                            }
                            if (searcher.Thing.HostileTo(thingList[j]))
                            {
                                num2 += num3 * 0.6f;
                            }
                            else
                            {
                                num2 -= num3;
                            }
                        }
                    }
                }
            }
            return(Mathf.Min(num2, 0f));
        }
        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);
        }
        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))
                    {
                        //	Log.Messageage(thing + " lord ValidateAttackTarget: false");
                        return(false);
                    }
                }
                if ((flags & TargetScanFlags.NeedNotUnderThickRoof) != 0)
                {
                    RoofDef roof = thing.Position.GetRoof(thing.Map);
                    if (roof != null && roof.isThickRoof)
                    {
                        //	Log.Messageage(thing + " isThickRoof: false");
                        return(false);
                    }
                }
                if ((flags & TargetScanFlags.NeedLOSToAll) != 0)
                {
                    if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position)))
                    {
                        //	Log.Messageage(thing + " LOSToAll: false");
                        return(false);
                    }
                    if (!searcherThing.CanSee(thing, losValidator))
                    {
                        if (t is Pawn)
                        {
                            if ((flags & TargetScanFlags.NeedLOSToPawns) != 0)
                            {
                                //	Log.Messageage(thing + " LOSToPawns: false");
                                return(false);
                            }
                        }
                        else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != 0)
                        {
                            //	Log.Messageage(thing + " LOSToNonPawns: false");
                            return(false);
                        }
                    }
                }
                if (((flags & TargetScanFlags.NeedThreat) != 0 || (flags & TargetScanFlags.NeedAutoTargetable) != 0) && t.ThreatDisabled(searcher))
                {
                    //	Log.Messageage(thing + " NeedThreat: false");
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedAutoTargetable) != 0 && !IsAutoTargetable(t))
                {
                    //	Log.Messageage(thing + " NeedAutoTargetable: false");
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedActiveThreat) != 0 && !GenHostility.IsActiveThreatTo(t, searcher.Thing.Faction))
                {
                    //	Log.Messageage(thing + " NeedActiveThreat: false");
                    return(false);
                }
                Pawn pawn = t as Pawn;
                if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh)
                {
                    //	Log.Messageage(thing + " onlyTargetMachines: false");
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning())
                {
                    //	Log.Messageage(thing + " NeedNonBurning: false");
                    return(false);
                }
                if (searcherThing.def.race != null && (int)searcherThing.def.race.intelligence >= 2)
                {
                    CompExplosive compExplosive = thing.TryGetCompFast <CompExplosive>();
                    if (compExplosive != null && compExplosive.wickStarted)
                    {
                        //	Log.Messageage(thing + " wickStarted: false");
                        return(false);
                    }
                }
                if (thing.def.size.x == 1 && thing.def.size.z == 1)
                {
                    if (thing.Position.Fogged(thing.Map))
                    {
                        //	Log.Messageage(thing + " Fogged: false");
                        return(false);
                    }
                }
                else
                {
                    bool flag2 = false;
                    foreach (IntVec3 item in thing.OccupiedRect())
                    {
                        if (!item.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (!flag2)
                    {
                        //	Log.Messageage(thing + " Fogged: false");
                        return(false);
                    }
                }
                //	Log.Messageage(thing + " valid: true");
                return(true);
            };

            if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState))
            {
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  0");
                tmpTargets.Clear();
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  1");
                tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  2 tmpTargets: " + tmpTargets.Count);
                if ((flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator2 = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator2(t) && CanReach(searcherThing, t.Thing, canBash));
                }
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  3");
                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;
                    }
                }
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack 4 ");
                IAttackTarget attackTarget2;
                if (flag)
                {
                    tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    attackTarget2 = GetRandomShootingTargetByScore(tmpTargets, searcher, verb);
                }
                else
                {
                    attackTarget2 = (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);
                }
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  5");
                tmpTargets.Clear();
                //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack tgt found: " + (attackTarget2 != null).ToString());
                return(attackTarget2);
            }
            //	Log.Messageage(searcher + "AttackTargetFinder.HasRangedAttack  no ranged attack found");
            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));
            }
            IAttackTarget attackTarget3 = (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 (attackTarget3 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn))
            {
                IAttackTarget attackTarget4 = FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash);
                if (attackTarget4 != null)
                {
                    float lengthHorizontal  = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal;
                    float lengthHorizontal2 = (searcherPawn.Position - attackTarget4.Thing.Position).LengthHorizontal;
                    if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f)
                    {
                        attackTarget3 = attackTarget4;
                    }
                }
            }
            return(attackTarget3);
        }
Exemple #23
0
        private static List <Pair <IAttackTarget, float> > GetAvailableShootingTargetsByScore(
            List <IAttackTarget> rawTargets,
            IAttackTargetSearcher searcher,
            Verb verb)
        {
            List <Pair <IAttackTarget, float> > availableShootingTargets = new List <Pair <IAttackTarget, float> >();

            //AttackTargetFinder.availableShootingTargets.Clear();
            if (rawTargets.Count == 0)
            {
                return(availableShootingTargets);
            }
            //AttackTargetFinder.tmpTargetScores.Clear();
            List <float> tmpTargetScores = new List <float>();
            //AttackTargetFinder.tmpCanShootAtTarget.Clear();
            List <bool>   tmpCanShootAtTarget = new List <bool>();
            float         b     = 0.0f;
            IAttackTarget first = (IAttackTarget)null;

            for (int index = 0; index < rawTargets.Count; ++index)
            {
                tmpTargetScores.Add(float.MinValue);
                tmpCanShootAtTarget.Add(false);
                if (rawTargets[index] != searcher)
                {
                    bool flag = CanShootAtFromCurrentPosition(rawTargets[index], searcher, verb);
                    tmpCanShootAtTarget[index] = flag;
                    if (flag)
                    {
                        float shootingTargetScore = GetShootingTargetScore(rawTargets[index], searcher, verb);
                        tmpTargetScores[index] = shootingTargetScore;
                        if (first == null || (double)shootingTargetScore > (double)b)
                        {
                            first = rawTargets[index];
                            b     = shootingTargetScore;
                        }
                    }
                }
            }
            if ((double)b < 1.0)
            {
                if (first != null)
                {
                    availableShootingTargets.Add(new Pair <IAttackTarget, float>(first, 1f));
                }
            }
            else
            {
                float num = b - 30f;
                for (int index = 0; index < rawTargets.Count; ++index)
                {
                    if (rawTargets[index] != searcher && tmpCanShootAtTarget[index])
                    {
                        float tmpTargetScore = tmpTargetScores[index];
                        if ((double)tmpTargetScore >= (double)num)
                        {
                            float second = Mathf.InverseLerp(b - 30f, b, tmpTargetScore);
                            availableShootingTargets.Add(new Pair <IAttackTarget, float>(rawTargets[index], second));
                        }
                    }
                }
            }
            return(availableShootingTargets);
        }
 private static IAttackTarget GetRandomShootingTargetByScore(List <IAttackTarget> targets, IAttackTargetSearcher searcher, Verb verb)
 {
     if (GetAvailableShootingTargetsByScore(targets, searcher, verb).TryRandomElementByWeight((Pair <IAttackTarget, float> x) => x.Second, out Pair <IAttackTarget, float> result))
     {
         return(result.First);
     }
     return(null);
 }
Exemple #25
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 = 3.40282347E+38f, bool canBash = false)
        {
            Thing searcherThing = searcher.Thing;
            Pawn  searcherPawn  = searcher as Pawn;
            Verb  verb          = searcher.CurrentEffectiveVerb;

            if (verb == null)
            {
                Log.Error("BestAttackTarget with " + searcher + " who has no attack verb.");
                return(null);
            }
            bool  onlyTargetMachines = verb != null && verb.IsEMP();
            float minDistanceSquared = 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 (minDistanceSquared > 0.0 && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistanceSquared)
                {
                    return(false);
                }
                if (maxTravelRadiusFromLocus < 9999.0 && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared)
                {
                    return(false);
                }
                if (!searcherThing.HostileTo(thing))
                {
                    return(false);
                }
                if (validator != null && !validator(thing))
                {
                    return(false);
                }
                if ((flags & TargetScanFlags.NeedLOSToAll) != 0 && !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 && t.ThreatDisabled())
                {
                    return(false);
                }
                Pawn pawn2 = t as Pawn;
                if (onlyTargetMachines && pawn2 != null && pawn2.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;
                    CellRect.CellRectIterator iterator = thing.OccupiedRect().GetIterator();
                    while (!iterator.Done())
                    {
                        if (iterator.Current.Fogged(thing.Map))
                        {
                            iterator.MoveNext();
                            continue;
                        }
                        flag2 = true;
                        break;
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (AttackTargetFinder.HasRangedAttack(searcher))
            {
                AttackTargetFinder.tmpTargets.Clear();
                AttackTargetFinder.tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher));
                if ((flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(t) && AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash));
                }
                bool flag = false;
                if (searcherThing.Faction != Faction.OfPlayer)
                {
                    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 = ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) == TargetScanFlags.None || (flags & TargetScanFlags.NeedReachable) != 0) ? ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t))) : ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t) && (AttackTargetFinder.CanReach(searcherThing, t, canBash) || AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb))));
                    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 > 0.0 && !searcherPawn.InMentalState)
            {
                Predicate <IAttackTarget> oldValidator2 = innerValidator;
                innerValidator = delegate(IAttackTarget t)
                {
                    if (!oldValidator2(t))
                    {
                        return(false);
                    }
                    if (!t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius))
                    {
                        return(false);
                    }
                    return(true);
                };
            }
            IntVec3           root             = searcherThing.Position;
            Map               map              = searcherThing.Map;
            ThingRequest      thingReq         = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget);
            PathEndMode       peMode           = PathEndMode.Touch;
            Pawn              pawn             = searcherPawn;
            Danger            maxDanger        = Danger.Deadly;
            bool              canBash2         = canBash;
            TraverseParms     traverseParams   = TraverseParms.For(pawn, maxDanger, TraverseMode.ByPawn, canBash2);
            float             maxDistance      = maxDist;
            Predicate <Thing> validator3       = (Thing x) => innerValidator((IAttackTarget)x);
            int               searchRegionsMax = (!(maxDist > 800.0)) ? 40 : (-1);
            IAttackTarget     attackTarget2    = (IAttackTarget)GenClosest.ClosestThingReachable(root, map, thingReq, peMode, traverseParams, maxDistance, 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)
                {
                    root = searcherPawn.Position - attackTarget2.Thing.Position;
                    float lengthHorizontal  = root.LengthHorizontal;
                    float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal;
                    if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50.0)
                    {
                        attackTarget2 = attackTarget3;
                    }
                }
            }
            return(attackTarget2);
        }