// 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); }
//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); }
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); }
// 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)); }
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)); }
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)); }
// 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)); }
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); }
// 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); } }
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); }
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); }
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); }