public static void CheckForAutoAttack(JobDriver jobDriver) { List <Hediff> hediffs = jobDriver.pawn.health.hediffSet.hediffs; foreach (Hediff hediff in hediffs) { HediffComp_VerbGiverExtended verbGiverExtended = hediff.TryGetComp <HediffComp_VerbGiverExtended>(); if (verbGiverExtended != null) // for each comp that gives verbs do this: { List <Verb> allVerbs = new List <Verb>(verbGiverExtended.AllVerbs.SkipWhile((Verb verb) => verb is Verb_CastPsycast)); int radVerb = Random.Range(0, allVerbs.Count); if (allVerbs[radVerb] != null && verbGiverExtended.canAutoAttack && verbGiverExtended.canAttack) // take a random verb that can attack { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat; if (allVerbs[radVerb].IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } // find best thing to attack Thing thing = (Thing)PCF_AttackTargetFinder.BestShootTargetFromCurrentPosition(jobDriver.pawn, allVerbs[radVerb], targetScanFlags, null, 0f, 9999f); if (thing != null && !allVerbs[radVerb].IsMeleeAttack) // attack (weird shit inbetween) { verbGiverExtended.rangedVerbWarmupTime = allVerbs[radVerb].verbProps.warmupTime; allVerbs[radVerb].verbProps.warmupTime = 0f; allVerbs[radVerb].TryStartCastOn(thing, false, true); allVerbs[radVerb].verbProps.warmupTime = verbGiverExtended.rangedVerbWarmupTime; } } verbGiverExtended.canAttack = false; } } }
public static bool Prefix(ref IAttackTarget __result, IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { bool result = true; if (!recursiveTrap) { recursiveTrap = true; Map oldMap = searcher.Thing.Map; IntVec3 oldPosition = searcher.Thing.Position; foreach (var map in ZUtils.GetAllMapsInClosestOrder(searcher.Thing, oldMap, oldPosition)) { var target = AttackTargetFinder.BestAttackTarget(searcher, flags, validator, minDist, maxDist, locus, maxTravelRadiusFromLocus, canBash, canTakeTargetsCloserThanEffectiveMinRange); Log.Message(ZUtils.ZTracker.GetMapInfo(searcher.Thing.Map) + " - result: " + target); if (target != null) { __result = target; result = false; break; } } ZUtils.TeleportThing(searcher.Thing, oldMap, oldPosition); recursiveTrap = false; } return(result); }
protected LocalTargetInfo TryFindNewTarget() { IAttackTargetSearcher attackTargetSearcher = this.TargSearcher(); Faction faction = attackTargetSearcher.Thing.Faction; float range = this.GunCompEq.PrimaryVerb.verbProps.range; float minRange = this.GunCompEq.PrimaryVerb.verbProps.minRange; Building t = default(Building); if (Rand.Value < 0.5 && this.GunCompEq.PrimaryVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && base.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = (float)x.Position.DistanceToSquared(base.Position); return(num > minRange * minRange && num < range * range); }).TryRandomElement <Building>(out t)) { return(t); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat; if (!this.GunCompEq.PrimaryVerb.ProjectileFliesOverhead()) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } if (this.GunCompEq.PrimaryVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, this.IsValidTarget, range, minRange, targetScanFlags)); }
public static void CheckForAutoAttack(JobDriver jobDriver) { List <Hediff> hediffs = jobDriver.pawn.health.hediffSet.hediffs; int hediff = hediffs.Count; for (int i = 0; i < hediff; i++) { HediffComp_VerbGiverExtended verbGiverExtended = hediffs[i].TryGetComp <HediffComp_VerbGiverExtended>(); if (verbGiverExtended != null) { List <Verb> allVerbs = verbGiverExtended.AllVerbs; int radVerb = Random.Range(0, allVerbs.Count); if (allVerbs[radVerb] != null && verbGiverExtended.canAutoAttack && verbGiverExtended.canAttack) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat; if (allVerbs[radVerb].IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)PCF_AttackTargetFinder.BestShootTargetFromCurrentPosition(jobDriver.pawn, allVerbs[radVerb], targetScanFlags, null, 0f, 9999f); if (thing != null && !allVerbs[radVerb].IsMeleeAttack) { verbGiverExtended.rangedVerbWarmupTime = allVerbs[radVerb].verbProps.warmupTime; allVerbs[radVerb].verbProps.warmupTime = 0f; allVerbs[radVerb].TryStartCastOn(thing, false, true); allVerbs[radVerb].verbProps.warmupTime = verbGiverExtended.rangedVerbWarmupTime; } } verbGiverExtended.canAttack = false; } } }
static void checkForAutoAttack(JobDriver_Goto __instance) { if ((__instance.pawn.story == null || !__instance.pawn.story.DisabledWorkTagsBackstoryAndTraits.HasFlag(WorkTags.Violent)) && __instance.pawn.Faction != null && !(__instance.pawn.stances.curStance is Stance_RunAndGun) && __instance.pawn.jobs.curJob.def == JobDefOf.Goto && (__instance.pawn.drafter == null || __instance.pawn.drafter.FireAtWill)) { CompRunAndGun comp = __instance.pawn.TryGetComp <CompRunAndGun>(); if (comp == null || comp.isEnabled == false) { return; } Verb verb = __instance.pawn.TryGetAttackVerb(null); if (verb != null) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat; if (verb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(__instance.pawn, targetScanFlags, null, 0f, 9999f); if (thing != null && !(verb.IsMeleeAttack && __instance.pawn.CanReachImmediate(thing, PathEndMode.Touch))) //Don't allow melee attacks, but take into account ranged animals or dual wield users { __instance.pawn.TryStartAttack(thing); return; } } } }
static void checkForAutoAttack(JobDriver_Goto __instance) { if ((__instance.pawn.story == null || !__instance.pawn.story.WorkTagIsDisabled(WorkTags.Violent)) && __instance.pawn.Faction != null && !(__instance.pawn.stances.curStance is Stance_RunAndGun) && __instance.pawn.jobs.curJob.def == JobDefOf.Goto && (__instance.pawn.drafter == null || __instance.pawn.drafter.FireAtWill)) { CompRunAndGun comp = __instance.pawn.TryGetComp <CompRunAndGun>(); if (comp == null || comp.isEnabled == false) { return; } Verb verb = __instance.pawn.TryGetAttackVerb(true); if (verb != null && !verb.verbProps.MeleeRange) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat; if (verb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(__instance.pawn, null, verb.verbProps.range, verb.verbProps.minRange, targetScanFlags); if (thing != null) { __instance.pawn.TryStartAttack(thing); return; } } } }
protected LocalTargetInfo TryFindNewTarget() { IAttackTargetSearcher attackTargetSearcher = TargSearcher(); Faction faction = attackTargetSearcher.Thing.Faction; float range = AttackVerb.verbProps.range; if (Rand.Value < 0.5f && AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && base.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = AttackVerb.verbProps.EffectiveMinRange(x, this); float num2 = x.Position.DistanceToSquared(base.Position); return(num2 > num * num && num2 < range * range); }).TryRandomElement(out var result)) { return(result); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (!AttackVerb.ProjectileFliesOverhead()) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } if (AttackVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } if (IsMortar) { targetScanFlags |= TargetScanFlags.NeedNotUnderThickRoof; } return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, IsValidTarget)); }
private Job TryGetAttackNearbyEnemyJob(Pawn pawn) { if (pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { return(null); } bool flag = pawn.equipment.Primary == null || pawn.equipment.Primary.def.IsMeleeWeapon; float num = 8f; if (!flag) { num = Mathf.Clamp((float)(pawn.equipment.PrimaryEq.PrimaryVerb.verbProps.range * 0.6600000262260437), 2f, 20f); } TargetScanFlags flags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat; float maxDist = num; Thing thing = (Thing)AttackTargetFinder.BestAttackTarget(pawn, flags, null, 0f, maxDist, default(IntVec3), 3.40282347E+38f, false); if (thing == null) { return(null); } if (!flag && !pawn.CanReachImmediate(thing, PathEndMode.Touch)) { Job job = new Job(JobDefOf.AttackStatic, thing); job.maxNumStaticAttacks = 2; job.expiryInterval = 2000; job.endIfCantShootTargetFromCurPos = true; return(job); } return(new Job(JobDefOf.AttackMelee, thing)); }
protected TargetInfo TryFindNewTarget() { IAttackTargetSearcher attackTargetSearcher = this.TargSearcher(); Faction faction = attackTargetSearcher.Thing.Faction; float range = this.GunCompEq.PrimaryVerb.verbProps.range; float minRange = this.GunCompEq.PrimaryVerb.verbProps.minRange; Building t; if (Rand.Value < 0.5f && this.GunCompEq.PrimaryVerb.verbProps.projectileDef.projectile.flyOverhead && faction.HostileTo(Faction.OfPlayer) && Find.VisibleMap.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = x.Position.DistanceToSquared(this.Position); return(num > minRange * minRange && num < range * range); }).TryRandomElement(out t)) { return(t); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat; if (!this.GunCompEq.PrimaryVerb.verbProps.projectileDef.projectile.flyOverhead) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; } if (this.GunCompEq.PrimaryVerb.verbProps.ai_IsIncendiary) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, new Predicate <Thing>(this.IsValidTarget), range, minRange, targetScanFlags)); }
protected LocalTargetInfo TryFindNewTarget() { Thing searcher; Faction faction; if (this.mannableComp != null && this.mannableComp.MannedNow) { searcher = this.mannableComp.ManningPawn; faction = this.mannableComp.ManningPawn.Faction; } else { searcher = this; faction = base.Faction; } if (this.GunCompEq.PrimaryVerb.verbProps.projectileDef.projectile.flyOverhead && faction.HostileTo(Faction.OfPlayer) && Rand.Value < 0.5f && base.Map.listerBuildings.allBuildingsColonist.Count > 0) { return(base.Map.listerBuildings.allBuildingsColonist.RandomElement <Building>()); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat; if (!this.GunCompEq.PrimaryVerb.verbProps.projectileDef.projectile.flyOverhead) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; } if (this.GunCompEq.PrimaryVerb.verbProps.ai_IsIncendiary) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } return(AttackTargetFinder.BestShootTargetFromCurrentPosition(searcher, new Predicate <Thing>(this.IsValidTarget), this.GunCompEq.PrimaryVerb.verbProps.range, this.GunCompEq.PrimaryVerb.verbProps.minRange, targetScanFlags)); }
protected LocalTargetInfo TryFindNewTarget() { IAttackTargetSearcher attackTargetSearcher = this.TargSearcher(); Faction faction = attackTargetSearcher.Thing.Faction; float range = this.GunCompEq.PrimaryVerb.verbProps.range; float minRange = this.GunCompEq.PrimaryVerb.verbProps.minRange; Building t; if (Rand.Value < 0.5f && Projectile.projectile.flyOverhead && faction.HostileTo(Faction.OfPlayer) && base.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = (float)x.Position.DistanceToSquared(this.Position); return(num > minRange * minRange && num < range * range); }).TryRandomElement(out t)) { return(t); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat; if (!Projectile.projectile.flyOverhead) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, new Predicate <Thing>(this.IsValidTarget), minRange, range)); // WTF B19??? }
private static void JobDriver_Wait_CheckForAutoAttackPostfix(JobDriver_Wait __instance) { if (__instance.pawn.Faction != null || __instance.pawn.Downed || __instance.pawn.stances.FullBodyBusy) { return; } if ((__instance.pawn.story == null || !__instance.pawn.story.WorkTagIsDisabled(WorkTags.Violent)) && __instance.job.def == JobDefOf.Wait_Combat && (__instance.pawn.drafter == null || __instance.pawn.drafter.FireAtWill)) { Verb currentEffectiveVerb = __instance.pawn.CurrentEffectiveVerb; if (currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat; if (currentEffectiveVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(__instance.pawn, targetScanFlags, null, 0f, 9999f); if (thing != null) { __instance.pawn.TryStartAttack(thing); __instance.collideWithPawns = true; return; } } } return; }
private Job TryGetAttackNearbyEnemyJob(Pawn pawn) { if (pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { return(null); } bool isMeleeAttack = pawn.CurrentEffectiveVerb.IsMeleeAttack; float num = 8f; if (!isMeleeAttack) { num = Mathf.Clamp(pawn.CurrentEffectiveVerb.verbProps.range * 0.66f, 2f, 20f); } TargetScanFlags flags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat; float maxDist = num; Thing thing = (Thing)AttackTargetFinder.BestAttackTarget(pawn, flags, null, 0f, maxDist, default(IntVec3), 3.40282347E+38f, false, true); if (thing == null) { return(null); } if (isMeleeAttack || pawn.CanReachImmediate(thing, PathEndMode.Touch)) { return(new Job(JobDefOf.AttackMelee, thing)); } return(new Job(JobDefOf.AttackStatic, thing) { maxNumStaticAttacks = 2, expiryInterval = 2000, endIfCantShootTargetFromCurPos = true }); }
protected LocalTargetInfo TryFindNewTarget() // Core method { IAttackTargetSearcher attackTargetSearcher = this.TargSearcher(); Faction faction = attackTargetSearcher.Thing.Faction; float range = this.AttackVerb.verbProps.range; Building t; if (Rand.Value < 0.5f && this.AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && base.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = this.AttackVerb.verbProps.EffectiveMinRange(x, this); float num2 = (float)x.Position.DistanceToSquared(this.Position); return(num2 > num * num && num2 < range * range); }).TryRandomElement(out t)) { return(t); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat; if (!this.AttackVerb.ProjectileFliesOverhead()) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } if (this.AttackVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, new Predicate <Thing>(this.IsValidTarget), 0f, 9999f)); }
public LocalTargetInfo FindTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> verifier, float minDistance = 0, float maxDistance = 9999) { if (!(searcher.Thing is Building_Turret turret)) { return(LocalTargetInfo.Invalid); } return(turret.FirstShieldInRange() ?? LocalTargetInfo.Invalid); }
//static IEnumerable<CodeInstruction> WoundConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator il) //{ // FieldInfo pawnDefInfo = AccessTools.Field(typeof(Thing), nameof(Thing.def)); // FieldInfo defNameInfo = AccessTools.Field(typeof(Def), nameof(Def.defName)); // MethodInfo startsWithInfo = AccessTools.Method(typeof(String), nameof(String.StartsWith), new Type[] { typeof(string) }); // bool didIt = false; // List<CodeInstruction> instructionList = instructions.ToList(); // for (int i=0; i<instructionList.Count; i++) // { // CodeInstruction instruction = instructionList[i]; // if(!didIt && instruction.opcode == OpCodes.Bne_Un) // { // Label label = il.DefineLabel(); // instructionList[i + 1].labels = new List<Label>() { label }; // yield return new CodeInstruction(OpCodes.Beq_S, label); // yield return new CodeInstruction(OpCodes.Ldarg_1); // yield return new CodeInstruction(OpCodes.Ldfld, pawnDefInfo); // yield return new CodeInstruction(OpCodes.Ldfld, defNameInfo); // yield return new CodeInstruction(OpCodes.Ldstr, "ROM_"); // yield return new CodeInstruction(OpCodes.Callvirt, startsWithInfo); // instruction.opcode = OpCodes.Brfalse_S; // didIt = true; // } // yield return instruction; // } //} public static void BestAttackTargetPrefix(IAttackTargetSearcher searcher, TargetScanFlags flags, ref Predicate <Thing> validator, float minDist, float maxDist, IntVec3 locus, float maxTravelRadiusFromLocus, bool canBashDoors, bool canTakeTargetsCloserThanEffectiveMinRange, bool canBashFences) { Predicate <Thing> validatorCopy = validator; validator = new Predicate <Thing>(delegate(Thing t) { return((validatorCopy == null || validatorCopy(t)) && (!(t is CosmicHorrorPawn cosmicPawn) || !cosmicPawn.IsInvisible)); }); }
protected override Thing FindAttackTarget(Pawn pawn) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat; /*if (PrimaryVerbIsIncendiary(pawn)) * { * targetScanFlags |= TargetScanFlags.NeedNonBurning; * }*/ return((Thing)AttackTargetFinder.BestAttackTarget(pawn, targetScanFlags, x => ExtraTargetValidator(pawn, x), 0f, TargetAcquireRadius, default(IntVec3), float.MaxValue, false)); }
//static IEnumerable<CodeInstruction> WoundConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator il) //{ // FieldInfo pawnDefInfo = AccessTools.Field(typeof(Thing), nameof(Thing.def)); // FieldInfo defNameInfo = AccessTools.Field(typeof(Def), nameof(Def.defName)); // MethodInfo startsWithInfo = AccessTools.Method(typeof(String), nameof(String.StartsWith), new Type[] { typeof(string) }); // bool didIt = false; // List<CodeInstruction> instructionList = instructions.ToList(); // for (int i=0; i<instructionList.Count; i++) // { // CodeInstruction instruction = instructionList[i]; // if(!didIt && instruction.opcode == OpCodes.Bne_Un) // { // Label label = il.DefineLabel(); // instructionList[i + 1].labels = new List<Label>() { label }; // yield return new CodeInstruction(OpCodes.Beq_S, label); // yield return new CodeInstruction(OpCodes.Ldarg_1); // yield return new CodeInstruction(OpCodes.Ldfld, pawnDefInfo); // yield return new CodeInstruction(OpCodes.Ldfld, defNameInfo); // yield return new CodeInstruction(OpCodes.Ldstr, "ROM_"); // yield return new CodeInstruction(OpCodes.Callvirt, startsWithInfo); // instruction.opcode = OpCodes.Brfalse_S; // didIt = true; // } // yield return instruction; // } //} public static void BestAttackTargetPrefix(IAttackTargetSearcher searcher, TargetScanFlags flags, ref Predicate <Thing> validator, float minDist, float maxDist, IntVec3 locus, float maxTravelRadiusFromLocus, bool canBash) { Predicate <Thing> validatorCopy = validator; validator = new Predicate <Thing>(delegate(Thing t) { return((validatorCopy != null ? validatorCopy(t) : true) && (t is CosmicHorrorPawn cosmicPawn ? !cosmicPawn.IsInvisible : true)); }); }
/// <summary> /// Find best attack target for VehicleTurret /// </summary> /// <seealso cref="BestAttackTarget(VehicleTurret, TargetScanFlags, Predicate{Thing}, float, float, IntVec3, float, bool, bool)"/> /// <param name="cannon"></param> /// <param name="restrictedAngle"></param> /// <param name="param"></param> public static LocalTargetInfo GetCannonTarget(this VehicleTurret cannon, float restrictedAngle = 0f, TargetingParameters param = null) { if (cannon.vehicle.CompCannons != null && cannon.vehicle.CompCannons.WeaponStatusOnline && cannon.vehicle.Faction != null) //add fire at will option { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; Thing thing = (Thing)BestAttackTarget(cannon, targetScanFlags, null, 0f, 9999f, default(IntVec3), float.MaxValue, false, false); if (thing != null) { return(new LocalTargetInfo(thing)); } } return(LocalTargetInfo.Invalid); }
protected virtual Thing FindAttackTarget(Pawn pawn) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (needLOSToAcquireNonPawnTargets) { targetScanFlags |= TargetScanFlags.NeedLOSToNonPawns; } if (PrimaryVerbIsIncendiary(pawn)) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } return((Thing)AttackTargetFinder.BestAttackTarget(pawn, targetScanFlags, (Thing x) => ExtraTargetValidator(pawn, x), 0f, targetAcquireRadius, GetFlagPosition(pawn), GetFlagRadius(pawn))); }
protected LocalTargetInfo TryFindNewTarget() { // Log.Messageage("TryFindNewTarget"); IAttackTargetSearcher attackTargetSearcher = this.TargSearcher(); Faction faction = attackTargetSearcher.Thing?.Faction ?? this.parent.Faction; float range = this.AttackVerb.verbProps.range; Building t; Rand.PushState(); float tgtt = Rand.Value; Rand.PopState(); if (tgtt < 0.5f && this.AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && Operator.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = this.AttackVerb.verbProps.EffectiveMinRange(x, Operator); float num2 = (float)x.Position.DistanceToSquared(Operator.Position); return(num2 > num * num && num2 < range * range); }).TryRandomElement(out t)) { return(t); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (!this.AttackVerb.ProjectileFliesOverhead()) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } if (this.AttackVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } if (this.IsMortar) { targetScanFlags |= TargetScanFlags.NeedNotUnderThickRoof; } Thing tgt = (Thing)BestShootTargetFromCurrentPosition(attackTargetSearcher, AttackVerb, targetScanFlags, new Predicate <Thing>(this.IsValidTarget), 0f, 9999f, Building != null); if (tgt == null && OperatorPawn?.verbTracker.PrimaryVerb.CurrentTarget != null && OperatorPawn.verbTracker.PrimaryVerb.CurrentTarget.HasThing) { tgt = OperatorPawn.verbTracker.PrimaryVerb.CurrentTarget.Thing; Log.Message("TryFindNewTarget OperatorPawntgt found: " + (tgt != null)); } // Log.Messageage("TryFindNewTarget tgt found: " + (tgt != null)); return(tgt); }
public static bool Prefix(ref IAttackTarget __result, List <IAttackTarget> ___tmpTargets, List <Pair <IAttackTarget, float> > ___availableShootingTargets, List <float> ___tmpTargetScores, List <bool> ___tmpCanShootAtTarget, List <IntVec3> ___tempDestList, List <IntVec3> ___tempSourceList, IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { bool result = true; if (!recursiveTrap && multiMapSearch) { recursiveTrap = true; Map oldMap = searcher.Thing.Map; IntVec3 oldPosition = searcher.Thing.Position; bool dontCheckForStairs = searcher.Thing is Building; foreach (var map in ZUtils.GetAllMapsInClosestOrder(searcher.Thing, oldMap, oldPosition, dontCheckForStairs: dontCheckForStairs)) { if (ZUtils.ZTracker.GetZIndexFor(map) < ZUtils.ZTracker.GetZIndexFor(oldMap)) { CanBeSeenOverFast_Patch.checkLevels = true; CanBeSeenOverFast_Patch.upperMap = oldMap; CanBeSeenOverFast_Patch.lowerMap = map; CanBeSeenOverFast_Patch.caster = searcher.Thing; } var target = AttackTargetFinder.BestAttackTarget(searcher, flags, validator, minDist, maxDist, locus, maxTravelRadiusFromLocus, canBash, canTakeTargetsCloserThanEffectiveMinRange); //ZLogger.Message(searcher.Thing + " - 1: " + ZUtils.ZTracker.GetMapInfo(searcher.Thing.Map) + " - result: " + target); if (target != null) { __result = target; result = false; break; } } //ZLogger.Message("1 Trying to get " + searcher.Thing + " back to " + oldMap + " - " + oldPosition, true); ZUtils.TeleportThing(searcher.Thing, oldMap, oldPosition); recursiveTrap = false; CanBeSeenOverFast_Patch.checkLevels = false; CanBeSeenOverFast_Patch.upperMap = null; CanBeSeenOverFast_Patch.lowerMap = null; CanBeSeenOverFast_Patch.caster = null; } //else if (!multiMapSearch) //{ // ZLogger.Message("BestAttackTarget: multiMapSearch: " + multiMapSearch, true); //} return(result); }
static void Prefix(IAttackTargetSearcher searcher, ref TargetScanFlags flags) { var comp = searcher.CurrentEffectiveVerb?.EquipmentSource?.TryGetComp <CompLootAffixableThing>(); if (comp == null) { return; } // Does the weapon have the ShootThroughWalls modifier? if (!comp.AllModifiers.Any(lam => lam is LootAffixModifier_ShootThroughWalls)) { return; } // We don't need no line-of-sight flags &= ~(TargetScanFlags.NeedLOSToAll | TargetScanFlags.LOSBlockableByGas); }
protected override Thing FindAttackTarget(Pawn pawn) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (PrimaryVerbIsIncendiary(pawn)) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } var target = enemies.RandomElement(); if (target is null) { return((Thing)AttackTargetFinder.BestAttackTarget (pawn, targetScanFlags, (Thing x) => ExtraTargetValidator(pawn, x), 0f, pawn.Map.Size.x, GetFlagPosition(pawn), GetFlagRadius(pawn))); } return(target); }
// Token: 0x0600001E RID: 30 RVA: 0x00002B98 File Offset: 0x00000D98 protected virtual Thing FindAttackTarget(Pawn pawn) { TargetScanFlags targetScanFlags = TargetScanFlags.None; bool flag = this.needLOSToAcquireNonPawnTargets; if (flag) { targetScanFlags |= TargetScanFlags.None; } bool flag2 = this.PrimaryVerbIsIncendiary(pawn); if (flag2) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } float maxDist = pawn.equipment.PrimaryEq.verbTracker.PrimaryVerb.verbProps.range * 2f; return((Thing)AttackTargetFinder.BestAttackTarget(pawn, targetScanFlags, (Thing x) => this.ExtraTargetValidator(pawn, x), 0f, maxDist, this.GetFlagPosition(pawn), this.GetFlagRadius(pawn), true, true)); }
public static bool TryFindNewTarget(Building_TurretGun __instance, ref LocalTargetInfo __result) { Building_Turret building_Turret = __instance; IAttackTargetSearcher attackTargetSearcher = TargSearcher(__instance); Faction faction = attackTargetSearcher.Thing.Faction; float range = __instance.AttackVerb.verbProps.range; if (Rand.Value < 0.5f && __instance.AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && building_Turret.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x) { float num = __instance.AttackVerb.verbProps.EffectiveMinRange(x, __instance); float num2 = x.Position.DistanceToSquared(building_Turret.Position); return(num2 > num * num && num2 < range * range); }).TryRandomElement(out Building result)) { __result = result; return(false); } TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable; if (!__instance.AttackVerb.ProjectileFliesOverhead()) { targetScanFlags |= TargetScanFlags.NeedLOSToAll; targetScanFlags |= TargetScanFlags.LOSBlockableByGas; } if (__instance.AttackVerb.IsIncendiary()) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } if (IsMortar(__instance)) { targetScanFlags |= TargetScanFlags.NeedNotUnderThickRoof; } //return (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, IsValidTarget); __result = null; return(false); }
private Job RangedAttackJob(Pawn pawn, Thing target) { if (target == null) { return(null); } Verb verb = TryGetRangedVerb(pawn); if (verb == null) { return(null); } IntVec3 intVec; if (!this.TryFindShootPosition(pawn, target, out intVec)) { return(null); } if (intVec == pawn.Position) { TargetScanFlags targetScanFlags = TargetScanFlags.NeedLOSToAll; Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(pawn, null, verb.verbProps.range, verb.verbProps.minRange, targetScanFlags); if (thing != null) { return(new Job(DefDatabase <JobDef> .GetNamed("AnimalRangedAttack"), thing, (int)verb.verbProps.warmupTime, true) { verbToUse = verb }); } } // Find.PawnDestinationManager.ReserveDestinationFor(pawn, intVec); return(new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }); }
private Job TryGetAttackNearbyEnemyJob(Pawn pawn) { Job result; if (pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { result = null; } else { bool flag = pawn.equipment.Primary == null || pawn.equipment.Primary.def.IsMeleeWeapon; float num = 8f; if (!flag) { num = Mathf.Clamp(pawn.equipment.PrimaryEq.PrimaryVerb.verbProps.range * 0.66f, 2f, 20f); } TargetScanFlags flags = TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedReachableIfCantHitFromMyPos | TargetScanFlags.NeedThreat; float maxDist = num; Thing thing = (Thing)AttackTargetFinder.BestAttackTarget(pawn, flags, null, 0f, maxDist, default(IntVec3), float.MaxValue, false); if (thing == null) { result = null; } else if (flag || pawn.CanReachImmediate(thing, PathEndMode.Touch)) { result = new Job(JobDefOf.AttackMelee, thing); } else { result = new Job(JobDefOf.AttackStatic, thing) { maxNumStaticAttacks = 2, expiryInterval = 2000, endIfCantShootTargetFromCurPos = true }; } } return(result); }
// Token: 0x0600004A RID: 74 RVA: 0x00003EE8 File Offset: 0x000020E8 private void CheckForAutoAttack() { bool downed = this.pawn.Downed; if (!downed) { bool fullBodyBusy = this.pawn.stances.FullBodyBusy; if (!fullBodyBusy) { bool flag = this.pawn.jobs.jobQueue != null; if (!flag) { bool flag2 = this.pawn.Faction != null && this.pawn.jobs.curJob.def == WPJobDefOf.ArtyWaitCombat; if (flag2) { Verb currentEffectiveVerb = this.pawn.CurrentEffectiveVerb; bool flag3 = currentEffectiveVerb != null && !currentEffectiveVerb.verbProps.IsMeleeAttack; if (flag3) { TargetScanFlags targetScanFlags = TargetScanFlags.None; bool flag4 = currentEffectiveVerb.IsIncendiary(); if (flag4) { targetScanFlags |= TargetScanFlags.NeedNonBurning; } Thing thing = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this.pawn, targetScanFlags, null, 0f, 9999f); bool flag5 = thing != null; if (flag5) { this.pawn.TryStartAttack(thing); this.collideWithPawns = true; } } } } } } }
public LocalTargetInfo FindTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> verifier, float minDistance = 0, float maxDistance = 9999) { if (!(searcher.Thing is Building_Turret turret)) { return(LocalTargetInfo.Invalid); } var comp = turret.GetCompAutoChangeProj(); if (comp == null) { return(LocalTargetInfo.Invalid); } var locations = turret.Map.attackTargetsCache.targetsHostileToFaction[turret.Faction] .Select(t => t.Thing as Pawn) .Where(t => verifier(t)).Select(p => AutoMortarShellChoiceMod.Settings.TargetLeading ? CalculateIntercept(p, turret.Position, comp.Projectile.projectile.SpeedTilesPerTick) : p.Position); return(BestClusterPos(locations, comp.Projectile.projectile.explosionRadius)); }