Esempio n. 1
0
        private static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn)
        {
            bool flag = !pawn.RaceProps.Animal;
            bool result;

            if (flag)
            {
                result = true;
            }
            else
            {
                bool        flag2    = false;
                List <Verb> allVerbs = pawn.verbTracker.AllVerbs;
                List <Verb> list     = new List <Verb>();
                for (int i = 0; i < allVerbs.Count; i++)
                {
                    bool flag3 = allVerbs[i].verbProps.range > 1.1f;
                    if (flag3)
                    {
                        list.Add(allVerbs[i]);
                        flag2 = true;
                    }
                }
                bool flag4 = !flag2;
                if (flag4)
                {
                    result = true;
                }
                else
                {
                    Verb verb  = GenCollection.RandomElementByWeight <Verb>(list, (Verb rangeItem) => rangeItem.verbProps.commonality);
                    bool flag5 = verb == null;
                    if (flag5)
                    {
                        result = true;
                    }
                    else
                    {
                        Thing thing = (Thing)AttackTargetFinder.BestAttackTarget(pawn, TargetScanFlags.NeedThreat, (Thing x) => x is Pawn || x is Building, 0f, verb.verbProps.range, default(IntVec3), float.MaxValue, false, true);
                        bool  flag6 = thing == null;
                        if (flag6)
                        {
                            result = true;
                        }
                        else
                        {
                            bool flag7 = IntVec3Utility.DistanceTo(thing.Position, pawn.Position) < verb.verbProps.minRange;
                            if (flag7)
                            {
                                bool flag8 = GenAdj.AdjacentTo8Way(thing.Position, pawn.Position);
                                if (flag8)
                                {
                                    __result = new Job(JobDefOf.AttackMelee, thing)
                                    {
                                        maxNumMeleeAttacks     = 1,
                                        expiryInterval         = Rand.Range(420, 900),
                                        attackDoorIfTargetLost = false
                                    };
                                    return(false);
                                }
                                bool flag9 = pawn.Faction != null && !pawn.Faction.def.isPlayer;
                                if (!flag9)
                                {
                                    bool flag10 = ReachabilityUtility.CanReach(pawn, thing, PathEndMode.Touch, Danger.Deadly, false, 0) && pawn.playerSettings.Master.playerSettings.animalsReleased;
                                    if (flag10)
                                    {
                                        __result = new Job(JobDefOf.AttackMelee, thing)
                                        {
                                            maxNumMeleeAttacks     = 1,
                                            expiryInterval         = Rand.Range(420, 900),
                                            attackDoorIfTargetLost = false
                                        };
                                        return(false);
                                    }
                                    return(true);
                                }
                            }
                            bool flag11 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, thing.Position, pawn.Map) > 0.00999999977648258;
                            bool flag12 = GenGrid.Standable(pawn.Position, pawn.Map);
                            bool flag13 = verb.CanHitTarget(thing);
                            bool flag14 = (pawn.Position - thing.Position).LengthHorizontalSquared < 25;
                            bool flag15 = (flag11 && flag12 && flag13) || (flag14 && flag13);
                            if (flag15)
                            {
                                JobDef named = DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack", true);

                                LocalTargetInfo localTargetInfo = thing;
                                IntRange        expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded;
                                __result = new Job(named, localTargetInfo, expiryInterval_ShooterSucceeded.RandomInRange, true)
                                {
                                    verbToUse = verb
                                };
                                result = false;
                            }
                            else
                            {
                                CastPositionRequest castPositionRequest = default(CastPositionRequest);
                                castPositionRequest.caster              = pawn;
                                castPositionRequest.target              = thing;
                                castPositionRequest.verb                = verb;
                                castPositionRequest.maxRangeFromTarget  = verb.verbProps.range;
                                castPositionRequest.wantCoverFromTarget = (pawn.training.HasLearned(TrainableDefOf.Release) && (double)verb.verbProps.range > 7.0);
                                castPositionRequest.locus               = pawn.playerSettings.Master.Position;
                                castPositionRequest.maxRangeFromLocus   = Traverse.Create(__instance).Method("GetFlagRadius", new object[]
                                {
                                    pawn
                                }).GetValue <float>();
                                castPositionRequest.maxRegions = 50;
                                IntVec3 intVec = new IntVec3();
                                bool    flag16 = CastPositionFinder.TryFindCastPosition(castPositionRequest, out intVec);
                                bool    flag17 = !flag16;
                                if (flag17)
                                {
                                    result = true;
                                }
                                else
                                {
                                    bool flag18 = intVec == pawn.Position;
                                    if (flag18)
                                    {
                                        JobDef named2 = DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack", true);

                                        LocalTargetInfo localTargetInfo2 = thing;
                                        IntRange        expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded;
                                        __result = new Job(named2, localTargetInfo2, expiryInterval_ShooterSucceeded.RandomInRange, true)
                                        {
                                            verbToUse = verb
                                        };
                                        result = false;
                                    }
                                    else
                                    {
                                        Job      job = new Job(JobDefOf.Goto, intVec);
                                        IntRange expiryInterval_ShooterSucceeded = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded;
                                        job.expiryInterval        = expiryInterval_ShooterSucceeded.RandomInRange;
                                        job.checkOverrideOnExpire = true;
                                        __result = job;
                                        result   = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
Esempio n. 2
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);
        }
        // Token: 0x06000011 RID: 17 RVA: 0x00002D14 File Offset: 0x00000F14
        private static Toil MarvsGotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false)
        {
            var toil = new Toil();

            toil.initAction = delegate
            {
                var actor  = toil.actor;
                var curJob = actor.jobs.curJob;
                var thing  = curJob.GetTarget(targetInd).Thing;
                if (thing is not Pawn pawn)
                {
                    return;
                }

                var curWeatherAccuracyMultiplier = pawn.Map.weatherManager.CurWeatherAccuracyMultiplier;
                var newReq = new CastPositionRequest
                {
                    caster = toil.actor,
                    target = thing,
                    verb   = curJob.verbToUse,
                    wantCoverFromTarget = false
                };
                if (!pawn.Downed && !pawn.Awake() && pawn.def.race.predator)
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                if (closeIfDowned &&
                    (pawn.Downed || Hunting_Loader.settings.shouldApprochSleepers && !pawn.Awake()))
                {
                    newReq.maxRangeFromTarget =
                        Mathf.Min(curJob.verbToUse.verbProps.range, pawn.RaceProps.executionRange);
                }
                else
                {
                    var def = actor.equipment.Primary.def;
                    var num = GetGoodWeaponHuntingRange(def);
                    if (IsPawnTriggerHappy(actor) && !def.IsMeleeWeapon)
                    {
                        num += TriggerHappyRangeReduction;
                    }

                    if (!def.IsMeleeWeapon)
                    {
                        num *= curWeatherAccuracyMultiplier;
                    }

                    var safeHuntingDistance = GetSafeHuntingDistance(pawn);
                    newReq.maxRangeFromTarget = Mathf.Max(num, safeHuntingDistance);
                }

                if (!CastPositionFinder.TryFindCastPosition(newReq, out var intVec))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }
                else
                {
                    if (intVec != toil.actor.Position)
                    {
                        toil.actor.pather.StartPath(intVec, PathEndMode.OnCell);
                        actor.Map.pawnDestinationReservationManager.Reserve(actor, curJob, intVec);
                    }
                    else
                    {
                        toil.actor.pather.StopDead();
                        toil.actor.jobs.curDriver.ReadyForNextToil();
                    }
                }
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }