public static bool TryFindCastPosition(CastPositionRequest newReq, out IntVec3 dest)
        {
            req       = newReq;
            casterLoc = req.caster.Position;
            targetLoc = req.target.Position;
            verb      = req.verb;
            avoidGrid = newReq.caster.GetAvoidGrid(onlyIfLordAllows: false);
            if (verb == null)
            {
                Log.Error(req.caster + " tried to find casting position without a verb.");
                dest = IntVec3.Invalid;
                return(false);
            }
            if (req.maxRegions > 0)
            {
                Region region = casterLoc.GetRegion(req.caster.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, newReq.maxRegions, inRadiusMark);
                if (req.maxRangeFromLocus > 0.01f)
                {
                    Region locusReg = req.locus.GetRegion(req.caster.Map);
                    if (locusReg == null)
                    {
                        Log.Error("locus " + req.locus + " has no region");
                        dest = IntVec3.Invalid;
                        return(false);
                    }
                    if (locusReg.mark != inRadiusMark)
                    {
                        inRadiusMark = Rand.Int;
                        RegionTraverser.BreadthFirstTraverse(region, null, delegate(Region r)
                        {
                            r.mark = inRadiusMark;
                            req.maxRegions++;
                            return(r == locusReg);
                        });
                    }
                }
            }
            CellRect cellRect = CellRect.WholeMap(req.caster.Map);

            if (req.maxRangeFromCaster > 0.01f)
            {
                int      num       = Mathf.CeilToInt(req.maxRangeFromCaster);
                CellRect otherRect = new CellRect(casterLoc.x - num, casterLoc.z - num, num * 2 + 1, num * 2 + 1);
                cellRect.ClipInsideRect(otherRect);
            }
            int      num2       = Mathf.CeilToInt(req.maxRangeFromTarget);
            CellRect otherRect2 = new CellRect(targetLoc.x - num2, targetLoc.z - num2, num2 * 2 + 1, num2 * 2 + 1);

            cellRect.ClipInsideRect(otherRect2);
            if (req.maxRangeFromLocus > 0.01f)
            {
                int      num3       = Mathf.CeilToInt(req.maxRangeFromLocus);
                CellRect otherRect3 = new CellRect(targetLoc.x - num3, targetLoc.z - num3, num3 * 2 + 1, num3 * 2 + 1);
                cellRect.ClipInsideRect(otherRect3);
            }
            bestSpot     = IntVec3.Invalid;
            bestSpotPref = 0.001f;
            maxRangeFromCasterSquared = req.maxRangeFromCaster * req.maxRangeFromCaster;
            maxRangeFromTargetSquared = req.maxRangeFromTarget * req.maxRangeFromTarget;
            maxRangeFromLocusSquared  = req.maxRangeFromLocus * req.maxRangeFromLocus;
            rangeFromTarget           = (req.caster.Position - req.target.Position).LengthHorizontal;
            rangeFromTargetSquared    = (req.caster.Position - req.target.Position).LengthHorizontalSquared;
            optimalRangeSquared       = verb.verbProps.range * 0.8f * (verb.verbProps.range * 0.8f);
            EvaluateCell(req.caster.Position);
            if ((double)bestSpotPref >= 1.0)
            {
                dest = req.caster.Position;
                return(true);
            }
            float    slope    = -1f / CellLine.Between(req.target.Position, req.caster.Position).Slope;
            CellLine cellLine = new CellLine(req.target.Position, slope);
            bool     flag     = cellLine.CellIsAbove(req.caster.Position);

            foreach (IntVec3 item in cellRect)
            {
                if (cellLine.CellIsAbove(item) == flag && cellRect.Contains(item))
                {
                    EvaluateCell(item);
                }
            }
            if (bestSpot.IsValid && bestSpotPref > 0.33f)
            {
                dest = bestSpot;
                return(true);
            }
            foreach (IntVec3 item2 in cellRect)
            {
                if (cellLine.CellIsAbove(item2) != flag && cellRect.Contains(item2))
                {
                    EvaluateCell(item2);
                }
            }
            if (bestSpot.IsValid)
            {
                dest = bestSpot;
                return(true);
            }
            dest = casterLoc;
            return(false);
        }
        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();
            if (CastPositionFinder.verb == null)
            {
                Log.Error(CastPositionFinder.req.caster + " tried to find casting position without a verb.");
                dest = IntVec3.Invalid;
                return(false);
            }
            if (CastPositionFinder.req.maxRegionsRadius > 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.");
                    dest = IntVec3.Invalid;
                    return(false);
                }
                CastPositionFinder.inRadiusMark = Rand.Int;
                RegionTraverser.MarkRegionsBFS(region, null, newReq.maxRegionsRadius, CastPositionFinder.inRadiusMark, RegionType.Set_Passable);
                if (CastPositionFinder.req.maxRangeFromLocus > 0.01f)
                {
                    Region region2 = CastPositionFinder.req.locus.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable);
                    if (region2 == null)
                    {
                        Log.Error("locus " + CastPositionFinder.req.locus + " has no region");
                        dest = IntVec3.Invalid;
                        return(false);
                    }
                    if (region2.mark != CastPositionFinder.inRadiusMark)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            CastPositionFinder.req.caster,
                            " can't possibly get to locus ",
                            CastPositionFinder.req.locus,
                            " as it's not in a maxRegionsRadius of ",
                            CastPositionFinder.req.maxRegionsRadius,
                            ". Overriding maxRegionsRadius."
                        }));
                        CastPositionFinder.req.maxRegionsRadius = 0;
                    }
                }
            }
            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;
                return(true);
            }
            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);

            CellRect.CellRectIterator iterator = cellRect.GetIterator();
            while (!iterator.Done())
            {
                IntVec3 current = iterator.Current;
                if (cellLine.CellIsAbove(current) == flag && cellRect.Contains(current))
                {
                    CastPositionFinder.EvaluateCell(current);
                }
                iterator.MoveNext();
            }
            if (CastPositionFinder.bestSpot.IsValid && CastPositionFinder.bestSpotPref > 0.33f)
            {
                dest = CastPositionFinder.bestSpot;
                return(true);
            }
            CellRect.CellRectIterator iterator2 = cellRect.GetIterator();
            while (!iterator2.Done())
            {
                IntVec3 current2 = iterator2.Current;
                if (cellLine.CellIsAbove(current2) != flag && cellRect.Contains(current2))
                {
                    CastPositionFinder.EvaluateCell(current2);
                }
                iterator2.MoveNext();
            }
            if (CastPositionFinder.bestSpot.IsValid)
            {
                dest = CastPositionFinder.bestSpot;
                return(true);
            }
            dest = CastPositionFinder.casterLoc;
            return(false);
        }
        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);
        }
Exemple #4
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);
        }
        private void TryAddWall(Sketch sketch, IntVec2 size)
        {
            for (int i = 0; i < 50; i++)
            {
                if (Rand.Chance(0.8f))
                {
                    bool     @bool = Rand.Bool;
                    int      num   = (@bool ? size.x : size.z);
                    CellRect rect2;
                    if (!@bool)
                    {
                        IntVec2 intVec = new IntVec2(Rand.Bool ? (size.x - 1) : 0, 0);
                        rect2 = new CellRect(intVec.x, intVec.z, 1, num);
                    }
                    else
                    {
                        IntVec2 intVec2 = new IntVec2(1, Rand.Bool ? (size.z - 1) : 0);
                        rect2 = new CellRect(intVec2.x, intVec2.z, num - 1, 1);
                    }
                    rect2.ClipInsideRect(new CellRect(0, 0, size.x, size.z));
                    if (rect2.Area >= 3 && WallRectIsUsable(rect2, checkAdjacentCells: false))
                    {
                        GenerateWallInRect(rect2, Rand.Bool);
                        break;
                    }
                    continue;
                }
                IntVec3  intVec3 = new IntVec3(Rand.RangeInclusive(0, size.x - 1), 0, Rand.RangeInclusive(0, size.z - 1));
                int      num2    = GenMath.RoundRandom(Rand.Range((float)size.x * 0.4f, size.x));
                CellRect rect3   = (Rand.Bool ? new CellRect(intVec3.x, intVec3.z, num2, 1) : new CellRect(intVec3.x - num2 + 1, intVec3.z, num2, 1));
                rect3.ClipInsideRect(new CellRect(0, 0, size.x, size.z));
                if (rect3.Area >= 2)
                {
                    int      num3  = GenMath.RoundRandom(Rand.Range((float)size.z * 0.4f, size.z));
                    CellRect rect4 = (Rand.Bool ? new CellRect(intVec3.x, intVec3.z, 1, num3) : new CellRect(intVec3.x, intVec3.z - num3 + 1, 1, num3));
                    rect4.ClipInsideRect(new CellRect(0, 0, size.x, size.z));
                    if (rect4.Area >= 2 && WallRectIsUsable(rect3, checkAdjacentCells: true) && WallRectIsUsable(rect4, checkAdjacentCells: true))
                    {
                        GenerateWallInRect(rect3, createRandomGap: false);
                        GenerateWallInRect(rect4, createRandomGap: false);
                        break;
                    }
                }
            }
            void GenerateWallInRect(CellRect rect, bool createRandomGap)
            {
                IntVec3 randomCell = rect.RandomCell;

                foreach (IntVec3 item in rect)
                {
                    if (!createRandomGap || !(item == randomCell))
                    {
                        sketch.AddThing(ThingDefOf.Wall, item, Rot4.North, ThingDefOf.Steel);
                    }
                }
            }

            bool WallRectIsUsable(CellRect rect, bool checkAdjacentCells)
            {
                foreach (IntVec3 item2 in rect)
                {
                    if (checkAdjacentCells)
                    {
                        for (int j = 0; j < 9; j++)
                        {
                            IntVec3 pos = item2 + GenAdj.AdjacentCellsAndInside[j];
                            if (sketch.EdificeAt(pos) != null)
                            {
                                return(false);
                            }
                        }
                    }
                    else if (sketch.EdificeAt(item2) != null)
                    {
                        return(false);
                    }
                }
                return(true);
            }
        }