コード例 #1
0
        public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != this.caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (this.verbProps.MeleeRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = cellRect.ClosestDistSquaredTo(root);

            if (num > this.verbProps.range * this.verbProps.range || num < this.verbProps.minRange * this.verbProps.minRange)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile
            if (Projectile.projectile.flyOverhead)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            if (this.CasterIsPawn)
            {
                IntVec3 dest;
                if (this.CanHitFromCellIgnoringRange(root, targ, out dest))
                {
                    resultingLine = new ShootLine(root, dest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, tempLeanShootSources);
                for (int i = 0; i < tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = tempLeanShootSources[i];
                    if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec, dest);
                        return(true);
                    }
                }
            }
            else
            {
                CellRect.CellRectIterator iterator = this.caster.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    IntVec3 dest;
                    if (this.CanHitFromCellIgnoringRange(current, targ, out dest))
                    {
                        resultingLine = new ShootLine(current, dest);
                        return(true);
                    }
                    iterator.MoveNext();
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
コード例 #2
0
        private void SpawnRoofOver(Thing thing)
        {
            CellRect cellRect = thing.OccupiedRect();
            bool     flag     = true;

            CellRect.CellRectIterator iterator = cellRect.GetIterator();
            while (!iterator.Done())
            {
                if (!iterator.Current.Roofed(thing.Map))
                {
                    flag = false;
                    break;
                }
                iterator.MoveNext();
            }
            if (flag)
            {
                return;
            }
            int      num       = 0;
            CellRect cellRect2 = cellRect.ExpandedBy(2);

            CellRect.CellRectIterator iterator2 = cellRect2.GetIterator();
            while (!iterator2.Done())
            {
                if (iterator2.Current.InBounds(thing.Map) && iterator2.Current.GetRoofHolderOrImpassable(thing.Map) != null)
                {
                    num++;
                }
                iterator2.MoveNext();
            }
            if (num < 2)
            {
                ThingDef stuff = Rand.Element <ThingDef>(ThingDefOf.WoodLog, ThingDefOf.Steel);
                foreach (IntVec3 current in cellRect2.Corners)
                {
                    if (current.InBounds(thing.Map))
                    {
                        if (current.Standable(thing.Map))
                        {
                            if (current.GetFirstItem(thing.Map) == null && current.GetFirstBuilding(thing.Map) == null && current.GetFirstPawn(thing.Map) == null)
                            {
                                if (!GenAdj.CellsAdjacent8Way(new TargetInfo(current, thing.Map, false)).Any((IntVec3 x) => !x.InBounds(thing.Map) || !x.Walkable(thing.Map)))
                                {
                                    if (current.SupportsStructureType(thing.Map, ThingDefOf.Wall.terrainAffordanceNeeded))
                                    {
                                        Thing thing2 = ThingMaker.MakeThing(ThingDefOf.Wall, stuff);
                                        GenSpawn.Spawn(thing2, current, thing.Map, WipeMode.Vanish);
                                        thing2.SetFaction(thing.Faction, null);
                                        num++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (num > 0)
            {
                CellRect.CellRectIterator iterator3 = cellRect2.GetIterator();
                while (!iterator3.Done())
                {
                    if (iterator3.Current.InBounds(thing.Map) && !iterator3.Current.Roofed(thing.Map))
                    {
                        thing.Map.roofGrid.SetRoof(iterator3.Current, RoofDefOf.RoofConstructed);
                    }
                    iterator3.MoveNext();
                }
            }
        }
コード例 #3
0
        public override void Resolve(ResolveParams rp)
        {
            CellRect.CellRectIterator iterator = rp.rect.ContractedBy(1).GetIterator();
            while (!iterator.Done())
            {
                if (rp.clearEdificeOnly.HasValue && rp.clearEdificeOnly.Value)
                {
                    Building edifice = iterator.Current.GetEdifice(BaseGen.globalSettings.map);
                    if (edifice != null && edifice.def.destroyable)
                    {
                        if (edifice.def != CthulhuFactionsDefOf.ROM_TemporaryDoorMarker)
                        {
                            edifice.Destroy(DestroyMode.Vanish);
                        }
                    }
                }
                else
                {
                    SymbolResolverAgency.tmpThingsToDestroy.Clear();
                    SymbolResolverAgency.tmpThingsToDestroy.AddRange(iterator.Current.GetThingList(BaseGen.globalSettings.map));
                    for (int i = 0; i < SymbolResolverAgency.tmpThingsToDestroy.Count; i++)
                    {
                        if (SymbolResolverAgency.tmpThingsToDestroy[i].def.destroyable)
                        {
                            if (SymbolResolverAgency.tmpThingsToDestroy[i].def != CthulhuFactionsDefOf.ROM_TemporaryDoorMarker)
                            {
                                SymbolResolverAgency.tmpThingsToDestroy[i].Destroy(DestroyMode.Vanish);
                            }
                        }
                    }
                }
                iterator.MoveNext();
            }

            foreach (IntVec3 cell in rp.rect.Cells)
            {
                ResolveParams resolveParams3 = rp;
                resolveParams3.rect           = CellRect.SingleCell(cell);
                resolveParams3.singleThingDef = CthulhuFactionsDefOf.ROM_TemporaryRegionBarrier;
                BaseGen.symbolStack.Push("thing", resolveParams3);
            }

            PassingParameters(rp);
            instanceMap     = map;
            instanceFaction = rp.faction ?? Find.FactionManager.FirstFactionOfDef(FactionDef.Named("TheAgency"));

            //ResolveParams resolveParams4 = rp;
            //BaseGen.symbolStack.Push("clear", resolveParams4);

            UnfogRoomCenter(rp.rect.CenterCell);

            LongEventHandler.QueueLongEvent(delegate
            {
                if (SymbolResolverAgency.instanceMap == null)
                {
                    return;
                }
                foreach (IntVec3 cell in SymbolResolverAgency.instanceMap.AllCells)
                {
                    Thing thing = cell.GetThingList(instanceMap).Find((Thing x) => x.def == CthulhuFactionsDefOf.ROM_TemporaryDoorMarker);
                    if (thing == null)
                    {
                        //Log.Warning("Could not destroy temporary region barrier at " + cell + " because it's not here.");
                    }
                    else
                    {
                        if (thing.def == CthulhuFactionsDefOf.ROM_TemporaryDoorMarker)
                        {
                            SymbolResolverAgency.newThing = null;
                            SymbolResolverAgency.newThing = ThingMaker.MakeThing(ThingDefOf.Door, ThingDefOf.Steel);
                            SymbolResolverAgency.newThing.SetFaction(SymbolResolverAgency.instanceFaction, null);
                            //newThing.Rotation = thing.Rotation;
                            tempIntVec = new IntVec3(cell.x, 0, cell.z);
                            GenSpawn.Spawn(SymbolResolverAgency.newThing, SymbolResolverAgency.tempIntVec, SymbolResolverAgency.instanceMap);
                        }
                        thing.Destroy(DestroyMode.Vanish);
                    }
                }
                foreach (Pawn pawn in SymbolResolverAgency.instanceMap.mapPawns.AllPawnsSpawned.FindAll((Pawn x) => x != null && x.Spawned && x.RaceProps.intelligence >= Intelligence.ToolUser && !x.IsColonist && x.Faction != instanceFaction && x.guest != null && SymbolResolver_FillCells.IsCosmicHorrorFaction(x.Faction) == false))
                {
                    pawn.guest.SetGuestStatus(instanceFaction, true);
                }
                foreach (Building_Bed bed in SymbolResolverAgency.instanceMap.listerThings.AllThings.FindAll((Thing x) => x != null && x is Building_Bed && x.def == ThingDefOf.SleepingSpot && x.Faction == instanceFaction))
                {
                    bed.ForPrisoners = true;
                }
            }, "doorResolver", true, null);
        }
コード例 #4
0
        private static bool TryFindSiegePosition(IntVec3 entrySpot, float minDistToColony, Map map, out IntVec3 result)
        {
            CellRect cellRect = CellRect.CenteredOn(entrySpot, 60);

            cellRect.ClipInsideMap(map);
            cellRect = cellRect.ContractedBy(14);
            List <IntVec3> list = new List <IntVec3>();

            foreach (Pawn current in map.mapPawns.FreeColonistsSpawned)
            {
                list.Add(current.Position);
            }
            foreach (Building current2 in map.listerBuildings.allBuildingsColonistCombatTargets)
            {
                list.Add(current2.Position);
            }
            float   num  = minDistToColony * minDistToColony;
            int     num2 = 0;
            IntVec3 randomCell;

            while (true)
            {
                num2++;
                if (num2 > 200)
                {
                    break;
                }
                randomCell = cellRect.RandomCell;
                if (randomCell.Standable(map))
                {
                    if (randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Heavy) && randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Light))
                    {
                        if (map.reachability.CanReach(randomCell, entrySpot, PathEndMode.OnCell, TraverseMode.NoPassClosedDoors, Danger.Some))
                        {
                            if (map.reachability.CanReachColony(randomCell))
                            {
                                bool flag = false;
                                for (int i = 0; i < list.Count; i++)
                                {
                                    if ((float)(list[i] - randomCell).LengthHorizontalSquared < num)
                                    {
                                        flag = true;
                                        break;
                                    }
                                }
                                if (!flag)
                                {
                                    if (!randomCell.Roofed(map))
                                    {
                                        int num3 = 0;
                                        CellRect.CellRectIterator iterator = CellRect.CenteredOn(randomCell, 10).ClipInsideMap(map).GetIterator();
                                        while (!iterator.Done())
                                        {
                                            if (randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Heavy) && randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Light))
                                            {
                                                num3++;
                                            }
                                            iterator.MoveNext();
                                        }
                                        if (num3 >= 35)
                                        {
                                            goto IL_223;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            result = IntVec3.Invalid;
            return(false);

IL_223:
            result = randomCell;
            return(true);
        }
コード例 #5
0
        public static bool TryFindRandomSpotJustOutsideColony(IntVec3 root, Map map, Pawn searcher, out IntVec3 result, Predicate <IntVec3> extraValidator = null)
        {
            bool desperate                = false;
            int  minColonyBuildingsLOS    = 0;
            int  walkRadius               = 0;
            int  walkRadiusMaxImpassable  = 0;
            Predicate <IntVec3> validator = delegate(IntVec3 c)
            {
                if (!c.Standable(map))
                {
                    return(false);
                }
                Room room = c.GetRoom(map, RegionType.Set_Passable);
                if (!room.PsychologicallyOutdoors || !room.TouchesMapEdge)
                {
                    return(false);
                }
                if (room == null || room.CellCount < 60)
                {
                    return(false);
                }
                if (root.IsValid)
                {
                    TraverseParms traverseParams = (searcher == null) ? TraverseMode.PassDoors : TraverseParms.For(searcher, Danger.Deadly, TraverseMode.ByPawn, false);
                    if (!map.reachability.CanReach(root, c, PathEndMode.Touch, traverseParams))
                    {
                        return(false);
                    }
                }
                if (!desperate && !map.reachability.CanReachColony(c))
                {
                    return(false);
                }
                if (extraValidator != null && !extraValidator(c))
                {
                    return(false);
                }
                int num = 0;
                CellRect.CellRectIterator iterator = CellRect.CenteredOn(c, walkRadius).GetIterator();
                while (!iterator.Done())
                {
                    Room room2 = iterator.Current.GetRoom(map, RegionType.Set_Passable);
                    if (room2 != room)
                    {
                        num++;
                        if (!desperate && room2 != null && room2.IsDoorway)
                        {
                            return(false);
                        }
                    }
                    if (num > walkRadiusMaxImpassable)
                    {
                        return(false);
                    }
                    iterator.MoveNext();
                }
                if (minColonyBuildingsLOS > 0)
                {
                    int colonyBuildingsLOSFound = 0;
                    RCellFinder_Zombiefied.tmpBuildings.Clear();
                    RegionTraverser.BreadthFirstTraverse(c, map, (Region from, Region to) => true, delegate(Region reg)
                    {
                        Faction ofPlayer  = Faction.OfPlayer;
                        List <Thing> list = reg.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial);
                        for (int l = 0; l < list.Count; l++)
                        {
                            Thing thing = list[l];
                            if (thing.Faction == ofPlayer && thing.Position.InHorDistOf(c, 16f) && GenSight.LineOfSight(thing.Position, c, map, true, null, 0, 0) && !RCellFinder_Zombiefied.tmpBuildings.Contains(thing))
                            {
                                RCellFinder_Zombiefied.tmpBuildings.Add(thing);
                                colonyBuildingsLOSFound++;
                                if (colonyBuildingsLOSFound >= minColonyBuildingsLOS)
                                {
                                    return(true);
                                }
                            }
                        }
                        return(false);
                    }, 12, RegionType.Set_Passable);
                    RCellFinder_Zombiefied.tmpBuildings.Clear();
                    if (colonyBuildingsLOSFound < minColonyBuildingsLOS)
                    {
                        return(false);
                    }
                }
                return(true);
            };
            IEnumerable <Building> source = from b in map.listerBuildings.allBuildingsColonist
                                            where b.def.building.ai_chillDestination
                                            select b;

            for (int i = 0; i < 120; i++)
            {
                Building building = null;
                if (!source.TryRandomElement(out building))
                {
                    break;
                }
                desperate  = (i > 60);
                walkRadius = 6 - i / 20;
                walkRadiusMaxImpassable = 6 - i / 20;
                minColonyBuildingsLOS   = 5 - i / 30;
                if (CellFinder.TryFindRandomCellNear(building.Position, map, 10, validator, out result, 50))
                {
                    return(true);
                }
            }
            List <Building> allBuildingsColonist = map.listerBuildings.allBuildingsColonist;

            for (int j = 0; j < 120; j++)
            {
                Building building2 = null;
                if (!allBuildingsColonist.TryRandomElement(out building2))
                {
                    break;
                }
                desperate  = (j > 60);
                walkRadius = 6 - j / 20;
                walkRadiusMaxImpassable = 6 - j / 20;
                minColonyBuildingsLOS   = 4 - j / 30;
                if (CellFinder.TryFindRandomCellNear(building2.Position, map, 15, validator, out result, 50))
                {
                    return(true);
                }
            }
            for (int k = 0; k < 50; k++)
            {
                Pawn pawn = null;
                if (!map.mapPawns.FreeColonistsAndPrisonersSpawned.TryRandomElement(out pawn))
                {
                    break;
                }
                desperate  = (k > 25);
                walkRadius = 3;
                walkRadiusMaxImpassable = 6;
                minColonyBuildingsLOS   = 0;
                if (CellFinder.TryFindRandomCellNear(pawn.Position, map, 15, validator, out result, 50))
                {
                    return(true);
                }
            }
            desperate  = true;
            walkRadius = 3;
            walkRadiusMaxImpassable = 6;
            minColonyBuildingsLOS   = 0;
            return(CellFinderLoose.TryGetRandomCellWith(validator, map, 1000, out result));
        }
コード例 #6
0
        private static string TemperatureString()
        {
            IntVec3 intVec = UI.MouseCell();
            IntVec3 c      = intVec;
            Room    room   = intVec.GetRoom(Find.VisibleMap, RegionType.Set_All);

            if (room == null)
            {
                for (int i = 0; i < 9; i++)
                {
                    IntVec3 intVec2 = intVec + GenAdj.AdjacentCellsAndInside[i];
                    Room    room2;
                    if (intVec2.InBounds(Find.VisibleMap))
                    {
                        room2 = intVec2.GetRoom(Find.VisibleMap, RegionType.Set_All);
                        if (room2 != null)
                        {
                            if (!room2.PsychologicallyOutdoors && !room2.UsesOutdoorTemperature)
                            {
                                goto IL_00a8;
                            }
                            if (!room2.PsychologicallyOutdoors && (room == null || room.PsychologicallyOutdoors))
                            {
                                goto IL_00a8;
                            }
                            if (room2.PsychologicallyOutdoors && room == null)
                            {
                                goto IL_00a8;
                            }
                        }
                    }
                    continue;
IL_00a8:
                    c    = intVec2;
                    room = room2;
                }
            }
            if (room == null && intVec.InBounds(Find.VisibleMap))
            {
                Building edifice = intVec.GetEdifice(Find.VisibleMap);
                if (edifice != null)
                {
                    CellRect.CellRectIterator iterator = edifice.OccupiedRect().ExpandedBy(1).ClipInsideMap(Find.VisibleMap)
                                                         .GetIterator();
                    while (!iterator.Done())
                    {
                        IntVec3 current = iterator.Current;
                        room = current.GetRoom(Find.VisibleMap, RegionType.Set_All);
                        if (room != null && !room.PsychologicallyOutdoors)
                        {
                            c = current;
                            break;
                        }
                        iterator.MoveNext();
                    }
                }
            }
            string str         = (!c.InBounds(Find.VisibleMap) || c.Fogged(Find.VisibleMap) || room == null || room.PsychologicallyOutdoors) ? "Outdoors".Translate() : ((room.OpenRoofCount != 0) ? ("IndoorsUnroofed".Translate() + " (" + room.OpenRoofCount.ToStringCached() + ")") : "Indoors".Translate());
            float  celsiusTemp = (room != null && !c.Fogged(Find.VisibleMap)) ? room.Temperature : Find.VisibleMap.mapTemperature.OutdoorTemp;

            return(str + " " + celsiusTemp.ToStringTemperature("F0"));
        }
コード例 #7
0
        public static bool TryFindCastPosition(CastPositionRequest newReq, out IntVec3 dest)
        {
            CastPositionFinder.req       = newReq;
            CastPositionFinder.casterLoc = CastPositionFinder.req.caster.Position;
            CastPositionFinder.targetLoc = CastPositionFinder.req.target.Position;
            CastPositionFinder.verb      = CastPositionFinder.req.verb;
            CastPositionFinder.avoidGrid = newReq.caster.GetAvoidGrid();
            bool result;

            if (CastPositionFinder.verb == null)
            {
                Log.Error(CastPositionFinder.req.caster + " tried to find casting position without a verb.", false);
                dest   = IntVec3.Invalid;
                result = false;
            }
            else
            {
                if (CastPositionFinder.req.maxRegions > 0)
                {
                    Region region = CastPositionFinder.casterLoc.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable);
                    if (region == null)
                    {
                        Log.Error("TryFindCastPosition requiring region traversal but root region is null.", false);
                        dest = IntVec3.Invalid;
                        return(false);
                    }
                    CastPositionFinder.inRadiusMark = Rand.Int;
                    RegionTraverser.MarkRegionsBFS(region, null, newReq.maxRegions, CastPositionFinder.inRadiusMark, RegionType.Set_Passable);
                    if (CastPositionFinder.req.maxRangeFromLocus > 0.01f)
                    {
                        Region locusReg = CastPositionFinder.req.locus.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable);
                        if (locusReg == null)
                        {
                            Log.Error("locus " + CastPositionFinder.req.locus + " has no region", false);
                            dest = IntVec3.Invalid;
                            return(false);
                        }
                        if (locusReg.mark != CastPositionFinder.inRadiusMark)
                        {
                            CastPositionFinder.inRadiusMark = Rand.Int;
                            RegionTraverser.BreadthFirstTraverse(region, null, delegate(Region r)
                            {
                                r.mark = CastPositionFinder.inRadiusMark;
                                CastPositionFinder.req.maxRegions = CastPositionFinder.req.maxRegions + 1;
                                return(r == locusReg);
                            }, 999999, RegionType.Set_Passable);
                        }
                    }
                }
                CellRect cellRect = CellRect.WholeMap(CastPositionFinder.req.caster.Map);
                if (CastPositionFinder.req.maxRangeFromCaster > 0.01f)
                {
                    int      num       = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromCaster);
                    CellRect otherRect = new CellRect(CastPositionFinder.casterLoc.x - num, CastPositionFinder.casterLoc.z - num, num * 2 + 1, num * 2 + 1);
                    cellRect.ClipInsideRect(otherRect);
                }
                int      num2       = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromTarget);
                CellRect otherRect2 = new CellRect(CastPositionFinder.targetLoc.x - num2, CastPositionFinder.targetLoc.z - num2, num2 * 2 + 1, num2 * 2 + 1);
                cellRect.ClipInsideRect(otherRect2);
                if (CastPositionFinder.req.maxRangeFromLocus > 0.01f)
                {
                    int      num3       = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromLocus);
                    CellRect otherRect3 = new CellRect(CastPositionFinder.targetLoc.x - num3, CastPositionFinder.targetLoc.z - num3, num3 * 2 + 1, num3 * 2 + 1);
                    cellRect.ClipInsideRect(otherRect3);
                }
                CastPositionFinder.bestSpot     = IntVec3.Invalid;
                CastPositionFinder.bestSpotPref = 0.001f;
                CastPositionFinder.maxRangeFromCasterSquared = CastPositionFinder.req.maxRangeFromCaster * CastPositionFinder.req.maxRangeFromCaster;
                CastPositionFinder.maxRangeFromTargetSquared = CastPositionFinder.req.maxRangeFromTarget * CastPositionFinder.req.maxRangeFromTarget;
                CastPositionFinder.maxRangeFromLocusSquared  = CastPositionFinder.req.maxRangeFromLocus * CastPositionFinder.req.maxRangeFromLocus;
                CastPositionFinder.rangeFromTarget           = (CastPositionFinder.req.caster.Position - CastPositionFinder.req.target.Position).LengthHorizontal;
                CastPositionFinder.rangeFromTargetSquared    = (float)(CastPositionFinder.req.caster.Position - CastPositionFinder.req.target.Position).LengthHorizontalSquared;
                CastPositionFinder.optimalRangeSquared       = CastPositionFinder.verb.verbProps.range * 0.8f * (CastPositionFinder.verb.verbProps.range * 0.8f);
                CastPositionFinder.EvaluateCell(CastPositionFinder.req.caster.Position);
                if ((double)CastPositionFinder.bestSpotPref >= 1.0)
                {
                    dest   = CastPositionFinder.req.caster.Position;
                    result = true;
                }
                else
                {
                    float    slope    = -1f / CellLine.Between(CastPositionFinder.req.target.Position, CastPositionFinder.req.caster.Position).Slope;
                    CellLine cellLine = new CellLine(CastPositionFinder.req.target.Position, slope);
                    bool     flag     = cellLine.CellIsAbove(CastPositionFinder.req.caster.Position);
                    Profiler.BeginSample("TryFindCastPosition scan near side");
                    CellRect.CellRectIterator iterator = cellRect.GetIterator();
                    while (!iterator.Done())
                    {
                        IntVec3 c = iterator.Current;
                        if (cellLine.CellIsAbove(c) == flag && cellRect.Contains(c))
                        {
                            CastPositionFinder.EvaluateCell(c);
                        }
                        iterator.MoveNext();
                    }
                    Profiler.EndSample();
                    if (CastPositionFinder.bestSpot.IsValid && CastPositionFinder.bestSpotPref > 0.33f)
                    {
                        dest   = CastPositionFinder.bestSpot;
                        result = true;
                    }
                    else
                    {
                        Profiler.BeginSample("TryFindCastPosition scan far side");
                        CellRect.CellRectIterator iterator2 = cellRect.GetIterator();
                        while (!iterator2.Done())
                        {
                            IntVec3 c2 = iterator2.Current;
                            if (cellLine.CellIsAbove(c2) != flag && cellRect.Contains(c2))
                            {
                                CastPositionFinder.EvaluateCell(c2);
                            }
                            iterator2.MoveNext();
                        }
                        Profiler.EndSample();
                        if (CastPositionFinder.bestSpot.IsValid)
                        {
                            dest   = CastPositionFinder.bestSpot;
                            result = true;
                        }
                        else
                        {
                            dest   = CastPositionFinder.casterLoc;
                            result = false;
                        }
                    }
                }
            }
            return(result);
        }
コード例 #8
0
        // Verse.AI.CastPositionFinder
        public bool TryFindCastPosition(CastPositionRequest req, out IntVec3 dest)
        {
            ByteGrid avoidGrid    = null;
            int      inRadiusMark = 0;

            if (this.pawn.CurJob.verbToUse == null)
            {
                Log.Error(this.pawn + " tried to find casting position without a verb.");
                dest = IntVec3.Invalid;
                return(false);
            }
            if (req.maxRegionsRadius > 0)
            {
                Region region = req.caster.PositionHeld.GetRegion(this.pawn.Map);
                if (region == null)
                {
                    Log.Error("TryFindCastPosition requiring region traversal but root region is null.");
                    dest = IntVec3.Invalid;
                    return(false);
                }
                inRadiusMark = Rand.Int;
                RegionTraverser.MarkRegionsBFS(region, null, req.maxRegionsRadius, inRadiusMark);
                if (req.maxRangeFromLocus > 0.01f)
                {
                    Region region2 = req.locus.GetRegion(this.pawn.Map);
                    if (region2 == null)
                    {
                        Log.Error("locus " + req.locus + " has no region");
                        dest = IntVec3.Invalid;
                        return(false);
                    }
                    if (region2.mark != inRadiusMark)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            req.caster,
                            " can't possibly get to locus ",
                            req.locus,
                            " as it's not in a maxRegionsRadius of ",
                            req.maxRegionsRadius,
                            ". Overriding maxRegionsRadius."
                        }));
                        req.maxRegionsRadius = 0;
                    }
                }
            }
            CellRect cellRect = CellRect.WholeMap(req.caster.Map);

            if (req.maxRangeFromCaster > 0.01f)
            {
                int      numSolo   = Mathf.CeilToInt(req.maxRangeFromCaster);
                CellRect otherRect = new CellRect(this.pawn.PositionHeld.x - numSolo, this.pawn.PositionHeld.z - numSolo, numSolo * 2 + 1, numSolo * 2 + 1);
                cellRect.ClipInsideRect(otherRect);
            }
            int      num2       = Mathf.CeilToInt(req.maxRangeFromTarget);
            CellRect otherRect2 = new CellRect(this.TargetA.Cell.x - num2, this.TargetA.Cell.z - num2, num2 * 2 + 1, num2 * 2 + 1);

            cellRect.ClipInsideRect(otherRect2);
            if (req.maxRangeFromLocus > 0.01f)
            {
                int      numThree   = Mathf.CeilToInt(req.maxRangeFromLocus);
                CellRect otherRect3 = new CellRect(this.TargetA.Cell.x - numThree, this.TargetA.Cell.z - numThree, numThree * 2 + 1, numThree * 2 + 1);
                cellRect.ClipInsideRect(otherRect3);
            }
            IntVec3 bestSpot     = IntVec3.Invalid;
            float   bestSpotPref = 0.001f;
            float   maxRangeFromCasterSquared    = req.maxRangeFromCaster * req.maxRangeFromCaster;
            float   maxRangeFromTargetSquared    = req.maxRangeFromTarget * req.maxRangeFromTarget;
            float   maxRangeFromLocusSquared     = req.maxRangeFromLocus * req.maxRangeFromLocus;
            float   rangeFromTarget              = (req.caster.Position - this.TargetA.Cell).LengthHorizontal;
            float   rangeFromTargetSquared       = (req.caster.Position - this.TargetA.Cell).LengthHorizontalSquared;
            float   rangeFromCasterToCellSquared = 0f;
            float   optimalRangeSquared          = this.pawn.CurJob.verbToUse.verbProps.range * 0.8f * (this.pawn.CurJob.verbToUse.verbProps.range * 0.8f);
            /////////////////// Evaluate Cell method

            IntVec3 c = req.caster.PositionHeld;

            EvaluateCell(c, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark);
            float num = -1f;
            /////////////////// CAST POSITION PREFERENCE
            bool         flag = true;
            List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                if (thing is Fire fire && fire.parent == null)
                {
                    num = -1f;
                    goto MainSequenceTwo;
                }
                if (thing.def.passability == Traversability.PassThroughOnly)
                {
                    flag = false;
                }
            }
            num = 0.3f;
            if (req.caster.kindDef.aiAvoidCover)
            {
                num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map);
            }
            if (req.wantCoverFromTarget)
            {
                num += CoverUtility.CalculateOverallBlockChance(c, this.TargetLocA, req.caster.Map);
            }
            float numTwo = (req.caster.Position - c).LengthHorizontal;

            if (rangeFromTarget > 100f)
            {
                numTwo -= rangeFromTarget - 100f;
                if (numTwo < 0f)
                {
                    numTwo = 0f;
                }
            }
            num *= Mathf.Pow(0.967f, num2);
            float num3 = 1f;
            float rangeFromTargetToCellSquared = (c - this.TargetLocA).LengthHorizontalSquared;
            //rangeFromCasterToCellSquared = (req.target.Position - c).LengthHorizontalSquared;
            float num4 = Mathf.Abs(rangeFromTargetToCellSquared - optimalRangeSquared) / optimalRangeSquared;

            num4  = 1f - num4;
            num4  = 0.7f + 0.3f * num4;
            num3 *= num4;
            if (rangeFromTargetToCellSquared < 25f)
            {
                num3 *= 0.5f;
            }
            num *= num3;
            if (rangeFromCasterToCellSquared > rangeFromTargetSquared)
            {
                num *= 0.4f;
            }
            if (!flag)
            {
                num *= 0.2f;
            }
            ///////////////////////////////////////////////
MainSequenceTwo:
            if (avoidGrid != null)
            {
                byte b = avoidGrid[c];
                num *= Mathf.Max(0.1f, (37f - b) / 37f);
            }
            if (DebugViewSettings.drawCastPositionSearch)
            {
                req.caster.Map.debugDrawer.FlashCell(c, num / 4f, num.ToString("F3"));
            }
            if (num < bestSpotPref)
            {
                goto MainSequence;
            }
            if (!this.pawn.CurJob.verbToUse.CanHitTargetFrom(c, this.TargetLocA))
            {
                if (DebugViewSettings.drawCastPositionSearch)
                {
                    req.caster.Map.debugDrawer.FlashCell(c, 0.6f, "can't hit");
                }
                goto MainSequence;
            }
            if (req.caster.Map.pawnDestinationManager.DestinationIsReserved(c, req.caster))
            {
                if (DebugViewSettings.drawCastPositionSearch)
                {
                    req.caster.Map.debugDrawer.FlashCell(c, num * 0.9f, "resvd");
                }
                goto MainSequence;
            }
            bestSpot     = c;
            bestSpotPref = num;
            /////////////////////////////////////////////////////
MainSequence:
            if (bestSpotPref >= 1.0)
            {
                dest = req.caster.Position;
                return(true);
            }

            float    slope    = -1f / CellLine.Between(this.TargetLocA, req.caster.Position).Slope;
            CellLine cellLine = new CellLine(this.TargetLocA, slope);
            bool     flagTwo  = cellLine.CellIsAbove(req.caster.Position);

            CellRect.CellRectIterator iterator = cellRect.GetIterator();
            while (!iterator.Done())
            {
                IntVec3 current = iterator.Current;
                if (cellLine.CellIsAbove(current) == flagTwo && cellRect.Contains(current))
                {
                    EvaluateCell(current, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark);
                }
                iterator.MoveNext();
            }
            if (bestSpot.IsValid && bestSpotPref > 0.33f)
            {
                dest = bestSpot;
                return(true);
            }
            CellRect.CellRectIterator iterator2 = cellRect.GetIterator();
            while (!iterator2.Done())
            {
                IntVec3 current2 = iterator2.Current;
                if (cellLine.CellIsAbove(current2) != flag && cellRect.Contains(current2))
                {
                    EvaluateCell(current2, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark);
                }
                iterator2.MoveNext();
            }
            if (bestSpot.IsValid)
            {
                dest = bestSpot;
                return(true);
            }
            dest = req.caster.PositionHeld;
            return(false);
        }
コード例 #9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var followAndAttack = new Toil();

            followAndAttack.initAction = delegate()
            {
                var actor  = followAndAttack.actor;
                var curJob = actor.jobs.curJob;
                var thing  = curJob.GetTarget(this.a).Thing;
                var pawn1  = thing as Pawn;
                if (thing != actor.pather.Destination.Thing || (!this.pawn.pather.Moving && !this.pawn.Position.AdjacentTo8WayOrInside(thing)))
                {
                    RoofDef roofDef = actor.Map.roofGrid.RoofAt(actor.Position);
                    if (roofDef != null)
                    {
                        if (roofDef != RoofDefOf.RoofConstructed)
                        {
                            return;
                        }
                        if (!SoundDefHelper.NullOrUndefined(roofDef.soundPunchThrough))
                        {
                            SoundStarter.PlayOneShot(roofDef.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false));
                            CellRect.CellRectIterator iterator = CellRect.CenteredOn(actor.Position, 1).GetIterator();
                            while (!iterator.Done())
                            {
                                Find.CurrentMap.roofGrid.SetRoof(iterator.Current, null);
                                iterator.MoveNext();
                            }
                        }
                    }
                    RoofDef roofDef2 = actor.Map.roofGrid.RoofAt(thing.Position);
                    if (roofDef2 != null)
                    {
                        if (roofDef2 != RoofDefOf.RoofConstructed)
                        {
                            return;
                        }
                        if (!SoundDefHelper.NullOrUndefined(roofDef2.soundPunchThrough))
                        {
                            SoundStarter.PlayOneShot(roofDef2.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false));
                            CellRect.CellRectIterator iterator2 = CellRect.CenteredOn(thing.Position, 1).GetIterator();
                            while (!iterator2.Done())
                            {
                                Find.CurrentMap.roofGrid.SetRoof(iterator2.Current, null);
                                iterator2.MoveNext();
                            }
                        }
                    }
                }
                actor.pather.StartPath(thing, PathEndMode.OnCell);
                actor.Position = thing.Position;
                actor.pather.StopDead();
                pawn1.pather.StopDead();
                pawn1.TakeDamage(new DamageInfo(PurpleIvyDefOf.AlienToxicSting, 3, 0f, -1f, actor, null, null));
                if (actor.jobs.curJob != null)
                {
                    actor.jobs.curDriver.Notify_PatherArrived();
                }
                actor.jobs.TryTakeOrderedJob(PurpleIvyUtils.MeleeAttackJob(actor, pawn1));
            };
            followAndAttack.defaultCompleteMode = ToilCompleteMode.Never;
            followAndAttack.EndOnDespawnedOrNull <Toil>(this.a, JobCondition.Succeeded);
            followAndAttack.FailOn <Toil>(new Func <bool>(this.hunterIsKilled));
            yield return(followAndAttack);

            yield break;
        }
コード例 #10
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);
        }
コード例 #11
0
        public override IEnumerable <IntVec3> PotentialWorkCellsGlobal(Pawn pawn)
        {
            Danger          maxDanger = pawn.NormalMaxDanger();
            List <Building> bList     = pawn.Map.listerBuildings.allBuildingsColonist;

            for (int i = 0; i < bList.Count; i++)
            {
                Building_PlantGrower b = bList[i] as Building_PlantGrower;
                if (b != null)
                {
                    if (this.ExtraRequirements(b, pawn))
                    {
                        if (!b.IsForbidden(pawn))
                        {
                            if (pawn.CanReach(b, PathEndMode.OnCell, maxDanger, false, TraverseMode.ByPawn))
                            {
                                if (!b.IsBurning())
                                {
                                    CellRect.CellRectIterator cri = b.OccupiedRect().GetIterator();
                                    while (!cri.Done())
                                    {
                                        yield return(cri.Current);

                                        cri.MoveNext();
                                    }
                                    WorkGiver_Grower.wantedPlantDef = null;
                                }
                            }
                        }
                    }
                }
            }
            WorkGiver_Grower.wantedPlantDef = null;
            List <Zone> zonesList = pawn.Map.zoneManager.AllZones;

            for (int j = 0; j < zonesList.Count; j++)
            {
                Zone_Growing growZone = zonesList[j] as Zone_Growing;
                if (growZone != null)
                {
                    if (growZone.cells.Count == 0)
                    {
                        Log.ErrorOnce("Grow zone has 0 cells: " + growZone, -563487, false);
                    }
                    else if (this.ExtraRequirements(growZone, pawn))
                    {
                        if (!growZone.ContainsStaticFire)
                        {
                            if (pawn.CanReach(growZone.Cells[0], PathEndMode.OnCell, maxDanger, false, TraverseMode.ByPawn))
                            {
                                for (int k = 0; k < growZone.cells.Count; k++)
                                {
                                    yield return(growZone.cells[k]);
                                }
                                WorkGiver_Grower.wantedPlantDef = null;
                            }
                        }
                    }
                }
            }
            WorkGiver_Grower.wantedPlantDef = null;
        }
コード例 #12
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 ((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.TryGetComp <CompExplosive>();
                    if (compExplosive != null && compExplosive.wickStarted)
                    {
                        return(false);
                    }
                }
                if (thing.def.size.x == 1 && thing.def.size.z == 1)
                {
                    if (thing.Position.Fogged(thing.Map))
                    {
                        return(false);
                    }
                }
                else
                {
                    bool flag2 = false;
                    CellRect.CellRectIterator iterator = thing.OccupiedRect().GetIterator();
                    while (!iterator.Done())
                    {
                        if (!iterator.Current.Fogged(thing.Map))
                        {
                            flag2 = true;
                            break;
                        }
                        iterator.MoveNext();
                    }
                    if (!flag2)
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (ARA_AttackTargetFinder.HasRangedAttack(searcher))
            {
                //Log.Warning("Finder: Range detected. Verb is " + verb);
                //Log.Warning("Finder: Pawn " + searcherPawn.Faction);
                ARA_AttackTargetFinder.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)
                {
                    ARA_AttackTargetFinder.tmpTargets.Add(iTarget);
                }

                if ((byte)(flags & TargetScanFlags.NeedReachable) != 0)
                {
                    Predicate <IAttackTarget> oldValidator = innerValidator;
                    innerValidator = ((IAttackTarget t) => oldValidator(t) && ARA_AttackTargetFinder.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 < ARA_AttackTargetFinder.tmpTargets.Count; i++)
                    {
                        IAttackTarget attackTarget = ARA_AttackTargetFinder.tmpTargets[i];
                        if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && ARA_AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb))
                        {
                            //Log.Warning("Finder: flag is true");
                            flag = true;
                            break;
                        }
                    }
                }

                IAttackTarget result;
                if (flag)
                {
                    //Log.Warning("Finder: FlagTrue result");
                    ARA_AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x));
                    //Log.Warning("Finder: Target Avaliable : " + ARA_AttackTargetFinder.tmpTargets.Count);
                    result = ARA_AttackTargetFinder.GetRandomShootingTargetByScore(ARA_AttackTargetFinder.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) && (ARA_AttackTargetFinder.CanReach(searcherThing, t, canBash) || ARA_AttackTargetFinder.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, ARA_AttackTargetFinder.tmpTargets, maxDist, validator2, null);
                }
                ARA_AttackTargetFinder.tmpTargets.Clear();
                //Log.Warning("Trying to return result " + result);
                return(result);
            }
            //Log.Warning("Returning Null");
            return(null);
        }