private static bool Prefix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn) { bool result = true; if (!recursiveTrap) { recursiveTrap = true; Map oldMap = pawn.Map; IntVec3 oldPosition = pawn.Position; foreach (var map in ZUtils.GetAllMapsInClosestOrder(pawn, oldMap, oldPosition)) { var job = Traverse.Create(__instance).Method("TryGiveJob", new object[] { pawn }).GetValue <Job>(); Log.Message("2: " + ZUtils.ZTracker.GetMapInfo(pawn.Map) + " - result: " + job); if (job != null) { __result = job; result = false; break; } } ZUtils.TeleportThing(pawn, oldMap, oldPosition); recursiveTrap = false; } Log.Message(pawn + " - 4 TEST: " + __result); return(result); }
public static bool HumanUser(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn, bool player) { if (pawn.abilities != null) { bool hasRangedVerb = false; List <Verb> rangeList = new List <Verb>(); foreach (Ability ability in pawn.abilities.abilities) { AbilitesExtended.EquipmentAbility equipmentAbility = ability as AbilitesExtended.EquipmentAbility; if (equipmentAbility != null) { if (equipmentAbility.CanCast && equipmentAbility.verb.verbProps.range < 1.5f) { Log.Message("Adding " + equipmentAbility.def.LabelCap + "to " + pawn + ""); rangeList.Add(equipmentAbility.verb); hasRangedVerb = true; } } } if (!rangeList.NullOrEmpty() && hasRangedVerb) { Log.Message("found " + rangeList.Count + " eqabilities for " + pawn); } } return(true); }
static void Postfix(ref JobGiver_AIFightEnemy __instance, ref Job __result, Pawn pawn) { if (pawn.RaceProps.FleshType.defName.Contains("BETAFlesh") && __result != null) { if (__result.def == JobDefOf.AttackMelee) { __result.killIncappedTarget = true; } } }
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); }
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); }
private static void Postfix(ref JobGiver_AIFightEnemy __instance, ref Job __result, ref Pawn pawn) { if (__result == null && !recursiveTrap) { recursiveTrap = true; CombatPatches_BestAttackTarget_Patch.multiMapSearch = true; var job = __instance.TryGiveJob(pawn); if (job != null) { ZLogger.Message("Second block: " + job, true); if (job.targetA.Thing?.Map != null && job.targetA.Thing.Map != pawn.Map) { if (!ZUtils.ZTracker.jobTracker.ContainsKey(pawn)) { ZUtils.ZTracker.jobTracker[pawn] = new JobTracker { activeJobs = new List <Job>() } } ; ZUtils.ZTracker.ResetJobTrackerFor(pawn); ZUtils.ZTracker.BuildJobListFor(pawn, job.targetA.Thing.Map, __result); ZUtils.ZTracker.jobTracker[pawn].targetDest = new TargetInfo(job.targetA.Thing); ZUtils.ZTracker.jobTracker[pawn].forceGoToDestMap = true; __result = ZUtils.ZTracker.jobTracker[pawn].activeJobs[0]; ZUtils.ZTracker.jobTracker[pawn].activeJobs.RemoveAt(0); } else { __result = job; } } recursiveTrap = false; CombatPatches_BestAttackTarget_Patch.multiMapSearch = false; } else if (__result != null && __result.targetA.Thing?.Map != null && __result.targetA.Thing.Map != pawn.Map) { ZLogger.Message("Second block: " + __result, true); if (!ZUtils.ZTracker.jobTracker.ContainsKey(pawn)) { ZUtils.ZTracker.jobTracker[pawn] = new JobTracker { activeJobs = new List <Job>() } } ; ZUtils.ZTracker.ResetJobTrackerFor(pawn); ZUtils.ZTracker.BuildJobListFor(pawn, __result.targetA.Thing.Map, __result); ZUtils.ZTracker.jobTracker[pawn].targetDest = new TargetInfo(__result.targetA.Thing); ZUtils.ZTracker.jobTracker[pawn].forceGoToDestMap = true; __result = ZUtils.ZTracker.jobTracker[pawn].activeJobs[0]; ZUtils.ZTracker.jobTracker[pawn].activeJobs.RemoveAt(0); } else if (__result == null && pawn.mindState.enemyTarget?.Map != null && pawn.mindState.enemyTarget.Map != pawn.Map) { ZLogger.Message("Third block: " + __result, true); if (!ZUtils.ZTracker.jobTracker.ContainsKey(pawn)) { ZUtils.ZTracker.jobTracker[pawn] = new JobTracker { activeJobs = new List <Job>() } } ; ZUtils.ZTracker.jobTracker[pawn].targetDest = new TargetInfo(pawn.mindState.enemyTarget); ZUtils.ZTracker.jobTracker[pawn].forceGoToDestMap = true; __result = JobMaker.MakeJob(ZLevelsDefOf.ZL_GoToMap); ZUtils.ZTracker.jobTracker[pawn].mainJob = __result; ZUtils.ZTracker.jobTracker[pawn].failIfTargetMapIsNotDest = true; ZUtils.ZTracker.jobTracker[pawn].target = pawn.mindState.enemyTarget; } ZLogger.Message(pawn + " got result 5: " + __result + " in " + pawn.Map + " - " + __result?.targetA.Thing?.Map + " - mind enemy: " + pawn.mindState.enemyTarget, true); } } }
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); }