示例#1
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            this.UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(null);
            }
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons);

            if (verb == null)
            {
                return(null);
            }

            if (pawn.GetComp <CompWerewolf>() is CompWerewolf w && w.IsWerewolf)
            {
                if (!w.IsTransformed)
                {
                    w.TransformInto(w.HighestLevelForm, false);
                }
            }

            if (verb.verbProps.MeleeRange)
            {
                return(this.MeleeAttackJob(enemyTarget));
            }
            bool flag  = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = verb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if ((flag && flag2 && flag3) || (flag4 && flag3))
            {
                return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
            }
            IntVec3 intVec;

            if (!this.TryFindShootingPosition(pawn, out intVec))
            {
                return(null);
            }
            if (intVec == pawn.Position)
            {
                return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
            }
            Job newJob = new Job(JobDefOf.Goto, intVec)
            {
                expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            };

            pawn.Map.pawnDestinationReservationManager.Reserve(pawn, newJob, intVec);
            return(newJob);
        }
示例#2
0
        public static IntVec3 BestOrderedGotoDestNear(IntVec3 root, Pawn searcher)
        {
            Map map = searcher.Map;
            Predicate <IntVec3> predicate = delegate(IntVec3 c)
            {
                if (!map.pawnDestinationReservationManager.CanReserve(c, searcher, draftedOnly: true) || !c.Standable(map) || !searcher.CanReach(c, PathEndMode.OnCell, Danger.Deadly))
                {
                    return(false);
                }
                List <Thing> thingList = c.GetThingList(map);
                for (int i = 0; i < thingList.Count; i++)
                {
                    Pawn pawn = thingList[i] as Pawn;
                    if (pawn != null && pawn != searcher && pawn.RaceProps.Humanlike && ((searcher.Faction == Faction.OfPlayer && pawn.Faction == searcher.Faction) || (searcher.Faction != Faction.OfPlayer && pawn.Faction != Faction.OfPlayer)))
                    {
                        return(false);
                    }
                }
                return(true);
            };

            if (predicate(root))
            {
                return(root);
            }
            int     num    = 1;
            IntVec3 result = default(IntVec3);
            float   num2   = -1000f;
            bool    flag   = false;
            int     num3   = GenRadial.NumCellsInRadius(30f);

            while (true)
            {
                IntVec3 intVec = root + GenRadial.RadialPattern[num];
                if (predicate(intVec))
                {
                    float num4 = CoverUtility.TotalSurroundingCoverScore(intVec, map);
                    if (num4 > num2)
                    {
                        num2   = num4;
                        result = intVec;
                        flag   = true;
                    }
                }
                if (num >= 8 && flag)
                {
                    break;
                }
                num++;
                if (num >= num3)
                {
                    return(searcher.Position);
                }
            }
            return(result);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                // Log.Message("There is no valid target. Returning null");
                return(null);
            }

            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);

            // Log.Message("allowManualCastWeapons: " + allowManualCastWeapons.ToString());
            // Log.Message("attackVerb: " + verb.ToString());

            if (verb == null)
            {
                Log.Error("pawn " + pawn.Label + " does not have attack verb");
            }
            else if (verb.IsMeleeAttack)
            {
                // Log.Message("verb is melee attack. Passing to RimWorld.JobGiver_Manhunter ...");
            }
            else
            {
                // Log.Message("verb is ranged attack");

                bool isInCover           = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f;
                bool positionIsStandable = pawn.Position.Standable(pawn.Map);
                bool canHitEnemy         = verb.CanHitTarget(enemyTarget);
                bool enemyNear           = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;
                if ((isInCover && positionIsStandable && canHitEnemy) || (enemyNear && canHitEnemy))
                {
                    // Log.Message("Can hit enemy from current position.");
                    return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, true));
                }
                IntVec3 intVec;
                if (!this.TryFindShootingPosition(pawn, out intVec))
                {
                    return(null);
                }
                if (intVec == pawn.Position)
                {
                    return(new Job(JobDefOf.Wait_Combat, VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
                }
                return(new Job(JobDefOf.Goto, intVec)
                {
                    expiryInterval = VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange,
                    checkOverrideOnExpire = true
                });
            }

            return(null);
        }
示例#4
0
        private static IntVec3 GetRestSpot(IntVec3 originCell, Danger maxDanger, Pawn me)
        {
            if (!(me is PawnConverted))
            {
                return(originCell);
            }

            var currentDanger = me.Position.GetDangerFor(me);
            var danger        = (Danger)Math.Max((int)maxDanger, (int)currentDanger);

            Predicate <IntVec3> validator = c => c.Standable() && Find.RoofGrid.Roofed(c) &&
                                            CoverUtility.TotalSurroundingCoverScore(c) > 2.5f && !NextToDoor(c, me) &&
                                            originCell.CanReach(c, PathEndMode.OnCell, TraverseMode.PassDoors, danger);

            if (validator(originCell) && InRange(originCell, me, 20))
            {
                return(originCell);
            }

            for (int i = 0; i < 50; i++)
            {
                Thing thing = GetRandom(Find.ListerBuildings.allBuildingsColonist);

                if (thing == null)
                {
                    thing = GetRandom(Find.ListerBuildings.allBuildingsColonistCombatTargets);
                }
                if (thing == null)
                {
                    thing = GetRandom(Find.ListerPawns.FreeColonists);
                }
                if (thing == null)
                {
                    thing = GetRandom(Find.ListerPawns.ColonistsAndPrisoners);
                }

                if (thing == null)
                {
                    break;
                }
                IntVec3 result;
                if (CellFinder.TryFindRandomCellNear(thing.Position, 10, validator, out result))
                {
                    return(result);
                }
            }

            Predicate <IntVec3> simpleValidator = c => c.Standable() &&
                                                  CoverUtility.TotalSurroundingCoverScore(c) > 1 && !NextToDoor(c, me) &&
                                                  originCell.CanReach(c, PathEndMode.OnCell, TraverseMode.PassDoors, danger);

            IntVec3 randomCell;

            return(CellFinder.TryFindRandomCellNear(originCell, 20, simpleValidator, out randomCell) ? randomCell : originCell);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            this.UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;
            Job   result;

            if (enemyTarget == null)
            {
                result = null;
            }
            else
            {
                bool allowManualCastWeapons = !pawn.IsColonist;
                Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);
                if (verb == null)
                {
                    result = null;
                }
                else if (verb.verbProps.IsMeleeAttack)
                {
                    result = this.MeleeAttackJob(enemyTarget);
                }
                else
                {
                    bool    flag  = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f;
                    bool    flag2 = pawn.Position.Standable(pawn.Map);
                    bool    flag3 = verb.CanHitTarget(enemyTarget);
                    bool    flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;
                    IntVec3 intVec;
                    if ((flag && flag2 && flag3) || (flag4 && flag3))
                    {
                        result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true);
                    }
                    else if (!this.TryFindShootingPosition(pawn, out intVec))
                    {
                        result = null;
                    }
                    else if (intVec == pawn.Position)
                    {
                        result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true);
                    }
                    else
                    {
                        result = new Job(JobDefOf.Goto, intVec)
                        {
                            expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                            checkOverrideOnExpire = true
                        };
                    }
                }
            }
            return(result);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            this.UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(null);
            }
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons);

            if (verb == null)
            {
                return(null);
            }
            if (verb.verbProps.MeleeRange)
            {
                return(this.MeleeAttackJob(enemyTarget));
            }
            bool flag  = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.0099999997764825821;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = verb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if (flag && flag2 && flag3)
            {
                goto IL_00cf;
            }
            if (flag4 && flag3)
            {
                goto IL_00cf;
            }
            IntVec3 intVec = default(IntVec3);

            if (!this.TryFindShootingPosition(pawn, out intVec))
            {
                return(null);
            }
            if (intVec == pawn.Position)
            {
                return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
            }
            Job job = new Job(JobDefOf.Goto, intVec);

            job.expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange;
            job.checkOverrideOnExpire = true;
            return(job);

IL_00cf:
            return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
        }
示例#7
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (HasRangedVerb(pawn))
            {
                Thing pawn2 = this.FindPawnTarget(pawn);
                return(this.RangedAttackJob(pawn, pawn2));
            }
            this.UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(null);
            }
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons);

            if (verb == null)
            {
                return(null);
            }

            if (verb.verbProps.MeleeRange)
            {
                return(this.MeleeAttackJob(enemyTarget));
            }
            bool flag  = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = verb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if ((flag && flag2 && flag3) || (flag4 && flag3))
            {
                return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
            }
            IntVec3 intVec;

            if (!this.TryFindShootingPosition(pawn, out intVec))
            {
                return(null);
            }
            if (intVec == pawn.Position)
            {
                return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true));
            }
            //pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, intVec);
            return(new Job(JobDefOf.Goto, intVec)
            {
                //expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            });
        }
示例#8
0
        public override bool CanContinueTraversing(Pawn caster)
        {
            var enemyTarget = caster.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(invert);
            }

            var cover = CoverUtility.CalculateOverallBlockChance(enemyTarget.Position, caster.Position, caster.Map);

            return((cover >= minCover && cover < maxCover) ^ invert);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(null);
            }
            Pawn pawn2 = enemyTarget as Pawn;

            if (pawn2 != null && pawn2.IsInvisible())
            {
                return(null);
            }
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);

            if (verb == null)
            {
                return(null);
            }
            if (verb.verbProps.IsMeleeAttack)
            {
                return(MeleeAttackJob(enemyTarget));
            }
            bool num   = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f;
            bool flag  = pawn.Position.Standable(pawn.Map) && pawn.Map.pawnDestinationReservationManager.CanReserve(pawn.Position, pawn, pawn.Drafted);
            bool flag2 = verb.CanHitTarget(enemyTarget);
            bool flag3 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if ((num && flag && flag2) || (flag3 && flag2))
            {
                return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true));
            }
            if (!TryFindShootingPosition(pawn, out var dest))
            {
                return(null);
            }
            if (dest == pawn.Position)
            {
                return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true));
            }
            Job job = JobMaker.MakeJob(JobDefOf.Goto, dest);

            job.expiryInterval        = ExpiryInterval_ShooterSucceeded.RandomInRange;
            job.checkOverrideOnExpire = true;
            return(job);
        }
        public override bool CanContinueTraversing(Pawn caster)
        {
            if (caster.mindState.enemyTarget == null)
            {
                return(false);
            }

            float cover = CoverUtility.CalculateOverallBlockChance(caster.mindState.enemyTarget.Position, caster.Position, caster.Map);

            bool result = cover >= minCover && cover < maxCover;

            if (invert)
            {
                return(!result);
            }

            return(result);
        }
        /*
         * public override float GetPriority(Pawn pawn)
         * {
         *  return base.GetPriority(pawn);
         * }
         *
         * public override void ResolveReferences()
         * {
         *  base.ResolveReferences();
         * }
         *
         * public override string ToString()
         * {
         *  return base.ToString();
         * }
         *
         * public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
         * {
         *  return base.TryIssueJobPackage(pawn, jobParams);
         * }
         *
         * protected override void ResolveSubnodes()
         * {
         *  base.ResolveSubnodes();
         * }*/

        protected override Job TryGiveJob(Pawn pawn)
        {
            UpdateEnemyTarget(pawn);
            Thing target = pawn.mindState.enemyTarget;

            if (target == null)
            {
                return(null);
            }

            Verb verb = pawn.TryGetAttackVerb();

            if (verb == null)
            {
                return(null);
            }
            else if (verb.verbProps.MeleeRange)
            {
                return(MeleeAttackJob(target));
            }

            if (((CoverUtility.CalculateOverallBlockChance(pawn.Position, target.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map)) ||
                 (pawn.Position - target.Position).LengthHorizontalSquared < 25) &&
                verb.CanHitTarget(target))
            {
                return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true));
            }

            if (!TryFindShootingPosition(pawn, out IntVec3 intVec))
            {
                return(null);
            }

            if (intVec == pawn.Position)
            {
                return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true));
            }

            Job job = new Job(JobDefOf.Goto, intVec);

            job.expiryInterval        = ExpiryTicks;
            job.checkOverrideOnExpire = true;
            return(job);
        }
示例#12
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            UpdateEnemyTarget(pawn);
            Thing enemyTarget = pawn.mindState.enemyTarget;

            if (enemyTarget == null)
            {
                return(null);
            }
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);

            if (verb == null)
            {
                return(null);
            }
            if (verb.verbProps.IsMeleeAttack)
            {
                return(MeleeAttackJob(enemyTarget));
            }
            bool flag  = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = verb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if ((flag && flag2 && flag3) || (flag4 && flag3))
            {
                return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true));
            }
            if (!TryFindShootingPosition(pawn, out IntVec3 dest))
            {
                return(null);
            }
            if (dest == pawn.Position)
            {
                return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true));
            }
            Job job = new Job(JobDefOf.Goto, dest);

            job.expiryInterval        = ExpiryInterval_ShooterSucceeded.RandomInRange;
            job.checkOverrideOnExpire = true;
            return(job);
        }
        private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            float num = 60f;

            num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);
            if (target.TargetCurrentlyAimingAt == searcher.Thing)
            {
                num += 10f;
            }
            if (searcher.LastAttackedTarget == target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num += 40f;
            }
            num -= CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f;
            if (target is Pawn pawn && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num -= 50f;
            }
            num += PCF_AttackTargetFinder.FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb);
            return(num + PCF_AttackTargetFinder.FriendlyFireConeTargetScoreOffset(target, searcher, verb));
        }
示例#14
0
        private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb)
        {
            float num = 60f;

            num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);
            if (target.TargetCurrentlyAimingAt == (LocalTargetInfo)searcher.Thing)
            {
                num = (float)(num + 10.0);
            }
            if (searcher.LastAttackedTarget == (LocalTargetInfo)target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num = (float)(num + 40.0);
            }
            num = (float)(num - CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10.0);
            Pawn pawn = target as Pawn;

            if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num = (float)(num - 50.0);
            }
            return(num + AttackTargetFinder.FriendlyFireShootingTargetScoreOffset(target, searcher, verb));
        }
示例#15
0
        private static float GetShootingTargetScore(
            IAttackTarget target,
            IAttackTargetSearcher searcher,
            Verb verb)
        {
            float num1 = 60f - Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);

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

            if (target is Pawn pawn && pawn.RaceProps.Animal && (pawn.Faction != null && !pawn.IsFighting()))
            {
                num2 -= 50f;
            }
            return((num2 + FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb) + FriendlyFireConeTargetScoreOffset(target, searcher, verb)) * target.TargetPriorityFactor);
        }
示例#16
0
        /// <summary>
        /// Get target score
        /// </summary>
        /// <param name="target"></param>
        /// <param name="searcher"></param>
        private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher)
        {
            float num = 60f;

            num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f);
            if (target.TargetCurrentlyAimingAt == searcher.Thing)
            {
                num += 10f;
            }
            if (searcher.LastAttackedTarget == target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300)
            {
                num += 40f;
            }
            num -= CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f;
            Pawn pawn = target as Pawn;

            if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting())
            {
                num -= 50f;
            }
            //num += _  - add additional cost based on how close to friendly fire
            return(num * target.TargetPriorityFactor);
        }
示例#17
0
        static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn)
        {
            //Log.Warning("Tame animal job detected");
            if (!pawn.RaceProps.Animal)
            {
                return(true);
            }

            bool hasRangedVerb = false;


            List <Verb> verbList  = pawn.verbTracker.AllVerbs;
            List <Verb> rangeList = new List <Verb>();

            for (int i = 0; i < verbList.Count; i++)
            {
                //Log.Warning("Checkity");
                //It corresponds with verbs anyway
                if (verbList[i].verbProps.range > 1.1f)
                {
                    rangeList.Add(verbList[i]);
                    hasRangedVerb = true;
                }
                //Log.Warning("Added Ranged Verb");
            }

            if (hasRangedVerb == false)
            {
                //Log.Warning("I don't have range verb");
                return(true);
            }
            // this.SetCurMeleeVerb(updatedAvailableVerbsList.RandomElementByWeight((VerbEntry ve) => ve.SelectionWeight).verb);
            Verb rangeVerb = rangeList.RandomElementByWeight((Verb rangeItem) => rangeItem.verbProps.commonality);

            if (rangeVerb == null)
            {
                //Log.Warning("Can't get random range verb");
                return(true);
            }


            Thing enemyTarget = (Thing)AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat, (Predicate <Thing>)(x =>
                                                                                                                                                        x is Pawn || x is Building), 0.0f, rangeVerb.verbProps.range, new IntVec3(), float.MaxValue, false);


            if (enemyTarget == null)
            {
                //Log.Warning("I can't find anything to fight.");
                return(true);
            }

            //Check if enemy directly next to pawn
            if (enemyTarget.Position.DistanceTo(pawn.Position) < rangeVerb.verbProps.minRange)
            {
                //If adjacent melee attack
                if (enemyTarget.Position.AdjacentTo8Way(pawn.Position))
                {
                    __result = new Job(JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                //Only go if I am to be released. This prevent animal running off.
                if (pawn.Faction != null && !pawn.Faction.def.isPlayer)
                {
                    //Log.Warning("This is just here for Giddy-Up compat. I hope.");
                }
                else if (pawn.CanReach(enemyTarget, PathEndMode.Touch, Danger.Deadly, false) && pawn.playerSettings.Master.playerSettings.animalsReleased)
                {
                    //Log.Warning("Melee Attack");
                    __result = new Job(JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            //Log.Warning("got list of ranged verb");

            //Log.Warning("Attempting flag");
            bool flag1 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.00999999977648258;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = rangeVerb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;



            if (flag1 && flag2 && flag3 || flag4 && flag3)
            {
                //Log.Warning("Shooting");
                __result = new Job(DefDatabase <JobDef> .GetNamed("AA_AlphaAnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            IntVec3 dest;
            bool    canShootCondition = false;

            //Log.Warning("Try casting");

            //Animals with training seek cover

            /*
             *                  if (pawn.training.IsCompleted(TrainableDefOf.Release) && (double)verb.verbProps.range > 7.0)
             *                          Log.Warning("Attempting cover");
             *                  Log.Warning("Try get flag radius :" + Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue<float>());
             *                  Log.Warning("Checking cast condition");
             */

            //Don't find new position if animal not released.


            canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster              = pawn,
                target              = enemyTarget,
                verb                = rangeVerb,
                maxRangeFromTarget  = rangeVerb.verbProps.range,
                wantCoverFromTarget = pawn.training.HasLearned(TrainableDefOf.Release) && (double)rangeVerb.verbProps.range > 7.0,
                locus               = pawn.playerSettings.Master.Position,
                maxRangeFromLocus   = Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue <float>(),
                maxRegions          = 50
            }, out dest);

            if (!canShootCondition)
            {
                //Log.Warning("I can't move to shooting position");


                return(true);
            }

            if (dest == pawn.Position)
            {
                //Log.Warning("I will stay here and attack");
                __result = new Job(DefDatabase <JobDef> .GetNamed("AA_AlphaAnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            //Log.Warning("Going to new place");
            __result = new Job(JobDefOf.Goto, (LocalTargetInfo)dest)
            {
                expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            };
            return(false);
        }
示例#18
0
        // Token: 0x06000031 RID: 49 RVA: 0x00002C44 File Offset: 0x00000E44
        protected override Job TryGiveJob(Pawn pawn)
        {
            var state      = (MentalState_Fighter)pawn.MentalState;
            var pawnTarget = state.otherPawn;
            var bellRef    = state.bellRef;
            Job result;
            var fighterTarget = bellRef.getFighter(pawnTarget);

            if (!fighterTarget.isInFight || Rand.Value < 0.5)
            {
                result = new Job(JobDefOf.Wait_Combat)
                {
                    expiryInterval = 10
                };
            }
            else
            {
                if (pawn.TryGetAttackVerb(null) == null)
                {
                    result = null;
                }
                else
                {
                    var primary = pawn.equipment?.Primary;
                    if (bellRef.currentState == Building_Bell.State.fight && pawn.equipment != null && primary == null)
                    {
                        var suitableWeapons = new List <Thing>();
                        foreach (var c in bellRef.GetComp <CompBell>().ValidCells)
                        {
                            var thingList = c.GetThingList(bellRef.Map);
                            foreach (var thing in thingList)
                            {
                                var flag8 = thing.def.IsWeapon && !suitableWeapons.Contains(thing) && thing.Spawned &&
                                            pawn.CanReserve(thing);
                                if (flag8)
                                {
                                    suitableWeapons.Add(thing);
                                }
                            }
                        }

                        Thing weapon      = null;
                        var   maxDistance = 9999;
                        foreach (var t2 in suitableWeapons)
                        {
                            if ((t2.Position - pawn.Position).LengthManhattan >= maxDistance)
                            {
                                continue;
                            }

                            weapon      = t2;
                            maxDistance = (t2.Position - pawn.Position).LengthManhattan;
                        }

                        if (weapon != null)
                        {
                            return(new Job(JobDefOf.Equip, weapon));
                        }
                    }

                    if (pawnTarget == null || !pawn.CanReach(pawnTarget, PathEndMode.ClosestTouch, Danger.Deadly))
                    {
                        result = new Job(JobDefOf.Wait);
                    }
                    else
                    {
                        pawn.mindState.enemyTarget = pawnTarget;
                        pawn.mindState.enemyTarget = pawnTarget;
                        UpdateEnemyTarget(pawn);
                        var enemyTarget = pawn.mindState.enemyTarget;

                        if (enemyTarget == null)
                        {
                            result = null;
                        }
                        else
                        {
                            var allowManualCastWeapons = !pawn.IsColonist;
                            var verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);
                            if (verb == null)
                            {
                                result = null;
                            }
                            else
                            {
                                var isMeleeAttack = verb.verbProps.IsMeleeAttack;
                                if (isMeleeAttack || pawnTarget.Downed)
                                {
                                    result = MeleeAttackJob(enemyTarget);
                                    result.killIncappedTarget = bellRef.toDeath;
                                }
                                else
                                {
                                    if (CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) >
                                        0.01f &&
                                        pawn.Position.Standable(pawn.Map) &&
                                        verb.CanHitTarget(enemyTarget) || (pawn.Position - enemyTarget.Position)
                                        .LengthHorizontalSquared < 25 &&
                                        verb.CanHitTarget(enemyTarget))
                                    {
                                        result = new Job(JobDefOf.AttackStatic, pawnTarget)
                                        {
                                            maxNumMeleeAttacks = 1,
                                            expiryInterval     = Rand.Range(420, 900),
                                            canBash            = true
                                        };
                                    }
                                    else
                                    {
                                        if (!TryFindShootingPosition(pawn, out var intVec))
                                        {
                                            result = null;
                                        }
                                        else
                                        {
                                            if (intVec == pawn.Position)
                                            {
                                                result = new Job(JobDefOf.AttackStatic, pawnTarget)
                                                {
                                                    maxNumMeleeAttacks = 1,
                                                    expiryInterval     = Rand.Range(420, 900),
                                                    canBash            = true
                                                };
                                            }
                                            else
                                            {
                                                result = new Job(JobDefOf.Goto, intVec)
                                                {
                                                    expiryInterval        = ExpiryInterval_ShooterSucceeded.RandomInRange,
                                                    checkOverrideOnExpire = true
                                                };
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
        // Token: 0x06003B77 RID: 15223 RVA: 0x001BFC0C File Offset: 0x001BE00C
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_General.DoAtomic(delegate
            {
                Pawn pawn = this.job.targetA.Thing as Pawn;
                if (pawn != null && pawn.Downed && this.pawn.mindState.duty != null && this.pawn.mindState.duty.attackDownedIfStarving && this.pawn.Starving())
                {
                    this.job.killIncappedTarget = true;
                }
            }));

            yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A));

            //
            yield return(new Toil()
            {
                initAction = () =>
                {
                    Pawn actor = this.GetActor();
                    Vector3 drawPos = actor.DrawPos;
                    var shootLine = new ShootLine(actor.PositionHeld, pawn.PositionHeld);
                    Projectile projectile2 = (Projectile)GenSpawn.Spawn(ThingDef.Named("LotRD_Dragonfireblast"), shootLine.Source, actor.Map, WipeMode.Vanish);
                    if (Rand.Value > 0.9f)
                    {
                        //Log.Message("Miss");
                        int num = Rand.Range(2, 3);
                        int max = GenRadial.NumCellsInRadius(num);
                        int num2 = Rand.Range(0, max);
                        if (num2 > 0)
                        {
                            IntVec3 c = pawn.PositionHeld + GenRadial.RadialPattern[num2];
                            ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                            if (Rand.Chance(0.5f))
                            {
                                projectileHitFlags = ProjectileHitFlags.All;
                            }
                            projectile2.Launch(actor, drawPos, c, pawn, projectileHitFlags, null, null);
                            return;
                        }
                    }
                    var covers = CoverUtility.CalculateCoverGiverSet(job.targetA, actor.Position, actor.Map);
                    covers.TryRandomElementByWeight((CoverInfo c) => c.BlockChance, out CoverInfo coverInfo);
                    ThingDef targetCoverDef = (coverInfo.Thing == null) ? null : coverInfo.Thing.def;

                    if (pawn != null)
                    {
                        projectile2.Launch(actor, drawPos + new Vector3(0, 0, 3), pawn, pawn, ProjectileHitFlags.All, null, targetCoverDef);
                    }
                    else
                    {
                        projectile2.Launch(actor, drawPos + new Vector3(0, 0, 3), shootLine.Dest, pawn, ProjectileHitFlags.All, null, targetCoverDef);
                    }

                    // Sends a wave outwards of flames
                    Vector2 behindVector = pawn.Rotation.AsVector2;
                    var behind = new IntVec3((int)behindVector.x, 0, (int)behindVector.y);
                    int rand = Rand.Range(6, 12);
                    //Log.Message("Pawn position: " + pawn.PositionHeld.x.ToString() + " " + pawn.PositionHeld.z.ToString());
                    for (int i = 0; i < rand; i++)
                    {
                        IntVec3 adjustment = new IntVec3((int)pawn.PositionHeld.x + (int)behind.x + i, pawn.PositionHeld.y, (int)pawn.PositionHeld.z + (int)behind.z + i);
                        //Log.Message("Fire position: " + adjustment.x.ToString() + " " + adjustment.z.ToString());
                        if (!adjustment.IsValid)
                        {
                            continue;
                        }
                        Projectile projectileNew = (Projectile)GenSpawn.Spawn(ThingDef.Named("LotRD_Dragonfireblast"), shootLine.Source, actor.Map, WipeMode.Vanish);
                        var headoffset = (actor.Rotation == Rot4.West) ? -3.75f : 3.75f;
                        projectileNew.Launch(actor, drawPos + new Vector3(0, 0, 1.5f) + new Vector3(actor.Rotation.AsVector2.x + headoffset, 0, actor.Rotation.AsVector2.y), adjustment, pawn, ProjectileHitFlags.All, null, targetCoverDef);
                    }
                }
            });
示例#20
0
        private static float CastPositionPreference(IntVec3 c)
        {
            bool         flag = true;
            List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                Fire  fire  = thing as Fire;
                if (fire != null && fire.parent == null)
                {
                    return(-1f);
                }
                if (thing.def.passability == Traversability.PassThroughOnly)
                {
                    flag = false;
                }
            }
            float num = 0.3f;

            if (req.caster.kindDef.aiAvoidCover)
            {
                num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map);
            }
            if (req.wantCoverFromTarget)
            {
                num += CoverUtility.CalculateOverallBlockChance(c, req.target.Position, req.caster.Map) * 0.55f;
            }
            float num2 = (req.caster.Position - c).LengthHorizontal;

            if (rangeFromTarget > 100f)
            {
                num2 -= rangeFromTarget - 100f;
                if (num2 < 0f)
                {
                    num2 = 0f;
                }
            }
            num *= Mathf.Pow(0.967f, num2);
            float num3 = 1f;

            rangeFromTargetToCellSquared = (c - req.target.Position).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;
            }
            return(num);
        }
        // Token: 0x0600001A RID: 26 RVA: 0x00002810 File Offset: 0x00000A10
        protected override Job TryGiveJob(Pawn pawn)
        {
            bool flag = pawn.playerSettings == null;
            Job  result;

            if (flag)
            {
                result = null;
            }
            else
            {
                bool flag2 = pawn.playerSettings.Master == null;
                if (flag2)
                {
                    result = null;
                }
                else
                {
                    Pawn respectedMaster = pawn.playerSettings.RespectedMaster;
                    bool flag3           = respectedMaster == null;
                    if (flag3)
                    {
                        result = null;
                    }
                    else
                    {
                        this.UpdateEnemyTarget(pawn);
                        Thing enemyTarget = pawn.mindState.enemyTarget;
                        bool  flag4       = enemyTarget == null;
                        if (flag4)
                        {
                            result = null;
                        }
                        else
                        {
                            bool flag5 = !pawn.IsColonist;
                            Verb currentEffectiveVerb = pawn.CurrentEffectiveVerb;
                            bool flag6 = currentEffectiveVerb == null;
                            if (flag6)
                            {
                                result = null;
                            }
                            else
                            {
                                bool isMeleeAttack = currentEffectiveVerb.verbProps.IsMeleeAttack;
                                if (isMeleeAttack)
                                {
                                    result = this.MeleeAttackJob(enemyTarget);
                                }
                                else
                                {
                                    bool flag7 = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f;
                                    bool flag8 = pawn.Position.Standable(pawn.Map);
                                    bool flag9 = flag7 || flag8;
                                    if (flag9)
                                    {
                                        result = new Job(WPJobDefOf.ArtyWaitCombat, JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true);
                                    }
                                    else
                                    {
                                        IntVec3 intVec;
                                        bool    flag10 = !this.TryFindShootingPosition(pawn, out intVec);
                                        if (flag10)
                                        {
                                            result = null;
                                        }
                                        else
                                        {
                                            bool flag11 = intVec == pawn.Position;
                                            if (flag11)
                                            {
                                                result = new Job(WPJobDefOf.ArtyWaitCombat, JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true);
                                            }
                                            else
                                            {
                                                result = new Job(JobDefOf.Goto, intVec)
                                                {
                                                    expiryInterval        = JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                                                    checkOverrideOnExpire = true
                                                };
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
示例#22
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);
        }
示例#23
0
        static bool Prefix(ref JobGiver_Manhunter __instance, ref Job __result, ref Pawn pawn)
        {
            //Log.Warning("Man hunter detected");
            if (!pawn.RaceProps.Animal)
            {
                return(true);
            }

            bool hasRangedVerb = false;

            List <Verb> verbList  = pawn.verbTracker.AllVerbs;
            List <Verb> rangeList = new List <Verb>();

            for (int i = 0; i < verbList.Count; i++)
            {
                //Log.Warning("Checkity");
                //It corresponds with verbs anyway
                if (!verbList[i].verbProps.IsMeleeAttack)
                {
                    rangeList.Add(verbList[i]);
                    hasRangedVerb = true;
                    //Log.Warning("Added Ranged Verb");
                }
            }

            if (hasRangedVerb == false)
            {
                // Log.Warning("I don't have range verb");
                return(true);
            }
            // this.SetCurMeleeVerb(updatedAvailableVerbsList.RandomElementByWeight((VerbEntry ve) => ve.SelectionWeight).verb);
            Verb rangeVerb = rangeList.RandomElementByWeight((Verb rangeItem) => rangeItem.verbProps.commonality);

            if (rangeVerb == null)
            {
                //Log.Warning("Can't get random range verb");
                return(true);
            }

            //Seek enemy in conventional way.
            Thing enemyTarget = (Thing)ARA_AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat | TargetScanFlags.NeedReachable, (Predicate <Thing>)(x =>
                                                                                                                                                                                            x is Pawn || x is Building), 0.0f, 9999, new IntVec3(), float.MaxValue, false);

            //Seek thing hiding in embrasure.
            if (enemyTarget == null)
            {
                enemyTarget = (Thing)ARA_AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat, (Predicate <Thing>)(x =>
                                                                                                                                                          x is Pawn || x is Building), 0.0f, 9999, new IntVec3(), float.MaxValue, false);
            }

            if (enemyTarget == null)
            {
                //Log.Warning("I can't find anything to fight.");
                return(true);
            }

            //Check if enemy directly next to pawn
            if (enemyTarget.Position.DistanceTo(pawn.Position) < rangeVerb.verbProps.minRange)
            {
                //If adjacent melee attack
                if (enemyTarget.Position.AdjacentTo8Way(pawn.Position))
                {
                    __result = new Job(JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                return(true);
            }

            //Log.Warning("got list of ranged verb");
            //Log.Warning("Attempting flag");
            bool flag1 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.00999999977648258;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = rangeVerb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;

            if (flag1 && flag2 && flag3 || flag4 && flag3)
            {
                //Log.Warning("Shooting");
                __result = new Job(DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            IntVec3 dest;
            bool    canShootCondition = false;

            canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster              = pawn,
                target              = enemyTarget,
                verb                = rangeVerb,
                maxRangeFromTarget  = rangeVerb.verbProps.range,
                wantCoverFromTarget = false,
                maxRegions          = 50
            }, out dest);

            if (!canShootCondition)
            {
                //Log.Warning("I can't move to shooting position");

                return(true);
            }

            if (dest == pawn.Position)
            {
                //Log.Warning("I will stay here and attack");
                __result = new Job(DefDatabase <JobDef> .GetNamed("PI_AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            //Log.Warning("Going to new place");
            __result = new Job(JobDefOf.Goto, (LocalTargetInfo)dest)
            {
                expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            };
            return(false);
        }
        static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn)
        {
            //    Log.Warning(string.Format("Tame animal job detected: {0}", pawn.LabelCap));

            if (pawn.RaceProps.Humanlike)
            {
                return(true);
            }
            if (pawn.equipment != null)
            {
                if (pawn.equipment.Primary != null)
                {
                    if (pawn.equipment.PrimaryEq != null)
                    {
                        if (pawn.equipment.PrimaryEq.verbTracker.PrimaryVerb.verbProps.range > 1.5)
                        {
                            return(true);
                        }
                    }
                }
            }
            bool hasRangedVerb = false;


            List <Verb> verbList  = pawn.verbTracker.AllVerbs;
            List <Verb> rangeList = new List <Verb>();

            if (pawn.health.hediffSet.hediffs.Any(x => x.TryGetComp <HediffComp_VerbGiverBETA>() != null))
            {
                List <Hediff> list = pawn.health.hediffSet.hediffs.FindAll(x => x.TryGetComp <HediffComp_VerbGiverBETA>() != null);

                foreach (Hediff item in list)
                {
                    HediffComp_VerbGiverBETA _VerbGiver = item.TryGetComp <HediffComp_VerbGiverBETA>();
                    if (_VerbGiver != null)
                    {
                        for (int i = 0; i < _VerbGiver.verbTracker.AllVerbs.Count; i++)
                        {
                            //    Log.Warning("Checkity");
                            //    Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range));
                            //It corresponds with verbs anyway
                            if (_VerbGiver.verbTracker.AllVerbs[i].verbProps.range > 1.5f)
                            {
                                if (!rangeList.Contains(_VerbGiver.verbTracker.AllVerbs[i]))
                                {
                                    rangeList.Add(_VerbGiver.verbTracker.AllVerbs[i]);
                                    hasRangedVerb = true;
                                }
                            }
                            //Log.Warning("Added Ranged Verb");
                        }
                    }
                }
                if (hasRangedVerb == false)
                {
                    Log.Warning("I don't have range verb");
                    return(true);
                }
            }

            // this.SetCurMeleeVerb(updatedAvailableVerbsList.RandomElementByWeight((VerbEntry ve) => ve.SelectionWeight).verb);

            //    Log.Warning(string.Format("rangeVerbs: {0}", rangeList.Count));
            Verb rangeVerb;

            if (rangeList.Count > 1)
            {
                rangeVerb = rangeList.RandomElementByWeightWithDefault((Verb rangeItem) => rangeItem.verbProps.commonality, 0.5f);
            }
            else if (rangeList.Count == 1)
            {
                rangeVerb = rangeList.First();
            }
            else
            {
                rangeVerb = null;
            }

            if (rangeVerb == null)
            {
                //    Log.Warning("Can't get random range verb");
                return(true);
            }
            else
            {
                //    Log.Warning(string.Format("rangeVerb: {0}, Range Max: {1}, Min: {2}, Burst: {3}, Projectile: {4}", rangeVerb.verbProps.label, rangeVerb.verbProps.range, rangeVerb.verbProps.minRange, rangeVerb.verbProps.burstShotCount, rangeVerb.verbProps.defaultProjectile));
            }


            Thing enemyTarget = (Thing)AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat, (Predicate <Thing>)(x =>
                                                                                                                                                        x is Pawn || x is Building), 0.0f, rangeVerb.verbProps.range, new IntVec3(), float.MaxValue, false);


            if (enemyTarget == null)
            {
                //    Log.Warning("I can't find anything to fight.");
                return(true);
            }
            bool useranged = rangeVerb != null;

            //    Log.Warning(string.Format("useranged: {0}", useranged));
            if (!useranged)
            {
                //If adjacent melee attack
                if (enemyTarget.Position.AdjacentTo8Way(pawn.Position))
                {
                    __result = new Job(RimWorld.JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                //Only go if I am to be released. This prevent animal running off.
                if (pawn.CanReach(enemyTarget, PathEndMode.Touch, Danger.Deadly, false))
                {
                    //    Log.Warning("Melee Attack");
                    __result = new Job(RimWorld.JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            //Log.Warning("got list of ranged verb");

            //    Log.Warning("Attempting flag");
            bool flag1 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.00999999977648258;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = rangeVerb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;



            if (flag1 && flag2 && flag3 || flag4 && flag3)
            {
                __result = new Job(DefDatabase <JobDef> .GetNamed("BETARangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            IntVec3 dest;
            bool    canShootCondition = false;

            canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster              = pawn,
                target              = enemyTarget,
                verb                = rangeVerb,
                maxRangeFromTarget  = rangeVerb.verbProps.range,
                wantCoverFromTarget = (double)rangeVerb.verbProps.range > 7.0,
                locus               = pawn.Position,
                maxRangeFromLocus   = Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue <float>(),
                maxRegions          = 50
            }, out dest);

            if (!canShootCondition)
            {
                //   Log.Warning("I can't move to shooting position");


                return(true);
            }

            if (dest == pawn.Position)
            {
                //   Log.Warning("I will stay here and attack");
                __result = new Job(DefDatabase <JobDef> .GetNamed("BETARangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            //   Log.Warning("Going to new place");
            __result = new Job(RimWorld.JobDefOf.Goto, (LocalTargetInfo)dest)
            {
                expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            };
            return(false);
        }
示例#25
0
        // Token: 0x06000031 RID: 49 RVA: 0x00002C44 File Offset: 0x00000E44
        protected override Job TryGiveJob(Pawn pawn)
        {
            MentalState_Fighter state = (MentalState_Fighter)pawn.MentalState;
            Pawn          pawnTarget  = state.otherPawn;
            Building_Bell bellRef     = state.bellRef;
            Job           result;
            Fighter       fighterTarget = bellRef.getFighter(pawnTarget);

            if (!fighterTarget.isInFight || (double)Rand.Value < 0.5)
            {
                result = new Job(JobDefOf.Wait_Combat)
                {
                    expiryInterval = 10
                };
            }
            else
            {
                if (pawn.TryGetAttackVerb(null, false) == null)
                {
                    result = null;
                }
                else
                {
                    ThingWithComps primary = pawn.equipment != null ? pawn.equipment.Primary : null;
                    if (bellRef.currentState == Building_Bell.State.fight && pawn.equipment != null && primary == null)
                    {
                        List <Thing> suitableWeapons = new List <Thing>();
                        foreach (IntVec3 c in bellRef.GetComp <CompBell>().ValidCells)
                        {
                            List <Thing> thingList = c.GetThingList(bellRef.Map);
                            for (int i = 0; i < thingList.Count; i++)
                            {
                                Thing t     = thingList[i];
                                bool  flag8 = t.def.IsWeapon && !suitableWeapons.Contains(t) && t.Spawned && pawn.CanReserve(t, 1, -1, null, false);
                                if (flag8)
                                {
                                    suitableWeapons.Add(t);
                                }
                            }
                        }
                        Thing weapon      = null;
                        int   maxDistance = 9999;
                        foreach (Thing t2 in suitableWeapons)
                        {
                            if ((t2.Position - pawn.Position).LengthManhattan < maxDistance)
                            {
                                weapon      = t2;
                                maxDistance = (t2.Position - pawn.Position).LengthManhattan;
                            }
                        }
                        if (weapon != null)
                        {
                            return(new Job(JobDefOf.Equip, weapon));
                        }
                    }
                    if (pawnTarget == null || !pawn.CanReach(pawnTarget, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        result = new Job(JobDefOf.Wait);
                    }
                    else
                    {
                        pawn.mindState.enemyTarget = pawnTarget;
                        pawn.mindState.enemyTarget = pawnTarget;
                        this.UpdateEnemyTarget(pawn);
                        Thing enemyTarget = pawn.mindState.enemyTarget;

                        if (enemyTarget == null)
                        {
                            result = null;
                        }
                        else
                        {
                            bool allowManualCastWeapons = !pawn.IsColonist;
                            Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);
                            if (verb == null)
                            {
                                result = null;
                            }
                            else
                            {
                                bool isMeleeAttack = verb.verbProps.IsMeleeAttack;
                                if (isMeleeAttack || pawnTarget.Downed)
                                {
                                    result = this.MeleeAttackJob(enemyTarget);
                                    result.killIncappedTarget = bellRef.toDeath;
                                }
                                else
                                {
                                    if ((
                                            CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f &&
                                            pawn.Position.Standable(pawn.Map) &&
                                            verb.CanHitTarget(enemyTarget)
                                            ) || (
                                            (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25 &&
                                            verb.CanHitTarget(enemyTarget)
                                            ))
                                    {
                                        result = new Job(JobDefOf.AttackStatic, pawnTarget)
                                        {
                                            maxNumMeleeAttacks = 1,
                                            expiryInterval     = Rand.Range(420, 900),
                                            canBash            = true
                                        };
                                    }
                                    else
                                    {
                                        IntVec3 intVec;
                                        if (!this.TryFindShootingPosition(pawn, out intVec))
                                        {
                                            result = null;
                                        }
                                        else
                                        {
                                            if (intVec == pawn.Position)
                                            {
                                                result = new Job(JobDefOf.AttackStatic, pawnTarget)
                                                {
                                                    maxNumMeleeAttacks = 1,
                                                    expiryInterval     = Rand.Range(420, 900),
                                                    canBash            = true
                                                };
                                            }
                                            else
                                            {
                                                result = new Job(JobDefOf.Goto, intVec)
                                                {
                                                    expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                                                    checkOverrideOnExpire = true
                                                };
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(result);
        }
        protected override bool Satisfied(Pawn pawn)
        {
            var coverValue = CoverUtility.TotalSurroundingCoverScore(pawn.Position, pawn.Map);

            return(coverValue >= min);
        }
示例#27
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);
        }
示例#28
0
        protected override void ScatterAt(IntVec3 c, Map map, GenStepParams parms, int stackCount = 1)
        {
            Log.Message("Horrors: Initiating Hive Spawn");
            var noiseArray = new double[map.Size.x, map.Size.z];

            var caveNoise = GeneratePerlinNoiseForCaves(map);

            Log.Message("Horrors: Noise Generated Successfully");

            Log.Message("Horrors: Stepping through noise grid");
            for (var i = 0; i < map.Size.x; i++)
            {
                for (var n = 0; n < map.Size.z; n++)
                {
                    noiseArray[i, n] = caveNoise.layeredNoise(Convert.ToDouble(i) / 10, Convert.ToDouble(n) / 10);
                }
            }

            Log.Message("Horrors: Digging out tunnels");
            for (var i = 0; i < map.Size.x; i++)
            {
                for (var n = 0; n < map.Size.z; n++)
                {
                    var loc = new IntVec3(i, 0, n);

                    if (CoverUtility.TotalSurroundingCoverScore(loc, map) > 0.2)
                    {
                        GenSpawn.Spawn(ThingDef.Named("HorrorWeb"), loc, map);
                    }

                    if (!(noiseArray[i, n] > 0.5))
                    {
                        continue;
                    }

                    if (loc.GetEdifice(map) != null)
                    {
                        loc.GetEdifice(map).Destroy(DestroyMode.KillFinalize);
                    }

                    if (map.fogGrid.IsFogged(loc))
                    {
                        map.fogGrid.Unfog(loc);
                    }

                    // map.terrainGrid.SetTerrain(loc, TerrainDef.Named("FloorWebs"));
                }
            }

            Log.Message("Horrors: Generating Hive Rect");
            var     rect = new CellRect(0, 0, 0, 0);
            Faction faction;

            if (map.info.parent?.Faction == null || map.info.parent.Faction == Faction.OfPlayer)
            {
                faction = Find.FactionManager.RandomEnemyFaction();
            }
            else
            {
                faction = map.info.parent.Faction;
            }

            rect = rect.ExpandedBy(4);

            rect.ClipInsideMap(map);
            var resolveParams = default(ResolveParams);

            resolveParams.rect         = rect;
            resolveParams.faction      = faction;
            BaseGen.globalSettings.map = map;

            Log.Message("Horrors: Validating Spawns");

            bool Validator(IntVec3 p)
            {
                return(DropCellFinder.IsGoodDropSpot(p, map, true, true));
            }

            // Pawns
            var queenPawn = PawnGenerator.GeneratePawn(PawnKindDef.Named("Pirate"), faction);

            Log.Message("Horrors: Spawning Sinkhole");
            CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out var cellReturned);
            GenSpawn.Spawn(ThingDef.Named("SinkHole"), map.Center, map);

            Log.Message("Horrors: Spawning Sinkhole");
            CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned);
            GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map);

            Log.Message("Horrors: Spawning Sinkhole");
            CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned);
            GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map);

            Log.Message("Horrors: Spawning Sinkhole");
            CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned);
            GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map);

            Log.Message("Horrors: Spawning Sinkhole");
            CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned);

            var queen = GenSpawn.Spawn(queenPawn, cellReturned, map);

            var pawnToSpawn = PawnGenerator.GeneratePawn(PawnKindDef.Named("BroodLord"), faction);

            GenSpawn.Spawn(pawnToSpawn, cellReturned, map);
            pawnToSpawn.training.Train(TrainableDefOf.Obedience, (Pawn)queen);
        }
        private static float CastPositionPreference(IntVec3 c)
        {
            bool         flag = true;
            List <Thing> list = CastPositionFinder.req.caster.Map.thingGrid.ThingsListAtFast(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                Fire  fire  = thing as Fire;
                if (fire != null && fire.parent == null)
                {
                    return(-1f);
                }
                if (thing.def.passability == Traversability.PassThroughOnly)
                {
                    flag = false;
                }
            }
            float num = 0.3f;

            if (CastPositionFinder.req.caster.kindDef.aiAvoidCover)
            {
                num = (float)(num + (8.0 - CoverUtility.TotalSurroundingCoverScore(c, CastPositionFinder.req.caster.Map)));
            }
            if (CastPositionFinder.req.wantCoverFromTarget)
            {
                num += CoverUtility.CalculateOverallBlockChance(c, CastPositionFinder.req.target.Position, CastPositionFinder.req.caster.Map);
            }
            float num2 = (CastPositionFinder.req.caster.Position - c).LengthHorizontal;

            if (CastPositionFinder.rangeFromTarget > 100.0)
            {
                num2 = (float)(num2 - (CastPositionFinder.rangeFromTarget - 100.0));
                if (num2 < 0.0)
                {
                    num2 = 0f;
                }
            }
            num *= Mathf.Pow(0.967f, num2);
            float num3 = 1f;

            CastPositionFinder.rangeFromTargetToCellSquared = (float)(c - CastPositionFinder.req.target.Position).LengthHorizontalSquared;
            float num4 = Mathf.Abs(CastPositionFinder.rangeFromTargetToCellSquared - CastPositionFinder.optimalRangeSquared) / CastPositionFinder.optimalRangeSquared;

            num4  = (float)(1.0 - num4);
            num4  = (float)(0.699999988079071 + 0.30000001192092896 * num4);
            num3 *= num4;
            if (CastPositionFinder.rangeFromTargetToCellSquared < 25.0)
            {
                num3 = (float)(num3 * 0.5);
            }
            num *= num3;
            if (CastPositionFinder.rangeFromCasterToCellSquared > CastPositionFinder.rangeFromTargetSquared)
            {
                num = (float)(num * 0.40000000596046448);
            }
            if (!flag)
            {
                num = (float)(num * 0.20000000298023224);
            }
            return(num);
        }