private static float GetAccuracy(Thing weapon, VerbProperties verb, ProjectileProperties projectile, float dist, Pawn pawn = null) { float forcedMissRadius = CalculateAdjustedForcedMissDist(verb.ForcedMissRadius, dist); float baseAimOn = verb.GetHitChanceFactor(weapon, dist); if (pawn != null) { baseAimOn *= ShotReport.HitFactorFromShooter(pawn, dist); } int affectedCellCount = (verb.CausesExplosion) ? GenRadial.NumCellsInRadius(projectile.explosionRadius) : 1; float accuracy; if (forcedMissRadius > 0.5f) { int affectableCellCount = GenRadial.NumCellsInRadius(forcedMissRadius); accuracy = (float)affectedCellCount / affectableCellCount; } else { float medianToWildRadius = ShootTuning.MissDistanceFromAimOnChanceCurves.Evaluate(baseAimOn, 0.5f); float indirectHitChance = (float)(affectedCellCount - 1) / GenRadial.NumCellsInRadius(medianToWildRadius); accuracy = baseAimOn + (1f - baseAimOn) * indirectHitChance; } return(Mathf.Clamp01(accuracy)); }
private static float VerbScore(Pawn p, Verb verb, LocalTargetInfo target, bool debug = false) { if (debug) { Log.Message("Getting score of " + verb + " with target " + target); } if (verb is IVerbScore score) { return(score.GetScore(p, target)); } var accuracy = 0f; if (p.Map != null) { accuracy = ShotReport.HitReportFor(p, verb, target).TotalEstimatedHitChance; } else if (verb.TryFindShootLineFromTo(p.Position, target, out var line)) { accuracy = verb.verbProps.GetHitChanceFactor(verb.EquipmentSource, p.Position.DistanceTo(target.Cell)); } var damage = accuracy * verb.verbProps.burstShotCount * GetDamage(verb); var timeSpent = verb.verbProps.AdjustedCooldownTicks(verb, p) + verb.verbProps.warmupTime.SecondsToTicks(); if (debug) { Log.Message("Accuracy: " + accuracy); Log.Message("Damage: " + damage); Log.Message("timeSpent: " + timeSpent); Log.Message("Score of " + verb + " on target " + target + " is " + damage / timeSpent); } return(damage / timeSpent); }
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); }
public static void Prefix(ref ShotReport __result, Thing caster, Verb verb, LocalTargetInfo target) { var projectileClass = verb.GetProjectile()?.thingClass; if (projectileClass != null && typeof(TeslaProjectile).IsAssignableFrom(projectileClass)) { accuracy = true; } }
// Token: 0x06002252 RID: 8786 RVA: 0x000D128C File Offset: 0x000CF48C protected override bool TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = this.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } Vector3 drawPos = this.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish); ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true); }
/// <summary> /// Gets the adjusted hit chance factor of a shot. This is equivalent to shootVerb.GetHitChanceFactor() unless /// a shooter is provided, in which case it will also be adjusted based on the shooter's hit chance. /// /// This value can be greater than 1.0 in the case of weapons with overcapped accuracy. /// </summary> /// <returns>The adjusted hit chance factor.</returns> /// <param name="range">The range of the shot.</param> /// <param name="shooter">(Optional) The turret or pawn shooting the weapon.</param> public float GetAdjustedHitChanceFactor(float range, Thing shooter = null) { float hitChance = shootVerb.GetHitChanceFactor(weapon, range); if (shooter != null) { hitChance *= ShotReport.HitFactorFromShooter(shooter, range); } return(hitChance); }
private static float VerbScore(Pawn p, Verb verb, LocalTargetInfo target, bool debug = false) { if (debug) { Log.Message("Getting score of " + verb + " with target " + target); } var report = ShotReport.HitReportFor(p, verb, target); var damage = report.TotalEstimatedHitChance * verb.verbProps.burstShotCount * GetDamage(verb); var timeSpent = verb.verbProps.AdjustedCooldownTicks(verb, p) + verb.verbProps.warmupTime.SecondsToTicks(); return(damage / timeSpent); }
public override string GetExplanationFinalizePart(StatRequest req, ToStringNumberSense numberSense, float finalVal) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 5; i <= 45; i += 5) { float f = ShotReport.HitFactorFromShooter(finalVal, i); stringBuilder.AppendLine("distance".Translate().CapitalizeFirst() + " " + i.ToString() + ": " + f.ToStringPercent("F1")); } stringBuilder.AppendLine(base.GetExplanationFinalizePart(req, numberSense, finalVal)); return(stringBuilder.ToString()); }
public static void HitReportFor_Postfix( ref ShotReport __result, Thing caster, Verb verb, LocalTargetInfo target ) { if (caster is Pawn pawn && pawn.TryGetComp <Comp_NightVision>() is Comp_NightVision comp) { CurrentShot.Caster = caster; CurrentShot.Verb = verb; CurrentShot.GlowFactor = CombatHelpers.GlowFactorForPawnAtTarget(pawn, target, comp); }
private static float FriendlyFireConeTargetScoreOffset( IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { if (!(searcher.Thing is Pawn thing) || thing.RaceProps.intelligence < Intelligence.ToolUser || (thing.RaceProps.IsMechanoid || !(verb is Verb_Shoot verbShoot))) { return(0.0f); } ThingDef defaultProjectile = verbShoot.verbProps.defaultProjectile; if (defaultProjectile == null || defaultProjectile.projectile.flyOverhead) { return(0.0f); } Map map = thing.Map; ShotReport report = ShotReport.HitReportFor((Thing)thing, verb, (LocalTargetInfo)(Thing)target); double forcedMissRadius = (double)verb.verbProps.forcedMissRadius; IntVec3 dest1 = report.ShootLine.Dest; ShootLine shootLine = report.ShootLine; IntVec3 source = shootLine.Source; IntVec3 vector = dest1 - source; float radius = Mathf.Max(VerbUtility.CalculateAdjustedForcedMiss((float)forcedMissRadius, vector), 1.5f); shootLine = report.ShootLine; IEnumerable <IntVec3> intVec3s = GenRadial.RadialCellsAround(shootLine.Dest, radius, true).Where <IntVec3>((Func <IntVec3, bool>)(dest => dest.InBounds(map))).Select <IntVec3, ShootLine>((Func <IntVec3, ShootLine>)(dest => new ShootLine(report.ShootLine.Source, dest))).SelectMany <ShootLine, IntVec3>((Func <ShootLine, IEnumerable <IntVec3> >)(line => line.Points().Concat <IntVec3>(line.Dest).TakeWhile <IntVec3>((Func <IntVec3, bool>)(pos => pos.CanBeSeenOverFast(map))))).Distinct <IntVec3>(); float num1 = 0.0f; foreach (IntVec3 c in intVec3s) { shootLine = report.ShootLine; float num2 = VerbUtility.InterceptChanceFactorFromDistance(shootLine.Source.ToVector3Shifted(), c); if ((double)num2 > 0.0) { List <Thing> thingList = c.GetThingList(map); for (int index = 0; index < thingList.Count; ++index) { Thing b = thingList[index]; if (b is IAttackTarget && b != target) { float num3 = (b != searcher ? (!(b is Pawn) ? 10f : (b.def.race.Animal ? 7f : 18f)) : 40f) * num2; float num4 = !searcher.Thing.HostileTo(b) ? num3 * -1f : num3 * 0.6f; num1 += num4; } } } } return(num1); }
public float GetAimOnTargetChance() { var distance = (Target - Origin).LengthHorizontal; var factorFromShooterAndDist = ShotReport.HitFactorFromShooter(Caster, distance); var factorFromEquipment = _weaponVerb.verbProps.GetHitChanceFactor( _weaponVerb.EquipmentSource, distance); var factorFromWeather = 1f; if (!Caster.Position.Roofed(CasterMap) || !Target.Roofed(CasterMap)) { factorFromWeather = CasterMap.weatherManager.CurWeatherAccuracyMultiplier; } ThingDef coveringGas = null; foreach (var point in GenSight.PointsOnLineOfSight(Origin, Target)) { if (!point.CanBeSeenOver(CasterMap)) { break; } Thing gas = point.GetGas(CasterMap); if (IsThisGasMorePenalisingThan(gas, coveringGas)) { coveringGas = gas.def; } } var factorFromCoveringGas = 1f - (coveringGas?.gas.accuracyPenalty ?? 0f); var result = factorFromShooterAndDist * factorFromEquipment * factorFromWeather * factorFromCoveringGas; if (result < 0.0201f) { result = 0.0201f; } return(result); }
public override float GetValueUnfinalized(StatRequest req, bool applyPostProcess = true) { if (!(req.Def is ThingDef def)) { return(0.0f); } CompEquippable equipComp = null; CompLootAffixableThing lootComp = null; if (req.HasThing) { var thing = (ThingWithComps)req.Thing; equipComp = thing.TryGetComp <CompEquippable>(); lootComp = thing.TryGetComp <CompLootAffixableThing>(); } Verb verb = equipComp?.AllVerbs.First(v => v.verbProps.isPrimary); VerbProperties verbProps = verb != null ? verb.verbProps : def.Verbs.First(vp => vp.isPrimary); Pawn attacker = req.HasThing ? GetCurrentWeaponUser(req.Thing) : null; var projProps = verbProps.defaultProjectile.projectile; var projModifier = (LootAffixModifier_VerbPropertiesChange_Def)lootComp?.AllModifiers.FirstOrFallback( lam => lam.AppliesTo == ModifierTarget.VerbProperties && lam is LootAffixModifier_VerbPropertiesChange_Def lamVPCD && lamVPCD.affectedField == "defaultProjectile" ); ThingDef modProjectile = projModifier != null ? (ThingDef)projModifier.resolvedDef : null; var modProjProps = modProjectile?.projectile; float chance = modProjProps != null ? 1f - projModifier.GetRealChance(lootComp.parent) : 1f; if (chance <= 0.05f) { chance = 1f; // already permanently set to "base" verbProps } float baseDamage = projProps.damageDef.harmsHealth == false ? 0f : req.HasThing ? projProps.GetDamageAmount(req.Thing) : req.StuffDef != null?projProps.GetDamageAmount(def.GetStatValueAbstract(StatDefOf.RangedWeapon_DamageMultiplier, req.StuffDef)) : projProps.GetDamageAmount(def.GetStatValueAbstract(StatDefOf.RangedWeapon_DamageMultiplier)) ; float damage = baseDamage * verbProps.burstShotCount * chance; if (chance < 1f) { float modChance = 1f - chance; float modBaseDamage = modProjProps.damageDef.harmsHealth == false ? 0f : modProjProps.GetDamageAmount(req.Thing) ; damage += modBaseDamage * verbProps.burstShotCount * modChance; } // FIXME: Confirm warmupTime (and AimingDelayFactor) is used in a full shot cycle // FIXME: warmupTime * this.CasterPawn.GetStatValue(StatDefOf.AimingDelayFactor, true)).SecondsToTicks() float secondsSpent = 0; if (verb != null) { secondsSpent = verbProps.AdjustedFullCycleTime(verb, attacker); } else { secondsSpent = verbProps.warmupTime + ((verbProps.burstShotCount - 1) * verbProps.ticksBetweenBurstShots).TicksToSeconds(); secondsSpent += req.HasThing ? req.Thing.GetStatValue(StatDefOf.RangedWeapon_Cooldown, true) : req.StuffDef != null?def.GetStatValueAbstract(StatDefOf.RangedWeapon_Cooldown, req.StuffDef) : def.GetStatValueAbstract(StatDefOf.RangedWeapon_Cooldown) ; } // Every integer range possible as an average float avgAccuracy = 0; for (int i = 3; i <= verbProps.range; i++) { float rngAccuracy = verbProps.GetHitChanceFactor(req.Thing, i); if (attacker != null) { rngAccuracy *= ShotReport.HitFactorFromShooter(attacker, i); } avgAccuracy += rngAccuracy; } if (verbProps.range >= 3) { avgAccuracy /= verbProps.range - 2; } return(secondsSpent == 0 ? 0.0f : damage / secondsSpent * avgAccuracy); }
public bool TryCastShot_V1Vanilla_Modified() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } var flag = TryFindShootLineFromTo(caster.Position, currentTarget, out var shootLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false); } var drawPos = caster.DrawPos; var projectile = (Projectile)GenSpawn.Spawn(verbProps.defaultProjectile, shootLine.Source, caster.Map); ///MODIFIED SECTION //////////////////////////////////////////// if (lastShotReflected) { ////Log.Message("lastShotReflected Called"); projectile.Launch(caster, currentTarget, currentTarget, ProjectileHitFlags.IntendedTarget, preventFriendlyFire, EquipmentSource); return(true); } //////////////////////////////////////////// // //projectile.FreeIntercept = canFreeInterceptNow && !projectile.def.projectile.flyOverhead; var forcedMissRadius = verbProps.ForcedMissRadius; if (forcedMissRadius > 0.5f) { var num = VerbUtility.CalculateAdjustedForcedMiss(forcedMissRadius, currentTarget.Cell - caster.Position); if (num > 0.5f) { var max = GenRadial.NumCellsInRadius(forcedMissRadius); var num2 = Rand.Range(0, max); if (num2 > 0) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToForRad"); // TODO: Translate()? } var c = currentTarget.Cell + GenRadial.RadialPattern[num2]; ProjectileHitFlags projectileHitFlags; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.NonTargetWorld; } else { projectileHitFlags = ProjectileHitFlags.All; } if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile.Launch(caster, currentTarget, c, projectileHitFlags, preventFriendlyFire, EquipmentSource); return(true); } } } var shotReport = ShotReport.HitReportFor(caster, this, currentTarget); var randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); var targetCoverDef = randomCoverToMissInto?.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToWild"); // TODO: Translate()? } shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ProjectileHitFlags projectileHitFlags2; if (Rand.Chance(0.5f)) { projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; } else { projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } } projectile.Launch(caster, currentTarget, shootLine.Dest, projectileHitFlags2, preventFriendlyFire, EquipmentSource); return(true); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover"); // TODO: Translate()? } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn) { var projectileHitFlags5 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags5 |= ProjectileHitFlags.NonTargetPawns; } projectile.Launch(caster, currentTarget, randomCoverToMissInto, projectileHitFlags5, preventFriendlyFire, EquipmentSource); return(true); } } else { if (!Rand.Chance(shotReport.PassCoverChance)) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover"); // TODO: Translate()? } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn) { var projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile.Launch(caster, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, preventFriendlyFire, EquipmentSource, targetCoverDef); return(true); } } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit"); // TODO: Translate()? } var projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } if (currentTarget.Thing != null) { projectile.Launch(caster, drawPos, currentTarget, currentTarget, projectileHitFlags4, preventFriendlyFire, EquipmentSource, targetCoverDef); } else { projectile.Launch(caster, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, preventFriendlyFire, EquipmentSource, targetCoverDef); } return(true); } return(false); }
// Token: 0x0600640C RID: 25612 RVA: 0x001B4770 File Offset: 0x001B2B70 protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } var shootLine = new ShootLine(); if (verbProps.stopBurstWithoutLos && !TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine)) { return(false); } var comp = EquipmentSource?.GetComp <CompChangeableProjectile>(); comp?.Notify_ProjectileLaunched(); var compMannable = caster.TryGetComp <CompMannable>(); if (compMannable?.ManningPawn != null) { } SpawnBeam(); hitThing(); var shotReport = ShotReport.HitReportFor(caster, this, currentTarget); var randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); var unused = randomCoverToMissInto?.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); var nonTargetWorld = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { nonTargetWorld |= ProjectileHitFlags.NonTargetPawns; } return(true); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { var projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } return(true); } var projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } return(true); }
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()); }
protected new bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget) { ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, launchTarget, out shootLine); bool flag2 = this.verbProps.stopBurstWithoutLos && !flag; bool? result; if (flag2) { result = new bool?(false); } else { Vector3 drawPos = this.caster.DrawPos; Projectile projectile = (Projectile)GenSpawn.Spawn(projectileDef, shootLine.Source, this.caster.Map, WipeMode.Vanish); SoundDef soundCast = this.verbProps.soundCast; if (soundCast != null) { soundCast.PlayOneShot(new TargetInfo(this.caster.Position, this.caster.Map, false)); } SoundDef soundCastTail = this.verbProps.soundCastTail; if (soundCastTail != null) { soundCastTail.PlayOneShotOnCamera(null); } bool drawShooting = DebugViewSettings.drawShooting; if (drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f); } ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.IntendedTarget; bool canHitNonTargetPawnsNow = this.canHitNonTargetPawnsNow; if (canHitNonTargetPawnsNow) { projectileHitFlags |= ProjectileHitFlags.NonTargetPawns; } bool flag3 = !this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full; if (flag3) { projectileHitFlags |= ProjectileHitFlags.NonTargetWorld; } // miss chance ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture) && !((VerbProperties_Ability)verbProps).AlwaysHits) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } projectile.Launch(caster, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, null, targetCoverDef); return(true); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance) && !((VerbProperties_Ability)verbProps).AlwaysHits) { ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile.Launch(caster, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, null, targetCoverDef); return(true); } // miss chance end projectile.Launch(caster, launchTarget, launchTarget, projectileHitFlags, null); result = new bool?(true); } return(result); }
/// <summary> /// Tries the cast shot. /// </summary> /// <returns></returns> protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } ThingDef projectile = Projectile; if (projectile == null) { return(false); } ShootLine resultingLine; bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { base.EquipmentSource.GetComp <CompChangeableProjectile>()?.Notify_ProjectileLaunched(); } Thing launcher = caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 drawPos = caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map); if (verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = randomCoverToMissInto?.def; //never miss ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef); } else { projectile2.Launch(launcher, drawPos, resultingLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef); } return(true); }
// Token: 0x0600651E RID: 25886 RVA: 0x001B8BC0 File Offset: 0x001B6FC0 public static bool TryCastExtraShot(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance, LocalTargetInfo currentTarget, bool canHitNonTargetPawnsNow) { if (currentTarget.HasThing && currentTarget.Thing.Map != __instance.caster.Map) { return(false); } ThingDef projectile = __instance.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = __instance.TryFindShootLineFromTo(__instance.caster.Position, currentTarget, out shootLine); if (__instance.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (__instance.EquipmentSource != null) { CompChangeableProjectile comp = __instance.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = __instance.caster; Thing equipment = __instance.EquipmentSource; CompMannable compMannable = __instance.caster.TryGetCompFast <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = __instance.caster; } Vector3 drawPos = __instance.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, __instance.caster.Map, WipeMode.Vanish); if (__instance.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(__instance.verbProps.forcedMissRadius, currentTarget.Cell - __instance.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); Rand.PushState(); int num2 = Rand.Range(0, max); Rand.PopState(); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } Rand.PopState(); if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(__instance.caster, __instance, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = randomCoverToMissInto?.def; Rand.PushState(); bool f1 = !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture); Rand.PopState(); if (f1) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } Rand.PopState(); projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true); } Rand.PushState(); bool f2 = !Rand.Chance(shotReport.PassCoverChance); Rand.PopState(); if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && f2) { ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } if (currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef); } return(true); }
// Token: 0x060057CC RID: 22476 RVA: 0x0017B880 File Offset: 0x00179C80 protected override bool TryCastShot() { //If we are aiming at something real on the map if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } //Check to see if we have line of sight ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (this.ownerEquipment != null) { CompChangeableProjectile comp = this.ownerEquipment.GetComp <CompChangeableProjectile>(); if (comp != null) { //!!!!!!!!!!!!!!!! This could be used to subtract from a battery pack comp.Notify_ProjectileLaunched(); } } //Launcher is the user; equipment is what is being used to shoot Thing launcher = this.caster; Thing equipment = this.ownerEquipment; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } //This drawPos may need to be modified so that the beam emerges from the weapon and not the user Vector3 drawPos = this.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map); //Can the projectile strike something on its flightpath? projectile2.FreeIntercept = (this.canFreeInterceptNow && !projectile2.def.projectile.flyOverhead); //ShotReport gives us our chance that the shot actual hit ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); //If the shot was a miss... if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f); } //Modify the shoot line to hit something else shootLine.ChangeDestToMissWild(); if (this.currentTarget.HasThing) { //Ensure that the projectile actually hits something else projectile2.ThingToNeverIntercept = this.currentTarget.Thing; } if (!projectile2.def.projectile.flyOverhead) { projectile2.InterceptWalls = true; } //Launch doomed projectile for shootLine's bad destination //Consider giving the beam projectile a function to switch destinations when something gets between launcher and shootLine.Dest projectile2.Launch(launcher, drawPos, shootLine.Dest, equipment, this.currentTarget.Thing); return(true); } if (Rand.Value > shotReport.ChanceToNotHitCover) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn) { Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); if (!projectile2.def.projectile.flyOverhead) { projectile2.InterceptWalls = true; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, equipment, this.currentTarget.Thing); return(true); } } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f); } if (!projectile2.def.projectile.flyOverhead) { projectile2.InterceptWalls = (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full); } if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, this.currentTarget, equipment, this.currentTarget.Thing); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, equipment, this.currentTarget.Thing); } return(true); }
protected new bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget) { DebugMessage(launchTarget.ToString()); var flag = TryFindShootLineFromTo(caster.Position, launchTarget, out var shootLine); if (verbProps.stopBurstWithoutLos && !flag) { DebugMessage("Targeting cancelled"); return(false); } var drawPos = caster.DrawPos; var projectile2 = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, caster.Map); projectile2.extraDamages = UseAbilityProps.extraDamages; projectile2.localSpawnThings = UseAbilityProps.thingsToSpawn; verbProps.soundCast?.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false)); verbProps.soundCastTail?.PlayOneShotOnCamera(); if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit", -1f); } if (this.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } // projectile2.Launch(CasterPawn, drawPos, c, this.currentTarget, projectileHitFlags, caster, null); projectile2.Launch(caster, Ability.Def, drawPos, c, projectileHitFlags, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } // projectile2.Launch(CasterPawn, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, caster, targetCoverDef); projectile2.Launch(caster, Ability.Def, drawPos, shootLine.Dest, projectileHitFlags2, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); return(true); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { this.ThrowDebugText("ToCover" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } // projectile2.Launch(CasterPawn, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, caster, targetCoverDef); projectile2.Launch(caster, Ability.Def, drawPos, randomCoverToMissInto, projectileHitFlags3, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + ((!this.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); if (this.currentTarget.Thing != null) { // projectile2.Launch(CasterPawn, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, caster, targetCoverDef); projectile2.Launch(caster, Ability.Def, drawPos, currentTarget, projectileHitFlags4, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { // projectile2.Launch(CasterPawn, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, caster, targetCoverDef); projectile2.Launch(caster, Ability.Def, drawPos, shootLine.Dest, projectileHitFlags4, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } /* * ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; * if (this.canHitNonTargetPawnsNow) * { * projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; * } * if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) * { * projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; * } * DebugMessage(launchTarget.ToString()); * projectile2.Launch(caster, Ability.Def, drawPos, launchTarget, projectileHitFlags4, null, * UseAbilityProps.hediffsToApply, * UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); */ return(true); }
private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { if (!(searcher.Thing is Pawn pawn)) { return(0f); } if (pawn.RaceProps.intelligence < Intelligence.ToolUser) { return(0f); } if (pawn.RaceProps.IsMechanoid) { return(0f); } if (!(verb is Verb_Shoot verb_Shoot)) { return(0f); } ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile; if (defaultProjectile == null) { return(0f); } if (defaultProjectile.projectile.flyOverhead) { return(0f); } Map map = pawn.Map; ShotReport report = ShotReport.HitReportFor(pawn, verb, (Thing)target); float a = VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source); float radius = Mathf.Max(a, 1.5f); IntVec3 dest2 = report.ShootLine.Dest; IEnumerable <IntVec3> source = from dest in GenRadial.RadialCellsAround(dest2, radius, true) where dest.InBounds(map) select dest; IEnumerable <ShootLine> source2 = from dest in source select new ShootLine(report.ShootLine.Source, dest); IEnumerable <IntVec3> source3 = source2.SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map))); IEnumerable <IntVec3> enumerable = source3.Distinct <IntVec3>(); float num = 0f; foreach (IntVec3 c in enumerable) { float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), c); if (num2 > 0f) { List <Thing> thingList = c.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing is IAttackTarget && thing != target) { float num3; if (thing == searcher) { num3 = 40f; } else if (thing is Pawn) { num3 = ((!thing.def.race.Animal) ? 18f : 7f); } else { num3 = 10f; } num3 *= num2; if (searcher.Thing.HostileTo(thing)) { num3 *= 0.6f; } else { num3 *= -1f; } num += num3; } } } } return(num); }
protected bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget) { DebugMessage(launchTarget.ToString()); var flag = TryFindShootLineFromTo(caster.Position, launchTarget, out var shootLine); if (verbProps.stopBurstWithoutLos && !flag) { DebugMessage("Targeting cancelled"); return(false); } var drawPos = caster.DrawPos; var projectile = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, caster.Map); projectile.extraDamages = UseAbilityProps.extraDamages; projectile.localSpawnThings = UseAbilityProps.thingsToSpawn; //projectile. FreeIntercept = canFreeInterceptNow && !projectile.def.projectile.flyOverhead; var shotReport = ShotReport.HitReportFor(caster, this, launchTarget); verbProps.soundCast?.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false)); verbProps.soundCastTail?.PlayOneShotOnCamera(); // if (!UseAbilityProps.AlwaysHits) // { // Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); // ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; // if (!Rand.Chance(shotReport.ChanceToNotGoWild_IgnoringPosture)) // { // if (DebugViewSettings.drawShooting) // MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToWild", -1f); // shootLine.ChangeDestToMissWild(); // ProjectileHitFlags projectileHitFlags2; // if (Rand.Chance(0.5f)) // { // projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; // } // else // { // projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; // if (this.canHitNonTargetPawnsNow) // { // projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; // } // } // projectile.Launch(caster, Ability.Def, drawPos, shootLine.Dest, projectileHitFlags2, EquipmentSource, // UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, // UseAbilityProps.thingsToSpawn); // return true; // } // if (!Rand.Chance(shotReport.ChanceToNotHitCover)) // { // if (DebugViewSettings.drawShooting) // MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToCover", -1f); // if (launchTarget.Thing != null && launchTarget.Thing.def.category == ThingCategory.Pawn) // { // randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); // ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; // if (this.canHitNonTargetPawnsNow) // { // projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; // } // projectile.Launch(caster, Ability.Def, drawPos, randomCoverToMissInto, projectileHitFlags3, null, // UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, // UseAbilityProps.thingsToSpawn); // return true; // } // } // } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(caster.DrawPos, caster.Map, "ToHit", -1f); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } DebugMessage(launchTarget.ToString()); projectile.Launch(caster, Ability.Def, drawPos, launchTarget, projectileHitFlags4, null, UseAbilityProps.hediffsToApply, UseAbilityProps.mentalStatesToApply, UseAbilityProps.thingsToSpawn); return(true); }
// Token: 0x06002252 RID: 8786 RVA: 0x000D128C File Offset: 0x000CF48C protected bool base_TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } //修改精度 if (CompShootMode != null) { CompShootMode.PostPreEachShoot(this); } } Thing launcher = this.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } Vector3 drawPos = this.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish); //强制误差半径,无视技能等级(原版迫击炮) if (this.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } LanuchWithDamageMultiplier(projectile2, launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } LanuchWithDamageMultiplier(projectile2, launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } LanuchWithDamageMultiplier(projectile2, launcher, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); if (this.currentTarget.Thing != null) { LanuchWithDamageMultiplier(projectile2, launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { LanuchWithDamageMultiplier(projectile2, launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true); }
protected bool?TryLaunchProjectile(ThingDef projectileDef, LocalTargetInfo launchTarget) { bool flag = base.TryFindShootLineFromTo(this.caster.Position, launchTarget, out ShootLine shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } Vector3 drawPos = this.caster.DrawPos; Projectile_AbilityBase projectile = (Projectile_AbilityBase)GenSpawn.Spawn(projectileDef, shootLine.Source, this.caster.Map); projectile.extraDamages = this.UseAbilityProps.extraDamages; projectile.localSpawnThings = this.UseAbilityProps.thingsToSpawn; projectile.FreeIntercept = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead); ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, launchTarget); if (this.verbProps.soundCast != null) { this.verbProps.soundCast.PlayOneShot(new TargetInfo(this.caster.Position, this.caster.Map, false)); } if (this.verbProps.soundCastTail != null) { this.verbProps.soundCastTail.PlayOneShotOnCamera(); } if (!this.UseAbilityProps.AlwaysHits) { if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f); } shootLine.ChangeDestToMissWild(); if (launchTarget.HasThing) { projectile.ThingToNeverIntercept = launchTarget.Thing; } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } // //Log.Message("LaunchingIntoWild"); projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn); return(true); } if (Rand.Value > shotReport.ChanceToNotHitCover) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f); } if (launchTarget.Thing != null && launchTarget.Thing.def.category == ThingCategory.Pawn) { Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } // //Log.Message("LaunchingINtoCover"); projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn); return(true); } } } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f); } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = (!launchTarget.HasThing || launchTarget.Thing.def.Fillage == FillCategory.Full); } projectile.Launch(this.caster, drawPos, launchTarget, null, this.UseAbilityProps.hediffsToApply, this.UseAbilityProps.mentalStatesToApply, this.UseAbilityProps.thingsToSpawn); return(true); }
protected override bool TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = this.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } /* * if (equipment == null) * { * Log.Message("equipment==null"); * } * else * { * Log.Message(equipment.LabelShortCap); * } */ Vector3 drawPos = this.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, this.caster.Map, WipeMode.Vanish); if (this.verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); Rand.PushState(); int num2 = Rand.Range(0, max); Rand.PopState(); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } Rand.PopState(); if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } // Log.Message("EquipmentAbility projectile2.Launch forcedMissRadius"); projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; Rand.PushState(); bool AimOnTarget = Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture); Rand.PopState(); if (!AimOnTarget) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; Rand.PushState(); if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } Rand.PopState(); projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags2, equipment, targetCoverDef); // Log.Message("EquipmentAbility projectile2.Launch OffTarget"); return(true); } Rand.PushState(); bool PassCover = Rand.Chance(shotReport.PassCoverChance); Rand.PopState(); if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !PassCover) { this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, drawPos, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, equipment, targetCoverDef); // Log.Message("EquipmentAbility projectile2.Launch IntoCover"); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, this.currentTarget, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); // Log.Message("EquipmentAbility projectile2.Launch NoThing"); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, this.currentTarget, projectileHitFlags4, equipment, targetCoverDef); // Log.Message("EquipmentAbility projectile2.Launch AtThing"); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true); // return this.ability.Activate(this.currentTarget, this.currentDestination); }
protected override bool TryCastShot() { // Log.Message("TryCastShot"); this.TargetsAoE.Clear(); UpdateTargets(); int burstshots = this.ShotsPerBurst; if (this.warpverbprops.PsykerPowerCategory != PsykerPowerTargetCategory.TargetAoE && this.TargetsAoE.Count > 1) { this.TargetsAoE.RemoveRange(0, TargetsAoE.Count - 1); } // Log.Message("Targeting: " + TargetsAoE.Count.ToString()); for (int i = 0; i < TargetsAoE.Count; i++) { // Log.Message(TargetsAoE[i].Thing.Label); for (int j = 0; j < burstshots; j++) { ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, TargetsAoE[i], out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } Vector3 drawPos = this.caster.DrawPos; Projectile projectile = (Projectile)GenSpawn.Spawn(this.verbProps.projectileDef, shootLine.Source, this.caster.Map); projectile.FreeIntercept = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead); ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, TargetsAoE[i]); if (!this.warpverbprops.AlwaysHits) { if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f); } shootLine.ChangeDestToMissWild(); if (TargetsAoE[i].HasThing) { projectile.ThingToNeverIntercept = TargetsAoE[i].Thing; } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } // Log.Message("LaunchingIntoWild"); projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment); return(true); } if (Rand.Value > shotReport.ChanceToNotHitCover) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f); } if (TargetsAoE[i].Thing != null && TargetsAoE[i].Thing.def.category == ThingCategory.Pawn) { Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } // Log.Message("LaunchingINtoCover"); projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment); return(true); } } } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f); } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = (!TargetsAoE[i].HasThing || TargetsAoE[i].Thing.def.Fillage == FillCategory.Full); } if (TargetsAoE[i].Thing != null) { // Log.Message("Release Shot at: " + TargetsAoE[i].Thing.Label); if (this.warpverbprops.DrawProjectileOnTarget) { Projectile_WarpPower wprojectile = projectile as Projectile_WarpPower; if (wprojectile != null) { // Log.Message("Launched Warpprojectile"); wprojectile.selectedTarget = TargetsAoE[i].Thing; wprojectile.Caster = this.CasterPawn; wprojectile.Launch(this.caster, drawPos, TargetsAoE[i]); } } else { // Log.Message("Launched Projectile"); projectile.Launch(this.caster, drawPos, TargetsAoE[i]); } } else { if (this.warpverbprops.DrawProjectileOnTarget) { Projectile_WarpPower wprojectile = projectile as Projectile_WarpPower; wprojectile.targetVec = shootLine.Dest.ToVector3(); wprojectile.Launch(this.caster, drawPos, TargetsAoE[i]); } // Log.Message("LaunchingWild"); projectile.Launch(this.caster, drawPos, shootLine.Dest); } } psycomp.TicksToCast = this.warpverbprops.TicksToRecharge; psycomp.TicksToCastMax = this.warpverbprops.TicksToRecharge; } this.burstShotsLeft = 0; if (soul != null) { soul.GainNeed(0.01f * (-warpverbprops.CorruptionFactor)); } // PsykerUtility.PsykerShockEvents(psycomp, psycomp.curPower.PowerLevel); return(true); }
private static float FriendlyFireConeTargetScoreOffset(IAttackTarget target, IAttackTargetSearcher searcher, Verb verb) { Pawn pawn = searcher.Thing as Pawn; if (pawn == null) { return(0f); } if ((int)pawn.RaceProps.intelligence < 1) { return(0f); } if (pawn.RaceProps.IsMechanoid) { return(0f); } Verb_Shoot verb_Shoot = verb as Verb_Shoot; if (verb_Shoot == null) { return(0f); } ThingDef defaultProjectile = verb_Shoot.verbProps.defaultProjectile; if (defaultProjectile == null) { return(0f); } if (defaultProjectile.projectile.flyOverhead) { return(0f); } Map map = pawn.Map; ShotReport report = ShotReport.HitReportFor(pawn, verb, (Thing)target); float radius = Mathf.Max(VerbUtility.CalculateAdjustedForcedMiss(verb.verbProps.forcedMissRadius, report.ShootLine.Dest - report.ShootLine.Source), 1.5f); IEnumerable <IntVec3> enumerable = (from dest in GenRadial.RadialCellsAround(report.ShootLine.Dest, radius, useCenter: true) where dest.InBounds(map) select new ShootLine(report.ShootLine.Source, dest)).SelectMany((ShootLine line) => line.Points().Concat(line.Dest).TakeWhile((IntVec3 pos) => pos.CanBeSeenOverFast(map))).Distinct(); float num = 0f; foreach (IntVec3 item in enumerable) { float num2 = VerbUtility.InterceptChanceFactorFromDistance(report.ShootLine.Source.ToVector3Shifted(), item); if (!(num2 <= 0f)) { List <Thing> thingList = item.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing is IAttackTarget && thing != target) { float num3 = (thing == searcher) ? 40f : ((!(thing is Pawn)) ? 10f : (thing.def.race.Animal ? 7f : 18f)); num3 *= num2; num3 = ((!searcher.Thing.HostileTo(thing)) ? (num3 * -1f) : (num3 * 0.6f)); num += num3; } } } } return(num); }
public bool TryCastShot_A16Vanilla_Modified() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out ShootLine shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } Vector3 drawPos = this.caster.DrawPos; Projectile projectile = (Projectile)GenSpawn.Spawn(this.verbProps.defaultProjectile, shootLine.Source, this.caster.Map); ///MODIFIED SECTION //////////////////////////////////////////// if (this.lastShotReflected) { ////Log.Message("lastShotReflected Called"); projectile.Launch(this.caster, drawPos, this.currentTarget, this.ownerEquipment); return(true); } //////////////////////////////////////////// // projectile.FreeIntercept = (this.canFreeInterceptNow && !projectile.def.projectile.flyOverhead); if (this.verbProps.forcedMissRadius > 0.5f) { float lengthHorizontalSquared = (this.currentTarget.Cell - this.caster.Position).LengthHorizontalSquared; float num; if (lengthHorizontalSquared < 9f) { num = 0f; } else if (lengthHorizontalSquared < 25f) { num = this.verbProps.forcedMissRadius * 0.5f; } else if (lengthHorizontalSquared < 49f) { num = this.verbProps.forcedMissRadius * 0.8f; } else { num = this.verbProps.forcedMissRadius * 1f; } if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(this.verbProps.forcedMissRadius); int num2 = Rand.Range(0, max); if (num2 > 0) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToForRad", -1f); } IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; if (this.currentTarget.HasThing) { projectile.ThingToNeverIntercept = this.currentTarget.Thing; } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } projectile.Launch(this.caster, drawPos, c, this.ownerEquipment); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); if (Rand.Value > shotReport.ChanceToNotGoWild_IgnoringPosture) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToWild", -1f); } shootLine.ChangeDestToMissWild(); if (this.currentTarget.HasThing) { projectile.ThingToNeverIntercept = this.currentTarget.Thing; } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment); return(true); } if (Rand.Value > shotReport.ChanceToNotHitCover) { if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToCover", -1f); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn) { Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = true; } projectile.Launch(this.caster, drawPos, randomCoverToMissInto, this.ownerEquipment); return(true); } } if (DebugViewSettings.drawShooting) { MoteMaker.ThrowText(this.caster.DrawPos, this.caster.Map, "ToHit", -1f); } if (!projectile.def.projectile.flyOverhead) { projectile.InterceptWalls = (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full); } if (this.currentTarget.Thing != null) { projectile.Launch(this.caster, drawPos, this.currentTarget, this.ownerEquipment); } else { projectile.Launch(this.caster, drawPos, shootLine.Dest, this.ownerEquipment); } return(true); }
public bool FireProjectile() { if (base.currentTarget.HasThing && base.currentTarget.Thing.Map != base.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine = default(ShootLine); bool flag = base.TryFindShootLineFromTo(base.caster.Position, base.currentTarget, out shootLine); if (base.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } } Thing launcher = base.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = base.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = base.caster; // Earn skills if (compMannable.ManningPawn.skills != null) { int skillsAffectingAccuracy = 0; if (Settings.intellectualAffectsMortarAccuracy) { skillsAffectingAccuracy++; } if (Settings.shootingAffectsMortarAccuracy) { skillsAffectingAccuracy++; } float skillXP = verbProps.AdjustedFullCycleTime(this, CasterPawn) * 100; skillXP /= skillsAffectingAccuracy; if (Settings.intellectualAffectsMortarAccuracy) { compMannable.ManningPawn.skills.Learn(SkillDefOf.Intellectual, skillXP, false); } if (Settings.shootingAffectsMortarAccuracy) { compMannable.ManningPawn.skills.Learn(SkillDefOf.Shooting, skillXP, false); } } } Vector3 drawPos = base.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, base.caster.Map, WipeMode.Vanish); // If targetting a pawn if (Settings.targetLeading) { if (currentTarget != null && currentTarget.Thing != null && currentTarget.Thing is Pawn targetPawn && targetPawn.pather.curPath != null) { List <IntVec3> nodes = new List <IntVec3>(targetPawn.pather.curPath.NodesReversed); nodes.Reverse(); // Purge outdated nodes from list for (int i = 0; i < nodes.Count; i++) { if (nodes[i] == targetPawn.Position) { // Remove all previous nodes nodes.RemoveRange(0, i); //Log.Message("Removed " + i + " entries. First node is now " + nodes[0].ToString()); break; } } // Path of target pawn from current to destination // Need travel speed of pawn, estimate Vec3 they will be in based on travel speed of our projectile float targetMoveSpeed = targetPawn.GetStatValue(StatDefOf.MoveSpeed); float projectileMoveSpeed = projectile.projectile.speed; // Estimate position target will be in after this amount of time IntVec3 bestTarget = targetPawn.Position; float bestTimeOffset = float.MaxValue; //Log.Message("Default time offset = " + Mathf.Abs(((targetPawn.Position - caster.Position).LengthHorizontal) / projectileMoveSpeed)); float accumulatedTargetTime = 0f; IntVec3 previousPosition = targetPawn.Position; foreach (IntVec3 pathPosition in nodes) { float projectileDistanceFromTarget = (pathPosition - caster.Position).LengthHorizontal; float timeForProjectileToReachPosition = projectileDistanceFromTarget / projectileMoveSpeed; //float pawnDistanceFromTarget = (pathPosition - targetPawn.Position).LengthHorizontal; //float timeForPawnToReachPosition = pawnDistanceFromTarget / targetMoveSpeed; float pawnDistanceFromLastPositionToHere = (pathPosition - previousPosition).LengthHorizontal; float timeForPawnToReachPositionFromLastPosition = pawnDistanceFromLastPositionToHere / targetMoveSpeed; accumulatedTargetTime += timeForPawnToReachPositionFromLastPosition; float timeOffset = Mathf.Abs(timeForProjectileToReachPosition - accumulatedTargetTime); if (timeOffset < bestTimeOffset) { bestTarget = pathPosition; bestTimeOffset = timeOffset; //Log.Message("Position " + pathPosition.ToString() + " is better. Time offset is " + timeOffset); } else { //Log.Message("Position " + pathPosition.ToString() + " is not better. Time offset is " + timeOffset); } previousPosition = pathPosition; } //Log.Message("Initial target cell = " + currentTarget.Cell.ToString() + " and new target is " + bestTarget.ToString()); currentTarget = new LocalTargetInfo(bestTarget); } } if (base.verbProps.forcedMissRadius > 0.5f) { float adjustedForcedMissRadius = GetAdjustedForcedMissRadius(); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.All; IntVec3 c = currentTarget.Cell; if (adjustedForcedMissRadius > 0.5f) { int max = GenRadial.NumCellsInRadius(adjustedForcedMissRadius); int num2 = Rand.Range(0, max); c = base.currentTarget.Cell + GenRadial.RadialPattern[num2]; /*if (num2 > 0) * { * this.ThrowDebugText("ToRadius"); * this.ThrowDebugText("Rad\nDest", c); * ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; * if (Rand.Chance(0.5f)) * { * projectileHitFlags = ProjectileHitFlags.All; * } * if (!base.canHitNonTargetPawnsNow) * { * projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; * } * projectile2.Launch(launcher, drawPos, c, base.currentTarget, projectileHitFlags, equipment, null); * return true; * }*/ } //Log.Message("Final target is " + c.ToString()); projectile2.Launch(launcher, drawPos, c, base.currentTarget, projectileHitFlags, equipment, null); return(true); } ShotReport shotReport = ShotReport.HitReportFor(base.caster, this, base.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto == null) ? null : randomCoverToMissInto.def; /*if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) * { * shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); * this.ThrowDebugText("ToWild" + ((!base.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); * this.ThrowDebugText("Wild\nDest", shootLine.Dest); * ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; * if (Rand.Chance(0.5f) && base.canHitNonTargetPawnsNow) * { * projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; * } * projectile2.Launch(launcher, drawPos, shootLine.Dest, base.currentTarget, projectileHitFlags2, equipment, targetCoverDef); * return true; * }*/ /*if (base.currentTarget.Thing != null && base.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) * { * this.ThrowDebugText("ToCover" + ((!base.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); * this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); * ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; * if (base.canHitNonTargetPawnsNow) * { * projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; * } * projectile2.Launch(launcher, drawPos, randomCoverToMissInto, base.currentTarget, projectileHitFlags3, equipment, targetCoverDef); * return true; * }*/ ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (base.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!base.currentTarget.HasThing || base.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + ((!base.canHitNonTargetPawnsNow) ? string.Empty : "\nchntp")); if (base.currentTarget.Thing != null) { projectile2.Launch(launcher, drawPos, base.currentTarget, base.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", base.currentTarget.Cell); } else { projectile2.Launch(launcher, drawPos, shootLine.Dest, base.currentTarget, projectileHitFlags4, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true); }
public static void Postfix(ShotReport report, ref float __result) { var traverse = Traverse.Create(report); var pawn = traverse.Field(""); }