public static bool OffhandTryStartCastOn(this Verb instance, LocalTargetInfo castTarg) { if (instance.caster == null) { Log.Error("Verb " + instance.GetUniqueLoadID() + " needs caster to work (possibly lost during saving/loading).", false); return(false); } if (!instance.caster.Spawned) { return(false); } if (instance.state == VerbState.Bursting || !instance.CanHitTarget(castTarg)) { return(false); } Traverse.Create(instance).Field("currentTarget").SetValue(castTarg); if (instance.CasterIsPawn && instance.verbProps.warmupTime > 0f) { ShootLine newShootLine; if (!instance.TryFindShootLineFromTo(instance.caster.Position, castTarg, out newShootLine)) { return(false); } instance.CasterPawn.Drawer.Notify_WarmingCastAlongLine(newShootLine, instance.caster.Position); float statValue = instance.CasterPawn.GetStatValue(StatDefOf.AimingDelayFactor, true); int ticks = (instance.verbProps.warmupTime * statValue).SecondsToTicks(); instance.CasterPawn.GetStancesOffHand().SetStance(new Stance_Warmup_DW(ticks, castTarg, instance)); } else { instance.WarmupComplete(); } return(true); }
public static bool ShotCalculationTipStringPrefix(ref string __result, Thing target) { StringBuilder stringBuilder = new StringBuilder(); if (Find.Selector.SingleSelectedThing != null) { Thing singleSelectedThing = Find.Selector.SingleSelectedThing; Verb verb = null; Pawn pawn = singleSelectedThing as Pawn; if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null) { Comp_VerbSaveable compsav = pawn.equipment.Primary.GetComp <Comp_VerbSaveable>(); if (compsav != null && compsav.tempVerb != null && compsav.tempVerb is Verb_LaunchProjectile) { verb = compsav.tempVerb; } else { verb = pawn.equipment.PrimaryEq.PrimaryVerb; } } Building_TurretGun building_TurretGun = singleSelectedThing as Building_TurretGun; if (building_TurretGun != null && building_TurretGun != target) { verb = building_TurretGun.AttackVerb; } if (verb != null) { stringBuilder.Append("ShotBy".Translate(Find.Selector.SingleSelectedThing.LabelShort, Find.Selector.SingleSelectedThing) + ": "); if (verb.CanHitTarget(target)) { stringBuilder.Append(ShotReport.HitReportFor(verb.caster, verb, target).GetTextReadout()); } else { stringBuilder.AppendLine("CannotHit".Translate()); } Pawn pawn2 = target as Pawn; if (pawn2 != null && pawn2.Faction == null && !pawn2.InAggroMentalState) { float manhunterOnDamageChance; if (verb.IsMeleeAttack) { manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, 0f, singleSelectedThing); } else { manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, singleSelectedThing); } if (manhunterOnDamageChance > 0f) { stringBuilder.AppendLine(); stringBuilder.AppendLine(string.Format("{0}: {1}", "ManhunterPerHit".Translate(), manhunterOnDamageChance.ToStringPercent())); } } } } __result = stringBuilder.ToString(); return(false); }
protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(null); if (verb == null) { return(null); } if (pawn.GetComp <CompWerewolf>() is CompWerewolf w && w.IsWerewolf) { if (!w.IsTransformed && w.IsBlooded) { w.TransformInto(w.HighestLevelForm, false); } } if (verb.verbProps.IsMeleeAttack) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } Job newJob = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; pawn.Map.pawnDestinationReservationManager.Reserve(pawn, newJob, intVec); return(newJob); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { // Log.Message("There is no valid target. Returning null"); return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); // Log.Message("allowManualCastWeapons: " + allowManualCastWeapons.ToString()); // Log.Message("attackVerb: " + verb.ToString()); if (verb == null) { Log.Error("pawn " + pawn.Label + " does not have attack verb"); } else if (verb.IsMeleeAttack) { // Log.Message("verb is melee attack. Passing to RimWorld.JobGiver_Manhunter ..."); } else { // Log.Message("verb is ranged attack"); bool isInCover = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool positionIsStandable = pawn.Position.Standable(pawn.Map); bool canHitEnemy = verb.CanHitTarget(enemyTarget); bool enemyNear = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((isInCover && positionIsStandable && canHitEnemy) || (enemyNear && canHitEnemy)) { // Log.Message("Can hit enemy from current position."); return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } return(new Job(JobDefOf.Goto, intVec) { expiryInterval = VEF_JobGiver_ManhunterRanged.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }); } return(null); }
protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; Job result; if (enemyTarget == null) { result = null; } else { bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { result = null; } else if (verb.verbProps.IsMeleeAttack) { result = this.MeleeAttackJob(enemyTarget); } else { bool flag = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; IntVec3 intVec; if ((flag && flag2 && flag3) || (flag4 && flag3)) { result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else if (!this.TryFindShootingPosition(pawn, out intVec)) { result = null; } else if (intVec == pawn.Position) { result = new Job(JobDefOf.Wait_Combat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true); } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } return(result); }
protected override Job TryGiveJob(Pawn pawn) { this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.MeleeRange) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.0099999997764825821; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if (flag && flag2 && flag3) { goto IL_00cf; } if (flag4 && flag3) { goto IL_00cf; } IntVec3 intVec = default(IntVec3); if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } Job job = new Job(JobDefOf.Goto, intVec); job.expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); IL_00cf: return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); }
protected override Job TryGiveJob(Pawn pawn) { if (HasRangedVerb(pawn)) { Thing pawn2 = this.FindPawnTarget(pawn); return(this.RangedAttackJob(pawn, pawn2)); } this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.MeleeRange) { return(this.MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)); } //pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, intVec); return(new Job(JobDefOf.Goto, intVec) { //expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }); }
public static Action GetRangedAttackAction(Pawn pawn, LocalTargetInfo target, out string failStr) { failStr = string.Empty; Verb curRangedVerb = pawn.GetComp <VEF_Comp_Pawn_RangedVerbs>().CurRangedVerb; if (pawn.GetComp <VEF_Comp_Pawn_RangedVerbs>().CurRangedVerb == null) { return(null); } if (!pawn.Drafted) { failStr = "IsNotDraftedLower".Translate(pawn.LabelShort, pawn); } else if (!pawn.IsColonistPlayerControlled) { failStr = "CannotOrderNonControlledLower".Translate(); } else if (target.IsValid && !curRangedVerb.CanHitTarget(target)) { if (!pawn.Position.InHorDistOf(target.Cell, curRangedVerb.verbProps.range)) { failStr = "OutOfRange".Translate(); } float num = curRangedVerb.verbProps.EffectiveMinRange(target, pawn); if ((float)pawn.Position.DistanceToSquared(target.Cell) < num * num) { failStr = "TooClose".Translate(); } else { failStr = "CannotHitTarget".Translate(); } } else if (pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { failStr = "IsIncapableOfViolenceLower".Translate(pawn.LabelShort, pawn); } else { if (pawn != target.Thing) { return(delegate() { Job job = new Job(JobDefOf.AttackStatic, target); pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); }); } failStr = "CannotAttackSelf".Translate(); } return(null); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } Pawn pawn2 = enemyTarget as Pawn; if (pawn2 != null && pawn2.IsInvisible()) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.IsMeleeAttack) { return(MeleeAttackJob(enemyTarget)); } bool num = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag = pawn.Position.Standable(pawn.Map) && pawn.Map.pawnDestinationReservationManager.CanReserve(pawn.Position, pawn, pawn.Drafted); bool flag2 = verb.CanHitTarget(enemyTarget); bool flag3 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((num && flag && flag2) || (flag3 && flag2)) { return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } if (!TryFindShootingPosition(pawn, out var dest)) { return(null); } if (dest == pawn.Position) { return(JobMaker.MakeJob(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } Job job = JobMaker.MakeJob(JobDefOf.Goto, dest); job.expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); }
private LocalTargetInfo CurrentTargetUnderMouse(bool mustBeHittableNowIfNotMelee) { LocalTargetInfo result; if (!this.IsTargeting) { result = LocalTargetInfo.Invalid; } else { TargetingParameters clickParams = (this.targetingVerb == null) ? this.targetParams : this.targetingVerb.verbProps.targetParams; LocalTargetInfo localTargetInfo = LocalTargetInfo.Invalid; using (IEnumerator <LocalTargetInfo> enumerator = GenUI.TargetsAtMouse(clickParams, false).GetEnumerator()) { if (enumerator.MoveNext()) { LocalTargetInfo localTargetInfo2 = enumerator.Current; localTargetInfo = localTargetInfo2; } } if (localTargetInfo.IsValid && mustBeHittableNowIfNotMelee && !(localTargetInfo.Thing is Pawn) && this.targetingVerb != null && !this.targetingVerb.verbProps.IsMeleeAttack) { if (this.targetingVerbAdditionalPawns != null && this.targetingVerbAdditionalPawns.Any <Pawn>()) { bool flag = false; for (int i = 0; i < this.targetingVerbAdditionalPawns.Count; i++) { Verb verb = this.GetTargetingVerb(this.targetingVerbAdditionalPawns[i]); if (verb != null && verb.CanHitTarget(localTargetInfo)) { flag = true; break; } } if (!flag) { localTargetInfo = LocalTargetInfo.Invalid; } } else if (!this.targetingVerb.CanHitTarget(localTargetInfo)) { localTargetInfo = LocalTargetInfo.Invalid; } } result = localTargetInfo; } return(result); }
private static LocalTargetInfo CurrentTargetUnderMouse(Targeter targeter, bool mustBeHittableNowIfNotMelee) { if (!targeter.IsTargeting) { return(LocalTargetInfo.Invalid); } var targetParams = Traverse.Create(targeter).Field("targetParams").GetValue <TargetingParameters>(); TargetingParameters clickParams = (targeter.targetingSource == null) ? targetParams : targeter.targetingSource.GetVerb.verbProps.targetParams; LocalTargetInfo localTargetInfo = LocalTargetInfo.Invalid; using (IEnumerator <LocalTargetInfo> enumerator = GenUI.TargetsAtMouse(clickParams, false).GetEnumerator()) { if (enumerator.MoveNext()) { LocalTargetInfo localTargetInfo2 = enumerator.Current; localTargetInfo = localTargetInfo2; } } if (localTargetInfo.IsValid && mustBeHittableNowIfNotMelee && !(localTargetInfo.Thing is Pawn) && targeter.targetingSource != null && !targeter.targetingSource.GetVerb.verbProps.IsMeleeAttack) { if (targeter.targetingSourceAdditionalPawns != null && targeter.targetingSourceAdditionalPawns.Any <Pawn>()) { bool flag = false; for (int i = 0; i < targeter.targetingSourceAdditionalPawns.Count; i++) { Verb verb = GetTargetingVerb(targeter, targeter.targetingSourceAdditionalPawns[i]); if (verb != null && verb.CanHitTarget(localTargetInfo)) { flag = true; break; } } if (!flag) { localTargetInfo = LocalTargetInfo.Invalid; } } else if (!targeter.targetingSource.CanHitTarget(localTargetInfo)) { localTargetInfo = LocalTargetInfo.Invalid; } } return(localTargetInfo); }
/* * public override float GetPriority(Pawn pawn) * { * return base.GetPriority(pawn); * } * * public override void ResolveReferences() * { * base.ResolveReferences(); * } * * public override string ToString() * { * return base.ToString(); * } * * public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) * { * return base.TryIssueJobPackage(pawn, jobParams); * } * * protected override void ResolveSubnodes() * { * base.ResolveSubnodes(); * }*/ protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing target = pawn.mindState.enemyTarget; if (target == null) { return(null); } Verb verb = pawn.TryGetAttackVerb(); if (verb == null) { return(null); } else if (verb.verbProps.MeleeRange) { return(MeleeAttackJob(target)); } if (((CoverUtility.CalculateOverallBlockChance(pawn.Position, target.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map)) || (pawn.Position - target.Position).LengthHorizontalSquared < 25) && verb.CanHitTarget(target)) { return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true)); } if (!TryFindShootingPosition(pawn, out IntVec3 intVec)) { return(null); } if (intVec == pawn.Position) { return(new Job(JobDefOf.WaitCombat, ExpiryTicks, true)); } Job job = new Job(JobDefOf.Goto, intVec); job.expiryInterval = ExpiryTicks; job.checkOverrideOnExpire = true; return(job); }
public bool TryStartCastOn(Verb verb, LocalTargetInfo castTarg, bool surpriseAttack = false, bool canHitNonTargetPawns = true) { if (verb.caster == null) { Log.Error("Verb " + this.GetUniqueLoadID() + " needs caster to work (possibly lost during saving/loading).", false); return(false); } if (!verb.caster.Spawned) { return(false); } if (verb.state == VerbState.Bursting || !verb.CanHitTarget(castTarg)) { return(false); } Patches_Misc_CE.Reflect <Boolean> .SetValue(verb, "surpriseAttack", surpriseAttack); Patches_Misc_CE.Reflect <Boolean> .SetValue(verb, "canHitNonTargetPawnsNow", canHitNonTargetPawns); Patches_Misc_CE.Reflect <LocalTargetInfo> .SetValue(verb, "currentTarget", castTarg); //verb.surpriseAttack = surpriseAttack; //verb.canHitNonTargetPawnsNow = canHitNonTargetPawns; //verb.currentTarget = castTarg; if (verb.CasterIsPawn && verb.verbProps.warmupTime > 0f) { ShootLine newShootLine; if (!verb.TryFindShootLineFromTo(verb.caster.Position, castTarg, out newShootLine)) { return(false); } verb.CasterPawn.Drawer.Notify_WarmingCastAlongLine(newShootLine, verb.caster.Position); float statValue = verb.CasterPawn.GetStatValue(StatDefOf.AimingDelayFactor, true); int ticks = (verb.verbProps.warmupTime * statValue).SecondsToTicks(); verb.CasterPawn.stances.SetStance(new Stance_Warmup(ticks, castTarg, verb)); } else { verb.WarmupComplete(); } return(true); }
protected override Job TryGiveJob(Pawn pawn) { UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { return(null); } bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { return(null); } if (verb.verbProps.IsMeleeAttack) { return(MeleeAttackJob(enemyTarget)); } bool flag = CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f; bool flag2 = pawn.Position.Standable(pawn.Map); bool flag3 = verb.CanHitTarget(enemyTarget); bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25; if ((flag && flag2 && flag3) || (flag4 && flag3)) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } if (!TryFindShootingPosition(pawn, out IntVec3 dest)) { return(null); } if (dest == pawn.Position) { return(new Job(JobDefOf.Wait_Combat, ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpiry: true)); } Job job = new Job(JobDefOf.Goto, dest); job.expiryInterval = ExpiryInterval_ShooterSucceeded.RandomInRange; job.checkOverrideOnExpire = true; return(job); }
public virtual void Tick() { if (!man.Pawn.Spawned) { return; } if (Verb.Bursting) { return; } if (cooldownTicksLeft > 0) { cooldownTicksLeft--; } if (cooldownTicksLeft > 0) { return; } if (!Enabled || !CanFire()) { if (currentTarget.IsValid) { currentTarget = LocalTargetInfo.Invalid; } if (warmUpTicksLeft > 0) { warmUpTicksLeft = 0; } return; } if (!currentTarget.IsValid || currentTarget.HasThing && currentTarget.ThingDestroyed || currentTarget.HasThing && currentTarget.Thing is Pawn p && (p.Downed || p.Dead) || !Verb.CanHitTarget(currentTarget)) { man.OverrideVerb = Verb; currentTarget = TryFindNewTarget(); man.OverrideVerb = null; TryStartCast(); }
private LocalTargetInfo CurrentTargetUnderMouse(bool mustBeHittableNowIfNotMelee) { if (!IsTargeting) { return(LocalTargetInfo.Invalid); } TargetingParameters targetingParameters = (targetingSource != null) ? targetingSource.targetParams : targetParams; LocalTargetInfo localTargetInfo = GenUI.TargetsAtMouse_NewTemp(targetingParameters, thingsOnly: false, targetingSource).FirstOrFallback(LocalTargetInfo.Invalid); if (localTargetInfo.IsValid && targetingSource != null) { if (mustBeHittableNowIfNotMelee && !(localTargetInfo.Thing is Pawn) && !targetingSource.IsMeleeAttack) { if (targetingSourceAdditionalPawns != null && targetingSourceAdditionalPawns.Any()) { bool flag = false; for (int i = 0; i < targetingSourceAdditionalPawns.Count; i++) { Verb targetingVerb = GetTargetingVerb(targetingSourceAdditionalPawns[i]); if (targetingVerb != null && targetingVerb.CanHitTarget(localTargetInfo)) { flag = true; break; } } if (!flag) { localTargetInfo = LocalTargetInfo.Invalid; } } else if (!targetingSource.CanHitTarget(localTargetInfo)) { localTargetInfo = LocalTargetInfo.Invalid; } } if (localTargetInfo == targetingSource.Caster && !targetingParameters.canTargetSelf) { localTargetInfo = LocalTargetInfo.Invalid; } } return(localTargetInfo); }
public static void TryStartCastOn_RapidFire_Prefix(ref Verb __instance, LocalTargetInfo castTarg, float __state, ref bool __result) { if (__instance.GetType() == typeof(Verb_Shoot)) { if (__instance.EquipmentSource != null && __instance.CasterPawn != null) { Pawn pawn = __instance.CasterPawn; if (castTarg != null /*&& castTarg.HasThing*/ && __instance.CanHitTarget(castTarg)) { if (__instance.EquipmentSource.TryGetComp <CompLaserCapacitor>() != null) { if (__instance.EquipmentSource.GetComp <CompLaserCapacitor>() is CompLaserCapacitor GunExt) { if (GunExt.initalized == false) { GunExt.originalwarmupTime = __instance.verbProps.warmupTime; GunExt.initalized = true; } if (GunExt.hotshot) { CompEquippable eq = __instance.EquipmentSource.TryGetComp <CompEquippable>(); IntVec3 lastpos = (IntVec3)GunExt.lastFiringLocation; if (lastpos == pawn.Position) { GunExt.shotstack++; __instance.verbProps.warmupTime = Math.Max(GunExt.originalwarmupTime - (GunExt.Props.WarmUpReductionPerShot * GunExt.shotstack), 0); } else { GunExt.shotstack = 0; __instance.verbProps.warmupTime = GunExt.originalwarmupTime; } GunExt.lastFiringLocation = pawn.Position; if (GunExt.Props.Overheats && __instance.verbProps.warmupTime == 0f) { if (Rand.Chance(GunExt.Props.OverheatChance)) { GunExt.CriticalOverheatExplosion((Verb_Shoot)__instance); if (GunExt.Props.OverheatDestroys) { eq.parent.Destroy(); } } else { if (GunExt.Props.OverheatMoteThrown != null) { MoteThrown moteThrown = (MoteThrown)ThingMaker.MakeThing(GunExt.Props.OverheatMoteThrown, null); moteThrown.Scale = Rand.Range(2f, 3f) * GunExt.Props.OverheatMoteSize; moteThrown.exactPosition = GunExt.lastFiringLocation.CenterVector3; moteThrown.rotationRate = Rand.Range(-0.5f, 0.5f); moteThrown.SetVelocity((float)Rand.Range(30, 40), Rand.Range(0.008f, 0.012f)); GenSpawn.Spawn(moteThrown, GunExt.lastFiringLocation.Cell, pawn.Map, WipeMode.Vanish); } } } } else { if (GunExt.originalwarmupTime != 0) { __instance.verbProps.warmupTime = GunExt.originalwarmupTime; } } } } } } } }
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); }
internal static string ShotCalculationTipString(Thing target) { StringBuilder stringBuilder = new StringBuilder(); if (Find.Selector.SingleSelectedThing != null) { Verb verb = null; Verb verbCR = null; Pawn pawn = Find.Selector.SingleSelectedThing as Pawn; if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectile) { verb = pawn.equipment.PrimaryEq.PrimaryVerb; } Building_TurretGun building_TurretGun = Find.Selector.SingleSelectedThing as Building_TurretGun; if (building_TurretGun != null && building_TurretGun != target) { verb = building_TurretGun.AttackVerb; } if (verb != null) { stringBuilder.AppendLine(); stringBuilder.Append("ShotBy".Translate(new object[] { Find.Selector.SingleSelectedThing.LabelShort }) + ": "); if (verb.CanHitTarget(target)) { stringBuilder.Append(ShotReport.HitReportFor(verb.caster, verb, target).GetTextReadout()); } else { stringBuilder.Append("CannotHit".Translate()); } } // Append CR tooltip else { if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectileCR) { verbCR = pawn.equipment.PrimaryEq.PrimaryVerb; } Building_TurretGun building_TurretGun2 = Find.Selector.SingleSelectedThing as Building_TurretGun; if (building_TurretGun != null && building_TurretGun != target) { verbCR = building_TurretGun.AttackVerb; } if (verbCR != null) { stringBuilder.AppendLine(); // stringBuilder.Append("ShotBy".Translate(new object[] { pawn.LabelShort }) + ":\n"); stringBuilder.Append("Shot stat. temporarily unavailable!"); if (verbCR.CanHitTarget(target)) { // stringBuilder.Append(ShiftVecReportFor(target).GetTextReadout()); } else { stringBuilder.Append("CannotHit".Translate()); } } } } return(stringBuilder.ToString()); }
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: 0x06000031 RID: 49 RVA: 0x00002C44 File Offset: 0x00000E44 protected override Job TryGiveJob(Pawn pawn) { MentalState_Fighter state = (MentalState_Fighter)pawn.MentalState; Pawn pawnTarget = state.otherPawn; Building_Bell bellRef = state.bellRef; Job result; Fighter fighterTarget = bellRef.getFighter(pawnTarget); if (!fighterTarget.isInFight || (double)Rand.Value < 0.5) { result = new Job(JobDefOf.Wait_Combat) { expiryInterval = 10 }; } else { if (pawn.TryGetAttackVerb(null, false) == null) { result = null; } else { ThingWithComps primary = pawn.equipment != null ? pawn.equipment.Primary : null; if (bellRef.currentState == Building_Bell.State.fight && pawn.equipment != null && primary == null) { List <Thing> suitableWeapons = new List <Thing>(); foreach (IntVec3 c in bellRef.GetComp <CompBell>().ValidCells) { List <Thing> thingList = c.GetThingList(bellRef.Map); for (int i = 0; i < thingList.Count; i++) { Thing t = thingList[i]; bool flag8 = t.def.IsWeapon && !suitableWeapons.Contains(t) && t.Spawned && pawn.CanReserve(t, 1, -1, null, false); if (flag8) { suitableWeapons.Add(t); } } } Thing weapon = null; int maxDistance = 9999; foreach (Thing t2 in suitableWeapons) { if ((t2.Position - pawn.Position).LengthManhattan < maxDistance) { weapon = t2; maxDistance = (t2.Position - pawn.Position).LengthManhattan; } } if (weapon != null) { return(new Job(JobDefOf.Equip, weapon)); } } if (pawnTarget == null || !pawn.CanReach(pawnTarget, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { result = new Job(JobDefOf.Wait); } else { pawn.mindState.enemyTarget = pawnTarget; pawn.mindState.enemyTarget = pawnTarget; this.UpdateEnemyTarget(pawn); Thing enemyTarget = pawn.mindState.enemyTarget; if (enemyTarget == null) { result = null; } else { bool allowManualCastWeapons = !pawn.IsColonist; Verb verb = pawn.TryGetAttackVerb(enemyTarget, allowManualCastWeapons); if (verb == null) { result = null; } else { bool isMeleeAttack = verb.verbProps.IsMeleeAttack; if (isMeleeAttack || pawnTarget.Downed) { result = this.MeleeAttackJob(enemyTarget); result.killIncappedTarget = bellRef.toDeath; } else { if (( CoverUtility.CalculateOverallBlockChance(pawn, enemyTarget.Position, pawn.Map) > 0.01f && pawn.Position.Standable(pawn.Map) && verb.CanHitTarget(enemyTarget) ) || ( (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25 && verb.CanHitTarget(enemyTarget) )) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { IntVec3 intVec; if (!this.TryFindShootingPosition(pawn, out intVec)) { result = null; } else { if (intVec == pawn.Position) { result = new Job(JobDefOf.AttackStatic, pawnTarget) { maxNumMeleeAttacks = 1, expiryInterval = Rand.Range(420, 900), canBash = true }; } else { result = new Job(JobDefOf.Goto, intVec) { expiryInterval = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, checkOverrideOnExpire = true }; } } } } } } } } } return(result); }
static bool Prefix(Verb __instance, ref LocalTargetInfo castTarg, ref bool surpriseAttack, ref bool canFreeIntercept) { Pawn pawn = __instance.CasterPawn; if (__instance.caster == null) { Log.Error("Verb " + __instance.GetUniqueLoadID() + " needs caster to work (possibly lost during saving/loading)."); return(false); } if (!__instance.caster.Spawned) { return(false); } if (__instance.state == VerbState.Bursting || !__instance.CanHitTarget(castTarg)) { return(false); } if (__instance.verbProps.CausesTimeSlowdown && castTarg.HasThing && (castTarg.Thing.def.category == ThingCategory.Pawn || (castTarg.Thing.def.building != null && castTarg.Thing.def.building.IsTurret)) && castTarg.Thing.Faction == Faction.OfPlayer && __instance.caster.HostileTo(Faction.OfPlayer)) { Find.TickManager.slower.SignalForceNormalSpeed(); } if (__instance.CasterIsPawn) { CompRunAndGun comp = pawn.TryGetComp <CompRunAndGun>(); if (comp == null || !comp.isEnabled || pawn.jobs.curJob.def != JobDefOf.Goto) { return(true); } } if (!__instance.CasterIsPawn) { return(true); } if ((__instance.CasterPawn.stances.curStance is Stance_RunAndGun) || (__instance.CasterPawn.stances.curStance is Stance_RunAndGun_Cooldown)) { return(false); } Traverse.Create(__instance).Field("surpriseAttack").SetValue(surpriseAttack); Traverse.Create(__instance).Field("canFreeInterceptNow").SetValue(canFreeIntercept); Traverse.Create(__instance).Field("currentTarget").SetValue(castTarg); if (__instance.CasterIsPawn && __instance.verbProps.warmupTime > 0f) { ShootLine newShootLine; if (!__instance.TryFindShootLineFromTo(__instance.caster.Position, castTarg, out newShootLine)) { return(false); } __instance.CasterPawn.Drawer.Notify_WarmingCastAlongLine(newShootLine, __instance.caster.Position); float statValue = __instance.CasterPawn.GetStatValue(StatDefOf.AimingDelayFactor, true); int ticks = (__instance.verbProps.warmupTime * statValue).SecondsToTicks(); __instance.CasterPawn.stances.SetStance(new Stance_RunAndGun(ticks, castTarg, __instance)); } else { __instance.WarmupComplete(); } return(false); }