public static ShotReport HitReportFor(Thing caster, Verb verb, LocalTargetInfo target) { IntVec3 cell = target.Cell; ShotReport result; result.distance = (cell - caster.Position).LengthHorizontal; result.target = target.ToTargetInfo(caster.Map); result.factorFromShooterAndDist = ShotReport.HitFactorFromShooter(caster, result.distance); result.factorFromEquipment = verb.verbProps.GetHitChanceFactor(verb.EquipmentSource, result.distance); result.covers = CoverUtility.CalculateCoverGiverSet(target, caster.Position, caster.Map); result.coversOverallBlockChance = CoverUtility.CalculateOverallBlockChance(target, caster.Position, caster.Map); result.coveringGas = null; if (verb.TryFindShootLineFromTo(verb.caster.Position, target, out result.shootLine)) { foreach (IntVec3 current in result.shootLine.Points()) { Thing gas = current.GetGas(caster.Map); if (gas != null && (result.coveringGas == null || result.coveringGas.gas.accuracyPenalty < gas.def.gas.accuracyPenalty)) { result.coveringGas = gas.def; } } } else { result.shootLine = new ShootLine(IntVec3.Invalid, IntVec3.Invalid); } if (!caster.Position.Roofed(caster.Map) || !target.Cell.Roofed(caster.Map)) { result.factorFromWeather = caster.Map.weatherManager.CurWeatherAccuracyMultiplier; } else { result.factorFromWeather = 1f; } if (target.HasThing) { Pawn pawn = target.Thing as Pawn; if (pawn != null) { result.factorFromTargetSize = pawn.BodySize; } else { result.factorFromTargetSize = target.Thing.def.fillPercent * (float)target.Thing.def.size.x * (float)target.Thing.def.size.z * 2.5f; } result.factorFromTargetSize = Mathf.Clamp(result.factorFromTargetSize, 0.5f, 2f); } else { result.factorFromTargetSize = 1f; } result.forcedMissRadius = verb.verbProps.forcedMissRadius; return(result); }
public static float HitFactorFromShooter(Thing caster, float distance) { float accRating = (!(caster is Pawn)) ? caster.GetStatValue(StatDefOf.ShootingAccuracyTurret, true) : caster.GetStatValue(StatDefOf.ShootingAccuracyPawn, true); return(ShotReport.HitFactorFromShooter(accRating, distance)); }