protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(null); if (verb == null) { return(null); } if (pawn.GetComp <CompWerewolf>() is CompWerewolf w && w.IsWerewolf) { if (!w.IsTransformed && w.IsBlooded) { w.TransformInto(w.HighestLevelForm, false); } } if (verb.verbProps.IsMeleeAttack) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } Job newJob = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; pawn.Map.pawnDestinationReservationManager.Reserve(pawn, newJob, intVec); return(newJob); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); var enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } _ = !pawn.IsColonist; var verb = pawn.TryGetAttackVerb(null); if (verb == null) { return(null); } if (pawn.GetComp <CompWerewolf>() is { IsWerewolf : true } w) { if (!w.IsTransformed && w.IsBlooded) { w.TransformInto(w.HighestLevelForm); } } if (verb.verbProps.IsMeleeAttack) { return(MeleeAttackJob(enemyTarget)); } if (CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map) && verb.CanHitTarget(enemyTarget) || (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25 && verb.CanHitTarget(enemyTarget)) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } if (!TryFindShootingPosition(pawn, out var intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } var newJob = new Job(JobDefOf.Goto, intVec) { expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; pawn.Map.pawnDestinationReservationManager.Reserve(pawn, newJob, intVec); return(newJob); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { // Log.Message("There is no valid target. Returning null"); return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); // Log.Message("allowManualCastWeapons: " + allowManualCastWeapons.ToString()); // Log.Message("attackVerb: " + verb.ToString()); if (verb == null) { Log.Error("pawn " + pawn.Label + " does not have attack verb"); } else if (verb.IsMeleeAttack) { // Log.Message("verb is melee attack. Passing to RimWorld.JobGiver_Manhunter ..."); } else { // Log.Message("verb is ranged attack"); bool isInCover = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool positionIsStandable = pawn.Position.Standable(pawn.Map); bool canHitEnemy = verb.CanHitTarget(enemyTarget); bool enemyNear = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((isInCover && positionIsStandable && canHitEnemy) || (enemyNear && canHitEnemy)) { // Log.Message("Can hit enemy from current position."); return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } return(new Job(JobDefOf.Goto, intVec) { expiryInterval = VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }); } return(null); }
protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; Job result; if (enemyTarget == null) { result = null; } else { bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { result = null; } else if (verb.verbProps.IsMeleeAttack) { result = this.MeleeAttackJob(enemyTarget); } else { bool flag = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; IntVec3 intVec; if ((flag && flag2 && flag3) || (flag4 && flag3)) { result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else if (!this.TryFindShootingPosition(pawn, out intVec)) { result = null; } else if (intVec == pawn.Position) { result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } return(result); }
protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.MeleeRange) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.0099999997764825821; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if (flag && flag2 && flag3) { goto IL_00cf; } if (flag4 && flag3) { goto IL_00cf; } IntVec3 intVec = default(IntVec3); if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } Job job = new Job(JobDefOf.Goto, intVec); job.expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); IL_00cf: return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); }
protected override Job TryGiveJob(Pawn pawn) { if (HasRangedVerb(pawn)) { Thing pawn2 = this.FindPawnTarget(pawn); return(this.RangedAttackJob(pawn, pawn2)); } this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.MeleeRange) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } //pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, intVec); return(new Job(JobDefOf.Goto, intVec) { //expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }); }
public override bool CanContinueTraversing(Pawn caster) { var enemyTarget = caster.mindState.enemyTarget; if (enemyTarget == null) { return(invert); } var cover = CoverUtility.CalculateOverallBlockChance(enemyTarget.Position, caster.Position, caster.Map); return((cover >= minCover && cover < maxCover) ^ invert); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } Pawn pawn2 = enemyTarget as Pawn; if (pawn2 != null && pawn2.IsInvisible()) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.IsMeleeAttack) { return(MeleeAttackJob(enemyTarget)); } bool num = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag = pawn.Position.Standable(pawn.Map) && pawn.Map.pawnDestinationReservationManager.CanReserve(pawn.Position, pawn, pawn.Drafted); bool flag2 = verb.CanHitTarget(enemyTarget); bool flag3 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((num && flag && flag2) || (flag3 && flag2)) { return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } if (!TryFindShootingPosition(pawn, out var dest)) { return(null); } if (dest == pawn.Position) { return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } Job job = JobMaker.MakeJob(JobDefOf.Goto, dest); job.expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); }
public override bool CanContinueTraversing(Pawn caster) { if (caster.mindState.enemyTarget == null) { return(false); } float cover = CoverUtility.CalculateOverallBlockChance(caster.mindState.enemyTarget.Position, caster.Position, caster.Map); bool result = cover >= minCover && cover < maxCover; if (invert) { return(!result); } return(result); }
/* * public override float GetPriority(Pawn pawn) * { * return base.GetPriority(pawn); * } * * public override void ResolveReferences() * { * base.ResolveReferences(); * } * * public override string ToString() * { * return base.ToString(); * } * * public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) * { * return base.TryIssueJobPackage(pawn, jobParams); * } * * protected override void ResolveSubnodes() * { * base.ResolveSubnodes(); * }*/ protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing target = pawn.mindState.enemyTarget; if (target == null) { return(null); } Verb verb = pawn.TryGetAttackVerb(); if (verb == null) { return(null); } else if (verb.verbProps.MeleeRange) { return(MeleeAttackJob(target)); } if (((CoverUtility.CalculateOverallBlockChance(pawn.Position, target.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map)) || (pawn.Position - target.Position).LengthHorizontalSquared < 25) && verb.CanHitTarget(target)) { return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true)); } if (!TryFindShootingPosition(pawn, out IntVec3 intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true)); } Job job = new Job(JobDefOf.Goto, intVec); job.expiryInterval = ExpiryTicks; job.checkOverrideOnExpire = true; return(job); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.IsMeleeAttack) { return(MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } if (!TryFindShootingPosition(pawn, out IntVec3 dest)) { return(null); } if (dest == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } Job job = new Job(JobDefOf.Goto, dest); job.expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); }
private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { float num = 60f; num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f); if (target.TargetCurrentlyAimingAt == searcher.Thing) { num += 10f; } if (searcher.LastAttackedTarget == target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300) { num += 40f; } num -= CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f; if (target is Pawn pawn && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting()) { num -= 50f; } num += PCF_AttackTargetFinder.FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb); return(num + PCF_AttackTargetFinder.FriendlyFireConeTargetScoreOffset(target, searcher, verb)); }
private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { float num = 60f; num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f); if (target.TargetCurrentlyAimingAt == (LocalTargetInfo)searcher.Thing) { num = (float)(num + 10.0); } if (searcher.LastAttackedTarget == (LocalTargetInfo)target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300) { num = (float)(num + 40.0); } num = (float)(num - CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10.0); Pawn pawn = target as Pawn; if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting()) { num = (float)(num - 50.0); } return(num + AttackTargetFinder.FriendlyFireShootingTargetScoreOffset(target, searcher, verb)); }
private static float GetShootingTargetScore( IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { float num1 = 60f - Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f); if (target.TargetCurrentlyAimingAt == (LocalTargetInfo)searcher.Thing) { num1 += 10f; } if (searcher.LastAttackedTarget == (LocalTargetInfo)target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300) { num1 += 40f; } float num2 = num1 - CoverUtility.CalculateOverallBlockChance((LocalTargetInfo)target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f; if (target is Pawn pawn && pawn.RaceProps.Animal && (pawn.Faction != null && !pawn.IsFighting())) { num2 -= 50f; } return((num2 + FriendlyFireBlastRadiusTargetScoreOffset(target, searcher, verb) + FriendlyFireConeTargetScoreOffset(target, searcher, verb)) * target.TargetPriorityFactor); }
/// <summary> /// Get target score /// </summary> /// <param name="target"></param> /// <param name="searcher"></param> private static float GetShootingTargetScore(IAttackTarget target, IAttackTargetSearcher searcher) { float num = 60f; num -= Mathf.Min((target.Thing.Position - searcher.Thing.Position).LengthHorizontal, 40f); if (target.TargetCurrentlyAimingAt == searcher.Thing) { num += 10f; } if (searcher.LastAttackedTarget == target.Thing && Find.TickManager.TicksGame - searcher.LastAttackTargetTick <= 300) { num += 40f; } num -= CoverUtility.CalculateOverallBlockChance(target.Thing.Position, searcher.Thing.Position, searcher.Thing.Map) * 10f; Pawn pawn = target as Pawn; if (pawn != null && pawn.RaceProps.Animal && pawn.Faction != null && !pawn.IsFighting()) { num -= 50f; } //num += _ - add additional cost based on how close to friendly fire return(num * target.TargetPriorityFactor); }
// Token: 0x06000031 RID: 49 RVA: 0x00002C44 File Offset: 0x00000E44 protected override Job TryGiveJob(Pawn pawn) { var state = (MentalState_Fighter)pawn.MentalState; var pawnTarget = state.otherPawn; var bellRef = state.bellRef; Job result; var fighterTarget = bellRef.getFighter(pawnTarget); if (!fighterTarget.isInFight || Rand.Value < 0.5) { result = new Job(JobDefOf.Wait_Combat) { expiryInterval = 10 }; } else { if (pawn.TryGetAttackVerb(null) == null) { result = null; } else { var primary = pawn.equipment?.Primary; if (bellRef.currentState == Building_Bell.State.fight && pawn.equipment != null && primary == null) { var suitableWeapons = new List <Thing>(); foreach (var c in bellRef.GetComp <CompBell>().ValidCells) { var thingList = c.GetThingList(bellRef.Map); foreach (var thing in thingList) { var flag8 = thing.def.IsWeapon && !suitableWeapons.Contains(thing) && thing.Spawned && pawn.CanReserve(thing); if (flag8) { suitableWeapons.Add(thing); } } } Thing weapon = null; var maxDistance = 9999; foreach (var t2 in suitableWeapons) { if ((t2.Position - pawn.Position).LengthManhattan >= maxDistance) { continue; } weapon = t2; maxDistance = (t2.Position - pawn.Position).LengthManhattan; } if (weapon != null) { return(new Job(JobDefOf.Equip, weapon)); } } if (pawnTarget == null || !pawn.CanReach(pawnTarget, PathEndMode.ClosestTouch, Danger.Deadly)) { result = new Job(JobDefOf.Wait); } else { pawn.mindState.enemyTarget = pawnTarget; pawn.mindState.enemyTarget = pawnTarget; UpdateEnemyTarget(pawn); var enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { result = null; } else { var allowManualCastWeapons = !pawn.IsColonist; var verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { result = null; } else { var isMeleeAttack = verb.verbProps.IsMeleeAttack; if (isMeleeAttack || pawnTarget.Downed) { result = MeleeAttackJob(enemyTarget); result.killIncappedTarget = bellRef.toDeath; } else { if (CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map) && verb.CanHitTarget(enemyTarget) || (pawn.Position - enemyTarget.Position) .LengthHorizontalSquared < 25 && verb.CanHitTarget(enemyTarget)) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { if (!TryFindShootingPosition(pawn, out var intVec)) { result = null; } else { if (intVec == pawn.Position) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } } } } } } } return(result); }
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); }
// Token: 0x0600001A RID: 26 RVA: 0x00002810 File Offset: 0x00000A10 protected override Job TryGiveJob(Pawn pawn) { bool flag = pawn.playerSettings == null; Job result; if (flag) { result = null; } else { bool flag2 = pawn.playerSettings.Master == null; if (flag2) { result = null; } else { Pawn respectedMaster = pawn.playerSettings.RespectedMaster; bool flag3 = respectedMaster == null; if (flag3) { result = null; } else { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; bool flag4 = enemyTarget == null; if (flag4) { result = null; } else { bool flag5 = !pawn.IsColonist; Verb currentEffectiveVerb = pawn.CurrentEffectiveVerb; bool flag6 = currentEffectiveVerb == null; if (flag6) { result = null; } else { bool isMeleeAttack = currentEffectiveVerb.verbProps.IsMeleeAttack; if (isMeleeAttack) { result = this.MeleeAttackJob(enemyTarget); } else { bool flag7 = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f; bool flag8 = pawn.Position.Standable(pawn.Map); bool flag9 = flag7 || flag8; if (flag9) { result = new Job(WPJobDefOf.ArtyWaitCombat, JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else { IntVec3 intVec; bool flag10 = !this.TryFindShootingPosition(pawn, out intVec); if (flag10) { result = null; } else { bool flag11 = intVec == pawn.Position; if (flag11) { result = new Job(WPJobDefOf.ArtyWaitCombat, JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_WPArtyAIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } } } } } } } return(result); }
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); }
private static float CastPositionPreference(IntVec3 c) { bool flag = true; List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; Fire fire = thing as Fire; if (fire != null && fire.parent == null) { return(-1f); } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } float num = 0.3f; if (req.caster.kindDef.aiAvoidCover) { num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map); } if (req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, req.target.Position, req.caster.Map) * 0.55f; } float num2 = (req.caster.Position - c).LengthHorizontal; if (rangeFromTarget > 100f) { num2 -= rangeFromTarget - 100f; if (num2 < 0f) { num2 = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; rangeFromTargetToCellSquared = (c - req.target.Position).LengthHorizontalSquared; float num4 = Mathf.Abs(rangeFromTargetToCellSquared - optimalRangeSquared) / optimalRangeSquared; num4 = 1f - num4; num4 = 0.7f + 0.3f * num4; num3 *= num4; if (rangeFromTargetToCellSquared < 25f) { num3 *= 0.5f; } num *= num3; if (rangeFromCasterToCellSquared > rangeFromTargetSquared) { num *= 0.4f; } if (!flag) { num *= 0.2f; } return(num); }
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: 0x06000031 RID: 49 RVA: 0x00002C44 File Offset: 0x00000E44 protected override Job TryGiveJob(Pawn pawn) { MentalState_Fighter state = (MentalState_Fighter)pawn.MentalState; Pawn pawnTarget = state.otherPawn; Building_Bell bellRef = state.bellRef; Job result; Fighter fighterTarget = bellRef.getFighter(pawnTarget); if (!fighterTarget.isInFight || (double)Rand.Value < 0.5) { result = new Job(JobDefOf.Wait_Combat) { expiryInterval = 10 }; } else { if (pawn.TryGetAttackVerb(null, false) == null) { result = null; } else { ThingWithComps primary = pawn.equipment != null ? pawn.equipment.Primary : null; if (bellRef.currentState == Building_Bell.State.fight && pawn.equipment != null && primary == null) { List <Thing> suitableWeapons = new List <Thing>(); foreach (IntVec3 c in bellRef.GetComp <CompBell>().ValidCells) { List <Thing> thingList = c.GetThingList(bellRef.Map); for (int i = 0; i < thingList.Count; i++) { Thing t = thingList[i]; bool flag8 = t.def.IsWeapon && !suitableWeapons.Contains(t) && t.Spawned && pawn.CanReserve(t, 1, -1, null, false); if (flag8) { suitableWeapons.Add(t); } } } Thing weapon = null; int maxDistance = 9999; foreach (Thing t2 in suitableWeapons) { if ((t2.Position - pawn.Position).LengthManhattan < maxDistance) { weapon = t2; maxDistance = (t2.Position - pawn.Position).LengthManhattan; } } if (weapon != null) { return(new Job(JobDefOf.Equip, weapon)); } } if (pawnTarget == null || !pawn.CanReach(pawnTarget, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { result = new Job(JobDefOf.Wait); } else { pawn.mindState.enemyTarget = pawnTarget; pawn.mindState.enemyTarget = pawnTarget; this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { result = null; } else { bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { result = null; } else { bool isMeleeAttack = verb.verbProps.IsMeleeAttack; if (isMeleeAttack || pawnTarget.Downed) { result = this.MeleeAttackJob(enemyTarget); result.killIncappedTarget = bellRef.toDeath; } else { if (( CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map) && verb.CanHitTarget(enemyTarget) ) || ( (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25 && verb.CanHitTarget(enemyTarget) )) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { result = null; } else { if (intVec == pawn.Position) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } } } } } } } return(result); }
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); }
// Verse.AI.CastPositionFinder public bool TryFindCastPosition(CastPositionRequest req, out IntVec3 dest) { ByteGrid avoidGrid = null; int inRadiusMark = 0; if (this.pawn.CurJob.verbToUse == null) { Log.Error(this.pawn + " tried to find casting position without a verb."); dest = IntVec3.Invalid; return(false); } if (req.maxRegionsRadius > 0) { Region region = req.caster.PositionHeld.GetRegion(this.pawn.Map); if (region == null) { Log.Error("TryFindCastPosition requiring region traversal but root region is null."); dest = IntVec3.Invalid; return(false); } inRadiusMark = Rand.Int; RegionTraverser.MarkRegionsBFS(region, null, req.maxRegionsRadius, inRadiusMark); if (req.maxRangeFromLocus > 0.01f) { Region region2 = req.locus.GetRegion(this.pawn.Map); if (region2 == null) { Log.Error("locus " + req.locus + " has no region"); dest = IntVec3.Invalid; return(false); } if (region2.mark != inRadiusMark) { Log.Error(string.Concat(new object[] { req.caster, " can't possibly get to locus ", req.locus, " as it's not in a maxRegionsRadius of ", req.maxRegionsRadius, ". Overriding maxRegionsRadius." })); req.maxRegionsRadius = 0; } } } CellRect cellRect = CellRect.WholeMap(req.caster.Map); if (req.maxRangeFromCaster > 0.01f) { int numSolo = Mathf.CeilToInt(req.maxRangeFromCaster); CellRect otherRect = new CellRect(this.pawn.PositionHeld.x - numSolo, this.pawn.PositionHeld.z - numSolo, numSolo * 2 + 1, numSolo * 2 + 1); cellRect.ClipInsideRect(otherRect); } int num2 = Mathf.CeilToInt(req.maxRangeFromTarget); CellRect otherRect2 = new CellRect(this.TargetA.Cell.x - num2, this.TargetA.Cell.z - num2, num2 * 2 + 1, num2 * 2 + 1); cellRect.ClipInsideRect(otherRect2); if (req.maxRangeFromLocus > 0.01f) { int numThree = Mathf.CeilToInt(req.maxRangeFromLocus); CellRect otherRect3 = new CellRect(this.TargetA.Cell.x - numThree, this.TargetA.Cell.z - numThree, numThree * 2 + 1, numThree * 2 + 1); cellRect.ClipInsideRect(otherRect3); } IntVec3 bestSpot = IntVec3.Invalid; float bestSpotPref = 0.001f; float maxRangeFromCasterSquared = req.maxRangeFromCaster * req.maxRangeFromCaster; float maxRangeFromTargetSquared = req.maxRangeFromTarget * req.maxRangeFromTarget; float maxRangeFromLocusSquared = req.maxRangeFromLocus * req.maxRangeFromLocus; float rangeFromTarget = (req.caster.Position - this.TargetA.Cell).LengthHorizontal; float rangeFromTargetSquared = (req.caster.Position - this.TargetA.Cell).LengthHorizontalSquared; float rangeFromCasterToCellSquared = 0f; float optimalRangeSquared = this.pawn.CurJob.verbToUse.verbProps.range * 0.8f * (this.pawn.CurJob.verbToUse.verbProps.range * 0.8f); /////////////////// Evaluate Cell method IntVec3 c = req.caster.PositionHeld; EvaluateCell(c, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); float num = -1f; /////////////////// CAST POSITION PREFERENCE bool flag = true; List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; if (thing is Fire fire && fire.parent == null) { num = -1f; goto MainSequenceTwo; } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } num = 0.3f; if (req.caster.kindDef.aiAvoidCover) { num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map); } if (req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, this.TargetLocA, req.caster.Map); } float numTwo = (req.caster.Position - c).LengthHorizontal; if (rangeFromTarget > 100f) { numTwo -= rangeFromTarget - 100f; if (numTwo < 0f) { numTwo = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; float rangeFromTargetToCellSquared = (c - this.TargetLocA).LengthHorizontalSquared; //rangeFromCasterToCellSquared = (req.target.Position - c).LengthHorizontalSquared; float num4 = Mathf.Abs(rangeFromTargetToCellSquared - optimalRangeSquared) / optimalRangeSquared; num4 = 1f - num4; num4 = 0.7f + 0.3f * num4; num3 *= num4; if (rangeFromTargetToCellSquared < 25f) { num3 *= 0.5f; } num *= num3; if (rangeFromCasterToCellSquared > rangeFromTargetSquared) { num *= 0.4f; } if (!flag) { num *= 0.2f; } /////////////////////////////////////////////// MainSequenceTwo: if (avoidGrid != null) { byte b = avoidGrid[c]; num *= Mathf.Max(0.1f, (37f - b) / 37f); } if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, num / 4f, num.ToString("F3")); } if (num < bestSpotPref) { goto MainSequence; } if (!this.pawn.CurJob.verbToUse.CanHitTargetFrom(c, this.TargetLocA)) { if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, 0.6f, "can't hit"); } goto MainSequence; } if (req.caster.Map.pawnDestinationManager.DestinationIsReserved(c, req.caster)) { if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, num * 0.9f, "resvd"); } goto MainSequence; } bestSpot = c; bestSpotPref = num; ///////////////////////////////////////////////////// MainSequence: if (bestSpotPref >= 1.0) { dest = req.caster.Position; return(true); } float slope = -1f / CellLine.Between(this.TargetLocA, req.caster.Position).Slope; CellLine cellLine = new CellLine(this.TargetLocA, slope); bool flagTwo = cellLine.CellIsAbove(req.caster.Position); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (cellLine.CellIsAbove(current) == flagTwo && cellRect.Contains(current)) { EvaluateCell(current, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); } iterator.MoveNext(); } if (bestSpot.IsValid && bestSpotPref > 0.33f) { dest = bestSpot; return(true); } CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { IntVec3 current2 = iterator2.Current; if (cellLine.CellIsAbove(current2) != flag && cellRect.Contains(current2)) { EvaluateCell(current2, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); } iterator2.MoveNext(); } if (bestSpot.IsValid) { dest = bestSpot; return(true); } dest = req.caster.PositionHeld; return(false); }
private static float CastPositionPreference(IntVec3 c) { bool flag = true; List <Thing> list = CastPositionFinder.req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; Fire fire = thing as Fire; if (fire != null && fire.parent == null) { return(-1f); } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } float num = 0.3f; if (CastPositionFinder.req.caster.kindDef.aiAvoidCover) { num = (float)(num + (8.0 - CoverUtility.TotalSurroundingCoverScore(c, CastPositionFinder.req.caster.Map))); } if (CastPositionFinder.req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, CastPositionFinder.req.target.Position, CastPositionFinder.req.caster.Map); } float num2 = (CastPositionFinder.req.caster.Position - c).LengthHorizontal; if (CastPositionFinder.rangeFromTarget > 100.0) { num2 = (float)(num2 - (CastPositionFinder.rangeFromTarget - 100.0)); if (num2 < 0.0) { num2 = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; CastPositionFinder.rangeFromTargetToCellSquared = (float)(c - CastPositionFinder.req.target.Position).LengthHorizontalSquared; float num4 = Mathf.Abs(CastPositionFinder.rangeFromTargetToCellSquared - CastPositionFinder.optimalRangeSquared) / CastPositionFinder.optimalRangeSquared; num4 = (float)(1.0 - num4); num4 = (float)(0.699999988079071 + 0.30000001192092896 * num4); num3 *= num4; if (CastPositionFinder.rangeFromTargetToCellSquared < 25.0) { num3 = (float)(num3 * 0.5); } num *= num3; if (CastPositionFinder.rangeFromCasterToCellSquared > CastPositionFinder.rangeFromTargetSquared) { num = (float)(num * 0.40000000596046448); } if (!flag) { num = (float)(num * 0.20000000298023224); } return(num); }