public static bool Prefix(Building_Shield __instance) { var thingsWithinRadius = new HashSet <Thing>(__instance.ThingsWithinRadius); var thingsWithinScanArea = new HashSet <Thing>(__instance.ThingsWithinScanArea); foreach (var thing in thingsWithinScanArea) { // Try and block projectiles from outside if (thing is ProjectileCE proj && proj.BlockableByShield(__instance)) { var launcher = NonPublicFields.CombatExtended.ProjectileCE_launcher.GetValue(proj) as Thing; if (launcher != null && !thingsWithinRadius.Contains(launcher)) { var explosiveProj = proj as ProjectileCE_Explosive; // Explosives are handled separately if (explosiveProj == null) { __instance.AbsorbDamage(proj.def.projectile.GetDamageAmount(1), proj.def.projectile.damageDef, proj.ExactRotation.eulerAngles.y); } proj.Position += Rot4.FromAngleFlat((__instance.Position - proj.Position).AngleFlat).Opposite.FacingCell; NonPublicMethods.CombatExtended.ProjectileCE_ImpactSomething(proj); if (explosiveProj != null) { NonPublicMethods.CombatExtended.ProjectileCE_Explosive_Explode(explosiveProj); } } } } return(false); }
public static bool BlockableByShield(this ProjectileCE proj, Building_Shield shieldGen) { if (!proj.def.projectile.flyOverhead) { return(true); } return(!shieldGen.coveredCells.Contains(((Vector3)VFESecurity.NonPublicFields.Projectile_origin.GetValue(proj)).ToIntVec3()) && NonPublicProperties.CombatExtended.ProjectileCE_get_IntTicksToImpact(proj) / NonPublicProperties.CombatExtended.ProjectileCE_get_StartingTicksToImpact(proj) <= 0.5f); }