示例#1
0
        // Token: 0x06000034 RID: 52 RVA: 0x0000311C File Offset: 0x0000131C
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Thing enemyTarget            = pawn.mindState.enemyTarget;
            bool  allowManualCastWeapons = !pawn.IsColonist;
            Verb  attackVerb             = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons);
            bool  flag = attackVerb == null;
            bool  result;

            if (flag)
            {
                dest   = IntVec3.Invalid;
                result = false;
            }
            else
            {
                result = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster              = pawn,
                    target              = enemyTarget,
                    verb                = attackVerb,
                    maxRangeFromTarget  = attackVerb.verbProps.range,
                    wantCoverFromTarget = ((double)attackVerb.verbProps.range > 5.0)
                }, out dest);
            }
            return(result);
        }
        //Copy of Verse.AI.Toils_CombatGotoCastPosition
        Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false)
        {
            var toil = new Toil();

            toil.initAction = delegate
            {
                Pawn    actor      = toil.actor;
                Job     curJob     = actor.CurJob;
                Thing   thing      = curJob.GetTarget(targetInd).Thing;
                var     pawnVictim = thing as Pawn;
                IntVec3 intVec;
                if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster = toil.actor,
                    target = thing,
                    verb = curJob.verbToUse,
                    maxRangeFromTarget = ((closeIfDowned && pawnVictim != null && pawnVictim.Downed)
                                          ? Mathf.Min(curJob.verbToUse.verbProps.range, (float)pawnVictim.RaceProps.executionRange)
                                          //The following line is changed
                                            : HuntRangePerBodysize(pawnVictim.RaceProps.baseBodySize, (float)pawnVictim.RaceProps.executionRange, curJob.verbToUse.verbProps.range)),
                    wantCoverFromTarget = false
                }, out intVec))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                toil.actor.pather.StartPath(intVec, PathEndMode.OnCell);
                actor.Map.pawnDestinationReservationManager.Reserve(actor, job, intVec);
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }
示例#3
0
        //Copy of Verse.AI.Toils_CombatGotoCastPosition
        Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false)
        {
            var toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor      = toil.actor;
                Job   curJob     = actor.CurJob;
                Thing thing      = curJob.GetTarget(targetInd).Thing;
                var   pawnVictim = thing as Pawn;

                if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster = toil.actor,
                    target = thing,
                    verb = curJob.verbToUse,
                    maxRangeFromTarget = GetOptimalHuntRange(actor, pawnVictim),
                    wantCoverFromTarget = false
                }, out var intVec))
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                toil.actor.pather.StartPath(intVec, PathEndMode.OnCell);
                actor.Map.pawnDestinationReservationManager.Reserve(actor, job, intVec);
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Thing enemyTarget = pawn.mindState.enemyTarget;
            Verb  verb        = pawn.TryGetAttackVerb(enemyTarget, !pawn.IsColonist);
            bool  result;

            if (verb == null)
            {
                dest   = IntVec3.Invalid;
                result = false;
            }
            else
            {
                result = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster              = pawn,
                    target              = enemyTarget,
                    verb                = verb,
                    maxRangeFromTarget  = 9999f,
                    locus               = (IntVec3)pawn.mindState.duty.focus,
                    maxRangeFromLocus   = pawn.mindState.duty.radius,
                    wantCoverFromTarget = (verb.verbProps.range > 7f)
                }, out dest);
            }
            return(result);
        }
        // Token: 0x06000013 RID: 19 RVA: 0x00002690 File Offset: 0x00000890
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Verb verb = pawn.TryGetAttackVerb(null, !pawn.IsColonist);
            bool flag = verb == null;
            bool result;

            if (flag)
            {
                dest   = IntVec3.Invalid;
                result = false;
            }
            else
            {
                float range = pawn.equipment.PrimaryEq.verbTracker.PrimaryVerb.verbProps.range;
                result = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster              = pawn,
                    target              = pawn.mindState.enemyTarget,
                    verb                = verb,
                    maxRangeFromTarget  = 9999f,
                    locus               = this.GetDefendee(pawn).PositionHeld,
                    maxRangeFromLocus   = this.GetFlagRadius(pawn),
                    wantCoverFromTarget = (verb.verbProps.range > 7f),
                    maxRegions          = 999
                }, out dest);
            }
            return(result);
        }
示例#6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil waitLabel = Toils_General.Label();
            Toil endLabel  = Toils_General.Label();

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil approach = new Toil();

            approach.initAction = delegate
            {
                Job curJob = pawn.jobs.curJob;

                if (pawn == Victim || Victim == null)
                {
                    pawn.pather.StopDead();
                    ReadyForNextToil();
                }
                else
                {
                    CastPositionRequest newReq = default(CastPositionRequest);
                    newReq.caster              = pawn;
                    newReq.target              = Victim;
                    newReq.verb                = curJob.verbToUse;
                    newReq.maxRangeFromTarget  = (!Victim.Downed ? Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, 1.42f) : Mathf.Min(curJob.verbToUse.verbProps.range, Victim.RaceProps.executionRange));
                    newReq.wantCoverFromTarget = false;
                    if (CastPositionFinder.TryFindCastPosition(newReq, out var dest))
                    {
                        pawn.pather.StartPath(dest, PathEndMode.OnCell);
                        pawn.Map.pawnDestinationReservationManager.Reserve(pawn, curJob, dest);
                    }
                    //else if (pawn.PositionHeld.DistanceTo(Victim.PositionHeld) <= waitRange)
                    //{
                    //    pawn.pather.StopDead();
                    //    pawn.jobs.curDriver.JumpToToil(waitLabel);
                    //}
                    else
                    {
                        pawn.pather.StartPath(Victim, PathEndMode.Touch);
                    }
                }
            };
            approach.FailOnDespawnedOrNull(VictimIndex);
            approach.defaultCompleteMode = ToilCompleteMode.Delay;
            approach.defaultDuration     = 60;
            yield return(approach);

            yield return(Toils_Jump.Jump(endLabel));

            yield return(waitLabel);

            yield return(Toils_General.Wait(60));

            yield return(endLabel);
        }
示例#7
0
        // Verse.AI.Toils_Combat
        public Toil GotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor  = toil.actor;
                Job   curJob = actor.jobs.curJob;
                Thing thing  = null;
                Pawn  pawn   = null;
                thing = curJob.GetTarget(targetInd).Thing;
                IntVec3 intVec;
                if (thing != null)
                {
                    pawn = thing as Pawn;
                    if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                    {
                        caster = toil.actor,
                        target = thing,
                        verb = curJob.verbToUse,
                        maxRangeFromTarget = ((closeIfDowned && pawn != null && pawn.Downed) ? Mathf.Min(curJob.verbToUse.verbProps.range, pawn.RaceProps.executionRange) : curJob.verbToUse.verbProps.range),
                        wantCoverFromTarget = false
                    }, out intVec))
                    {
                        toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                }
                else
                {
                    if (!TryFindCastPosition(new CastPositionRequest
                    {
                        caster = toil.actor,
                        target = null,
                        verb = curJob.verbToUse,
                        maxRangeFromTarget = ((closeIfDowned && pawn != null && pawn.Downed) ? Mathf.Min(curJob.verbToUse.verbProps.range, pawn.RaceProps.executionRange) : curJob.verbToUse.verbProps.range),
                        wantCoverFromTarget = false
                    }, out intVec))
                    {
                        toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                }
                toil.actor.pather.StartPath(intVec, PathEndMode.OnCell);
                actor.Map.pawnDestinationManager.ReserveDestinationFor(actor, intVec);
            };
            toil.FailOnDespawnedOrNull(targetInd);
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            return(toil);
        }
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }
            CastPositionRequest newReq = default(CastPositionRequest);

            newReq.caster              = pawn;
            newReq.target              = pawn.mindState.enemyTarget;
            newReq.verb                = verb;
            newReq.maxRangeFromTarget  = verb.verbProps.range;
            newReq.wantCoverFromTarget = (verb.verbProps.range > 5.0);
            return(CastPositionFinder.TryFindCastPosition(newReq, out dest));
        }
示例#9
0
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Verb verb = pawn.TryGetAttackVerb(null, !pawn.IsColonist);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }
            CastPositionRequest newReq = default(CastPositionRequest);

            newReq.caster              = pawn;
            newReq.target              = pawn.mindState.enemyTarget;
            newReq.verb                = verb;
            newReq.maxRangeFromTarget  = 9999f;
            newReq.wantCoverFromTarget = false;
            newReq.maxRegions          = 50;
            return(CastPositionFinder.TryFindCastPosition(newReq, out dest));
        }
示例#10
0
        private bool TryFindShootPosition(Pawn pawn, Thing target, out IntVec3 dest)
        {
            Verb verb = TryGetRangedVerb(pawn);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }

            return(CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster = pawn,
                target = target,
                verb = verb,
                maxRangeFromTarget = verb.verbProps.range,
                wantCoverFromTarget = false
            }, out dest));
        }
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            bool allowManualCastWeapons = !pawn.IsColonist;
            Verb verb = pawn.TryGetAttackVerb(null);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }
            return(CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster = pawn,
                target = pawn.mindState.enemyTarget,
                verb = verb,
                maxRangeFromTarget = verb.verbProps.range,
                wantCoverFromTarget = (verb.verbProps.range > 5f)
            }, out dest));
        }
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Verb verb = pawn.TryGetAttackVerb(!pawn.IsColonist);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }
            CastPositionRequest newReq = default(CastPositionRequest);

            newReq.caster              = pawn;
            newReq.target              = pawn.mindState.enemyTarget;
            newReq.verb                = verb;
            newReq.maxRangeFromTarget  = 9999f;
            newReq.locus               = (IntVec3)pawn.mindState.duty.focus;
            newReq.maxRangeFromLocus   = pawn.mindState.duty.radius;
            newReq.wantCoverFromTarget = (verb.verbProps.range > 7.0);
            return(CastPositionFinder.TryFindCastPosition(newReq, out dest));
        }
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Verb verb = pawn.TryGetAttackVerb(null, !pawn.IsColonist);

            if (verb == null)
            {
                dest = IntVec3.Invalid;
                return(false);
            }
            return(CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster = pawn,
                target = pawn.mindState.enemyTarget,
                verb = verb,
                maxRangeFromTarget = 9999f,
                locus = this.GetDefendee(pawn).PositionHeld,
                maxRangeFromLocus = this.GetFlagRadius(pawn),
                wantCoverFromTarget = (verb.verbProps.range > 7f),
                maxRegions = 50
            }, out dest));
        }
示例#14
0
        // Token: 0x06000458 RID: 1112 RVA: 0x0002C7FC File Offset: 0x0002ABFC
        protected override bool TryFindShootingPosition(Pawn pawn, out IntVec3 dest)
        {
            Thing enemyTarget            = pawn.mindState.enemyTarget;
            int   forceMeleeRange        = 7;
            bool  allowManualCastWeapons = !pawn.IsColonist;
            bool  canReach    = (pawn.CanReach(enemyTarget, PathEndMode.Touch, Danger.Deadly, false));
            bool  meleeRange  = (pawn.Position.InHorDistOf(enemyTarget.Position, forceMeleeRange));
            Pawn  tPawn       = enemyTarget as Pawn;
            bool  targetPawn  = (tPawn != null && tPawn.Awake()) || tPawn == null;
            bool  allowRanged = (Rand.Chance(0.25f) && targetPawn && (canReach && !meleeRange)) || !canReach;
            Verb  verb        = allowRanged ? pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons) : pawn.meleeVerbs.TryGetMeleeVerb(enemyTarget);

            if (verb == null)
            {
                //    Log.Message(string.Format("JobGiver_XenomorphFightEnemies Allow ranged: {0}, Verb: {1}", verb, allowRanged));
                dest = IntVec3.Invalid;
                return(false);
            }
            if (allowRanged)
            {
                return(CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                {
                    caster = pawn,
                    target = enemyTarget,
                    verb = verb,
                    maxRangeFromTarget = verb.verbProps.range,
                    wantCoverFromTarget = true
                }, out dest));
            }
            return(CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster = pawn,
                target = enemyTarget,
                verb = verb,
                maxRangeFromTarget = 1,
                wantCoverFromTarget = false
            }, out dest));
        }
示例#15
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);
        }
示例#16
0
        // Token: 0x06000063 RID: 99 RVA: 0x00004318 File Offset: 0x00002518
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.A);
            var toilInv       = new Toil();
            var toilEquipGoto = new Toil();
            var toilEquip     = new Toil();
            var toilGoto      = new Toil();
            var toilCast      = new Toil();
            var toilTouch     = new Toil();
            var toilBeat      = new Toil();
            var toilBash      = new Toil();
            var HasPrimFE     = false;
            var HasPrimFB     = false;

            if (pawn.equipment.Primary != null)
            {
                if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary))
                {
                    HasPrimFE = true;
                }
                else if (pawn.equipment.Primary.def.defName == FBDefName)
                {
                    HasPrimFB = true;
                }
            }

            if (!HasPrimFE)
            {
                var fb = HasPrimFB;
                toilInv.initAction = delegate
                {
                    var            Swap            = false;
                    ThingWithComps invGearToEquip2 = null;
                    ThingWithComps primToSwap2     = null;
                    Thing          RemoveThing     = null;
                    Thing          BackupThing2    = null;
                    if (pawn.equipment.Primary != null)
                    {
                        primToSwap2 = pawn.equipment.Primary;
                    }

                    foreach (var invThing2 in pawn.inventory.innerContainer)
                    {
                        if (invThing2.def.defName != FEDefName || !FWFoamUtility.HasFEFoam(invThing2))
                        {
                            if (invThing2.def.defName == FBDefName)
                            {
                                BackupThing2 = invThing2;
                            }
                        }
                        else
                        {
                            RemoveThing     = invThing2;
                            invGearToEquip2 = (ThingWithComps)invThing2;
                            if (primToSwap2 != null)
                            {
                                Swap = true;
                            }

                            break;
                        }
                    }

                    if (invGearToEquip2 == null && !fb && BackupThing2 != null)
                    {
                        RemoveThing     = BackupThing2;
                        invGearToEquip2 = (ThingWithComps)BackupThing2;
                        if (primToSwap2 != null)
                        {
                            Swap = true;
                        }
                    }

                    if (invGearToEquip2 == null)
                    {
                        return;
                    }

                    var primDef = "";
                    if (Swap)
                    {
                        primDef = pawn.equipment.Primary.def.defName;
                        pawn.equipment.Remove(pawn.equipment.Primary);
                    }

                    pawn.inventory.innerContainer.Remove(RemoveThing);
                    pawn.equipment.MakeRoomFor(invGearToEquip2);
                    pawn.equipment.AddEquipment(invGearToEquip2);
                    if (Swap)
                    {
                        pawn.inventory.innerContainer.TryAdd(primToSwap2);
                    }

                    if (!Swap)
                    {
                        return;
                    }

                    var returnType = "SI";
                    if (pawn.equipment.Primary.def.defName != FEDefName &&
                        pawn.equipment.Primary.def.defName != FBDefName)
                    {
                        return;
                    }

                    var primary = pawn.equipment.Primary;
                    ((FireWardenData)primary).FWSwapType = returnType;
                    ((FireWardenData)primary).FWPawnID   = pawn.thingIDNumber;
                    ((FireWardenData)primary).FWPrimDef  = primDef;
                    if (!DebugFWData)
                    {
                        return;
                    }

                    var Test      = pawn.equipment.Primary;
                    var debugTest = pawn.Label + " : ";
                    debugTest = debugTest + Test.Label + " : ";
                    debugTest = debugTest + pawn.equipment.Primary.GetType() + " : ";
                    if (((FireWardenData)Test).FWSwapType != null)
                    {
                        debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : ";
                    }
                    else
                    {
                        debugTest += "null : ";
                    }

                    debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : ";
                    if (((FireWardenData)Test).FWPrimDef != null)
                    {
                        debugTest += ((FireWardenData)Test).FWPrimDef;
                    }
                    else
                    {
                        debugTest += "null";
                    }

                    Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false);
                };
                toilInv.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                yield return(toilInv);
            }

            var FWEquipping   = Controller.Settings.EquippingDone;
            var FWSearchRange = (float)Controller.Settings.SearchRange;

            if (FWSearchRange < 25f)
            {
                FWSearchRange = 25f;
            }

            if (FWSearchRange > 75f)
            {
                FWSearchRange = 75f;
            }

            HasPrimFE = false;
            HasPrimFB = false;
            if (pawn.equipment.Primary != null)
            {
                if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary))
                {
                    HasPrimFE = true;
                }
                else if (pawn.equipment.Primary.def.defName == FBDefName)
                {
                    HasPrimFB = true;
                }
            }

            if (!HasPrimFE && !HasPrimFB && FWEquipping)
            {
                ThingWithComps invGearToEquip = null;
                ThingWithComps primToSwap     = null;
                Thing          BackupThing    = null;
                if (pawn.equipment.Primary != null)
                {
                    primToSwap = pawn.equipment.Primary;
                }

                foreach (var invThing in pawn.inventory.innerContainer)
                {
                    if (invThing.def.defName == FEDefName && FWFoamUtility.HasFEFoam(invThing))
                    {
                        invGearToEquip = (ThingWithComps)invThing;
                        if (primToSwap != null)
                        {
                        }

                        break;
                    }

                    if (invThing.def.defName == FBDefName)
                    {
                        BackupThing = invThing;
                    }
                }

                if (invGearToEquip == null && BackupThing != null)
                {
                    invGearToEquip = (ThingWithComps)BackupThing;
                }

                if (invGearToEquip == null)
                {
                    Thing ThingToGrab    = null;
                    var   skip           = Controller.Settings.BrawlerNotOK && pawn.story.traits.HasTrait(TraitDefOf.Brawler);
                    var   traverseParams = TraverseParms.For(pawn);

                    bool validatorFE(Thing t)
                    {
                        return(!t.IsForbidden(pawn) && pawn.CanReserve(t) && FWFoamUtility.HasFEFoam(t) &&
                               !FWFoamUtility.ReplaceFEFoam(t));
                    }

                    bool validatorFB(Thing t)
                    {
                        return(!t.IsForbidden(pawn) && pawn.CanReserve(t));
                    }

                    if (!skip)
                    {
                        var FElist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FEDefName));
                        var FEGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FElist,
                                                                              PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFE);
                        if (FEGrab != null)
                        {
                            ThingToGrab = FEGrab;
                        }
                        else
                        {
                            var FBlist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName));
                            var FBGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist,
                                                                                  PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB);
                            if (FBGrab != null)
                            {
                                ThingToGrab = FBGrab;
                            }
                        }
                    }
                    else
                    {
                        var FBlist2 = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName));
                        var FBGrab2 = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist2,
                                                                               PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB);
                        if (FBGrab2 != null)
                        {
                            ThingToGrab = FBGrab2;
                        }
                    }

                    if (ThingToGrab != null)
                    {
                        toilEquipGoto.initAction = delegate
                        {
                            if (Map.reservationManager.CanReserve(pawn, ThingToGrab))
                            {
                                pawn.Reserve(ThingToGrab, job);
                            }

                            pawn.pather.StartPath(ThingToGrab, PathEndMode.OnCell);
                        };
                        toilEquipGoto.FailOn(ThingToGrab.DestroyedOrNull);
                        toilEquipGoto.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName);
                        toilEquipGoto.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName);
                        toilEquipGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                        yield return(toilEquipGoto);

                        toilEquip.initAction = delegate
                        {
                            var primDeEquip = pawn.equipment.Primary;
                            var primDef     = "N";
                            if (primDeEquip != null)
                            {
                                primDef = pawn.equipment.Primary.def.defName;
                                pawn.equipment.Remove(pawn.equipment.Primary);
                                pawn.inventory.innerContainer.TryAdd(primDeEquip);
                            }

                            var            FWGrabWithComps = (ThingWithComps)ThingToGrab;
                            ThingWithComps FWGrabbed;
                            if (FWGrabWithComps.def.stackLimit > 1 && FWGrabWithComps.stackCount > 1)
                            {
                                FWGrabbed = (ThingWithComps)FWGrabWithComps.SplitOff(1);
                            }
                            else
                            {
                                FWGrabbed = FWGrabWithComps;
                                FWGrabbed.DeSpawn();
                            }

                            pawn.equipment.MakeRoomFor(FWGrabbed);
                            pawn.equipment.AddEquipment(FWGrabbed);
                            var returnType = "EN";
                            if (pawn.equipment.Primary.def.defName != FEDefName &&
                                pawn.equipment.Primary.def.defName != FBDefName)
                            {
                                return;
                            }

                            var primary = pawn.equipment.Primary;
                            ((FireWardenData)primary).FWSwapType = returnType;
                            ((FireWardenData)primary).FWPawnID   = pawn.thingIDNumber;
                            ((FireWardenData)primary).FWPrimDef  = primDef;
                            if (!DebugFWData)
                            {
                                return;
                            }

                            var Test      = pawn.equipment.Primary;
                            var debugTest = pawn.Label + " : ";
                            debugTest = debugTest + Test.Label + " : ";
                            debugTest = debugTest + pawn.equipment.Primary.GetType() + " : ";
                            if ((Test as FireWardenData)?.FWSwapType != null)
                            {
                                debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : ";
                            }
                            else
                            {
                                debugTest += "null : ";
                            }

                            debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : ";
                            if (((FireWardenData)Test).FWPrimDef != null)
                            {
                                debugTest += ((FireWardenData)Test).FWPrimDef;
                            }
                            else
                            {
                                debugTest += "null";
                            }

                            Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false);
                        };
                        toilEquip.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName);
                        toilEquip.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName);
                        toilEquip.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                        yield return(toilEquip);
                    }
                }
            }

            var HasPrimFEEq = pawn.equipment.Primary != null && pawn.equipment.Primary.def.defName == FEDefName &&
                              FWFoamUtility.HasFEFoam(pawn.equipment.Primary);

            if (HasPrimFEEq)
            {
                var FEVerbToUse  = pawn.TryGetAttackVerb(TargetFire);
                var RangeFireExt = 10f;
                if (FEVerbToUse != null)
                {
                    pawn.jobs.curJob.verbToUse = FEVerbToUse;
                    RangeFireExt  = pawn.jobs.curJob.verbToUse.verbProps.range;
                    RangeFireExt *= (float)(Controller.Settings.HowClose / 100.0);
                    if (RangeFireExt < 3f)
                    {
                        RangeFireExt = 3f;
                    }

                    if (RangeFireExt > pawn.jobs.curJob.verbToUse.verbProps.range)
                    {
                        RangeFireExt = pawn.jobs.curJob.verbToUse.verbProps.range;
                    }
                }

                toilGoto.initAction = delegate
                {
                    if (Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                    {
                        caster = pawn,
                        target = TargetFire,
                        verb = pawn.jobs.curJob.verbToUse,
                        maxRangeFromTarget = RangeFireExt,
                        wantCoverFromTarget = false
                    }, out var dest))
                    {
                        toilGoto.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }

                    toilGoto.actor.pather.StartPath(dest, PathEndMode.OnCell);
                    pawn.Map.pawnDestinationReservationManager.Reserve(pawn, pawn.jobs.curJob, dest);
                };
                toilGoto.tickAction = delegate
                {
                    if (Controller.Settings.TooBrave)
                    {
                        return;
                    }

                    if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilCast);
                    }

                    if (pawn.Position != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.Position, toilCast);
                    }
                };
                toilGoto.FailOnDespawnedOrNull(TargetIndex.A);
                toilGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                toilGoto.atomicWithPrevious  = true;
                yield return(toilGoto);

                toilCast.initAction = delegate
                {
                    pawn.jobs.curJob.verbToUse.TryStartCastOn(TargetFire);
                    if (!TargetFire.Destroyed)
                    {
                        return;
                    }

                    pawn.records.Increment(RecordDefOf.FiresExtinguished);
                    pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                };
                toilCast.FailOnDespawnedOrNull(TargetIndex.A);
                toilCast.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                yield return(toilCast);
            }
            else
            {
                toilTouch.initAction = delegate
                {
                    if (Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    pawn.pather.StartPath(TargetFire, PathEndMode.Touch);
                };
                toilTouch.tickAction = delegate
                {
                    if (Controller.Settings.TooBrave)
                    {
                        return;
                    }

                    if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilBeat);
                    }

                    if (pawn.Position != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.Position, toilBeat);
                    }
                };
                toilTouch.FailOnDespawnedOrNull(TargetIndex.A);
                toilTouch.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                toilTouch.atomicWithPrevious  = true;
                yield return(toilTouch);

                toilBeat.tickAction = delegate
                {
                    if (!pawn.CanReachImmediate(TargetFire, PathEndMode.Touch))
                    {
                        JumpToToil(toilTouch);
                        return;
                    }

                    if (pawn.Position != TargetFire.Position && StartTacklingFireIfAnyAt(pawn.Position, toilBeat))
                    {
                        return;
                    }

                    if (pawn.equipment.Primary != null)
                    {
                        if (pawn.equipment.Primary.def.defName == FBDefName)
                        {
                            JumpToToil(toilBash);
                        }
                        else
                        {
                            pawn.natives.TryBeatFire(TargetFire);
                        }
                    }
                    else
                    {
                        pawn.natives.TryBeatFire(TargetFire);
                    }

                    if (!TargetFire.Destroyed)
                    {
                        return;
                    }

                    pawn.records.Increment(RecordDefOf.FiresExtinguished);
                    pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                };
                toilBeat.FailOnDespawnedOrNull(TargetIndex.A);
                toilBeat.defaultCompleteMode = ToilCompleteMode.Never;
                yield return(toilBeat);

                if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.defName != FBDefName)
                {
                    yield break;
                }

                toilBash.initAction = delegate
                {
                    if (TargetFire != null && Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    pawn.pather.StopDead();
                };
                toilBash.handlingFacing = true;
                toilBash.tickAction     = delegate
                {
                    pawn.rotationTracker.FaceTarget(pawn.CurJob.GetTarget(TargetIndex.A));
                    if (TargetFire != null)
                    {
                        pawn.Drawer.Notify_MeleeAttackOn(TargetFire);
                    }
                };
                toilBash.PlaySoundAtStart(SoundDefOf.Interact_BeatFire);
                toilBash.WithProgressBarToilDelay(TargetIndex.A);
                toilBash.AddFinishAction(delegate
                {
                    if (TargetFire != null && !TargetFire.Destroyed)
                    {
                        TargetFire.Destroy();
                    }
                });
                toilBash.FailOnDespawnedOrNull(TargetIndex.A);
                toilBash.defaultCompleteMode = ToilCompleteMode.Delay;
                var ticks     = 50;
                var WorkSpeed = pawn.GetStatValue(StatDefOf.WorkSpeedGlobal);
                if (WorkSpeed <= 0f)
                {
                    WorkSpeed = 1f;
                }

                ticks = (int)(ticks * (1f / WorkSpeed));
                if (ticks < 25)
                {
                    ticks = 25;
                }

                if (ticks > 200)
                {
                    ticks = 200;
                }

                toilBash.defaultDuration = ticks;
                yield return(toilBash);
            }
        }
示例#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
        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);
        }
示例#19
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);
        }
        // Token: 0x06000011 RID: 17 RVA: 0x00002D14 File Offset: 0x00000F14
        private static Toil MarvsGotoCastPosition(TargetIndex targetInd, bool closeIfDowned = false)
        {
            var toil = new Toil();

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

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

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

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

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

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