Exemplo n.º 1
0
        static bool Prefix(ref JobGiver_Manhunter __instance, ref Job __result, ref Pawn pawn)
        {
            //Log.Warning("Detected Animal Attack");

            bool hasRangedVerb = false;



            //Log.Warning("Trying to fire at pawn");

            List <Verb> verbList = pawn.verbTracker.AllVerbs;

            //Log.Warning("Got list of verb");

            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");
            }
            //Log.Warning("got list of ranged verb");



            //If there is no ranged verb just return;
            if (hasRangedVerb == false)
            {
                return(true);
            }

            Verb rangeVerb = rangeList.RandomElementByWeight((Verb rangeItem) => rangeItem.verbProps.commonality);

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

            //Log.Warning("Range verb detected");
            Thing target = (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 (target == null)
            {
                target = (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);
            }
            //Use normal manhunter
            //Can't check for target if it doesn't exist duh

            //Log.Warning("CurrentEffectiveVerb " + pawn.CurrentEffectiveVerb);

            /*
             * Log.Warning("Effective Range " + pawn.CurrentEffectiveVerb.verbProps.range);
             * if (!pawn.CurrentEffectiveVerb.verbProps.MeleeRange)
             * {
             *      Log.Warning("Not melee range");
             * }
             */

            bool  targetInSight = false;
            Thing shootable     = null;

            if (target == null)
            {
                shootable = (Thing)ARA_AttackTargetFinder.BestShootTargetFromCurrentPosition(pawn, (Predicate <Thing>)(x =>
                                                                                                                       x is Pawn || x is Building), rangeVerb.verbProps.range, rangeVerb.verbProps.minRange, TargetScanFlags.NeedThreat | TargetScanFlags.NeedLOSToPawns | TargetScanFlags.LOSBlockableByGas);

                //Log.Warning("Shootable found, " + shootable);
                if (shootable == null)
                {
                    //Log.Warning("No target in line of site");
                    return(true);
                }
                targetInSight = true;
            }
            else if (target.Position.DistanceTo(pawn.Position) < rangeVerb.verbProps.minRange || target.Position.AdjacentTo8Way(pawn.Position))
            {
                //Log.Warning("Target too close, melee!");
                //Core code can't handle animal anymore
                if (pawn.CanReach(target, PathEndMode.Touch, Danger.Deadly, false))
                {
                    //Log.Warning("Melee Attack");
                    __result = new Job(JobDefOf.AttackMelee, target)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                else
                {
                    return(true);
                }
            }


            //Log.Warning("Got target");

            //Formally range attack job
            //if (target != null && pawn.CanReach(target, PathEndMode.Touch, Danger.Deadly, false))


            //Log.Warning("Ranged verb selected, range of  " + verb.verbProps.range);
            IntVec3 intVec;

            //Log.Warning("Trying to shoot");
            //Searches for target within range again.
            if (!targetInSight)
            {
                //Log.Warning("No target");
                shootable = (Thing)ARA_AttackTargetFinder.BestShootTargetFromCurrentPosition(pawn, (Predicate <Thing>)(x =>
                                                                                                                       x is Pawn || x is Building), rangeVerb.verbProps.range, rangeVerb.verbProps.minRange, TargetScanFlags.NeedThreat | TargetScanFlags.NeedLOSToPawns | TargetScanFlags.LOSBlockableByGas);
            }

            if (shootable != null)
            {
                //Log.Warning("Got Shootable");
                if (target.Position.DistanceTo(pawn.Position) < rangeVerb.verbProps.minRange || target.Position.AdjacentTo8Way(pawn.Position))
                {
                    //Log.Warning("Target too close, melee!");
                    //Core code can't handle animal anymore
                    if (pawn.CanReach(target, PathEndMode.Touch, Danger.Deadly, false))
                    {
                        //Log.Warning("Melee Attack");
                        __result = new Job(JobDefOf.AttackMelee, target)
                        {
                            maxNumMeleeAttacks     = 1,
                            expiryInterval         = Rand.Range(420, 900),
                            attackDoorIfTargetLost = false
                        };
                        return(false);
                    }
                    else
                    {
                        //Log.Warning("Target too close and I can't melee right away");
                        return(true);
                    }
                }

                //Log.Warning("Trying initiate job");
                __result = new Job(DefDatabase <JobDef> .GetNamed("AA_AlphaAnimalRangeAttack"), shootable, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                //Log.Warning("Succesfully created job");
                return(false);
            }
            //Target is not null
            if (target != null)
            {
                //Can't shoot at target from current position. Find a new position

                bool canShootCondition = false;
                //Log.Warning("Try casting");
                canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster              = pawn,
                    target              = target,
                    verb                = rangeVerb,
                    maxRangeFromTarget  = 9999,
                    wantCoverFromTarget = false
                }, out intVec);

                if (!canShootCondition)
                {
                    //Log.Warning("Can't find place to shoot at target");
                    return(true);
                }
                //Log.Warning("Going");
                //Go to new destination

                //Protection againt not being able to find target.
                if (pawn.Position == intVec)
                {
                    //Log.Warning(pawn + " already at position to shoot, but target not selected to shoot.");
                    __result = new Job(JobDefOf.Wait, 100);
                    return(false);
                }

                __result = new Job(JobDefOf.Goto, intVec)
                {
                    expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                    checkOverrideOnExpire = true
                };
                return(false);
            }
            //Log.Warning("Hit end condition");
            return(true);
        }
Exemplo n.º 2
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);
        }